Skip to content

Commit

Permalink
Add support for inline comments
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Sep 27, 2024
1 parent a23cd9f commit cb818ba
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# 3.15.0 (2024-XX-XX)

* Add support for inline comments
* Add support for accessing class constants with the dot operator
* Add `Profile::getStartTime()` and `Profile::getEndTime()`
* Fix "ignore missing" when used on an "embed" tag
Expand Down
40 changes: 37 additions & 3 deletions doc/templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ Go to the :doc:`tags<tags/index>` page to learn more about the built-in tags.
Comments
--------

To comment-out part of a line in a template, use the comment syntax ``{# ...
#}``. This is useful for debugging or to add information for other template
designers or yourself:
To comment-out part of a template, use the comment syntax ``{# ... #}``. This
is useful for debugging or to add information for other template designers or
yourself:

.. code-block:: twig
Expand All @@ -271,6 +271,40 @@ designers or yourself:
{% endfor %}
#}
If you want to add comments inside a block, variable, or comment, use an inline
comment. They start with ``#`` and continue to the end of the line:

.. code-block:: twig
{{
# this is an inline comment
"Hello World"|upper
# this is an inline comment
}}
{{
{
# this is an inline comment
fruit: 'apple', # this is an inline comment
color: 'red', # this is an inline comment
}|join(', ')
}}
Inline comments can also be on the same line as the expression:

.. code-block:: twig
{{
"Hello World"|upper # this is an inline comment
}}
As inline comments continue until the end of the current line, the following
code does not work as ``}}``would be part of the comment:
.. code-block:: twig
{{ "Hello World"|upper # this is an inline comment }}
Including other Templates
-------------------------
Expand Down
5 changes: 5 additions & 0 deletions src/Lexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Lexer
public const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
public const REGEX_DQ_STRING_DELIM = '/"/A';
public const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
public const REGEX_INLINE_COMMENT = '/#[^\n]*/A';
public const PUNCTUATION = '()[]{}?:.,|';

private const SPECIAL_CHARS = [
Expand Down Expand Up @@ -384,6 +385,10 @@ private function lexExpression(): void
$this->pushState(self::STATE_STRING);
$this->moveCursor($match[0]);
}
// inline comment
elseif (preg_match(self::REGEX_INLINE_COMMENT, $this->code, $match, 0, $this->cursor)) {
$this->moveCursor($match[0]);
}
// unlexable
else {
throw new SyntaxError(\sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
Expand Down
98 changes: 98 additions & 0 deletions tests/LexerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -534,4 +534,102 @@ public static function getTemplateForStrings()
yield ['日本では、春になると桜の花が咲きます。多くの人々は、公園や川の近くに集まり、お花見を楽しみます。桜の花びらが風に舞い、まるで雪のように見える瞬間は、とても美しいです。'];
yield ['في العالم العربي، يُعتبر الخط العربي أحد أجمل أشكال الفن. يُستخدم الخط في تزيين المساجد والكتب والمخطوطات القديمة. يتميز الخط العربي بجماله وتناسقه، ويُعتبر رمزًا للثقافة الإسلامية.'];
}

public function testInlineCommentWithHashInString()
{
$lexer = new Lexer(new Environment(new ArrayLoader()));
$stream = $lexer->tokenize(new Source('{{ "me # this is NOT an inline comment" }}', 'index'));
$stream->expect(Token::VAR_START_TYPE);
$stream->expect(Token::STRING_TYPE, 'me # this is NOT an inline comment');
$stream->expect(Token::VAR_END_TYPE);
$this->assertTrue($stream->isEOF());
}

/**
* @dataProvider getTemplateForInlineCommentsForVariable
*/
public function testInlineCommentForVariable(string $template)
{
$lexer = new Lexer(new Environment(new ArrayLoader()));
$stream = $lexer->tokenize(new Source($template, 'index'));
$stream->expect(Token::VAR_START_TYPE);
$stream->expect(Token::STRING_TYPE, 'me');
$stream->expect(Token::VAR_END_TYPE);
$this->assertTrue($stream->isEOF());
}

public static function getTemplateForInlineCommentsForVariable()
{
yield ['{{
"me"
# this is an inline comment
}}'];
yield ['{{
# this is an inline comment
"me"
}}'];
yield ['{{
"me" # this is an inline comment
}}'];
yield ['{{
# this is an inline comment
"me" # this is an inline comment
# this is an inline comment
}}'];
}

/**
* @dataProvider getTemplateForInlineCommentsForBlock
*/
public function testInlineCommentForBlock(string $template)
{
$lexer = new Lexer(new Environment(new ArrayLoader()));
$stream = $lexer->tokenize(new Source($template, 'index'));
$stream->expect(Token::BLOCK_START_TYPE);
$stream->expect(Token::NAME_TYPE, 'if');
$stream->expect(Token::NAME_TYPE, 'true');
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(Token::TEXT_TYPE, 'me');
$stream->expect(Token::BLOCK_START_TYPE);
$stream->expect(Token::NAME_TYPE, 'endif');
$stream->expect(Token::BLOCK_END_TYPE);
$this->assertTrue($stream->isEOF());
}

public static function getTemplateForInlineCommentsForBlock()
{
yield ['{%
if true
# this is an inline comment
%}me{% endif %}'];
yield ['{%
# this is an inline comment
if true
%}me{% endif %}'];
yield ['{%
if true # this is an inline comment
%}me{% endif %}'];
yield ['{%
# this is an inline comment
if true # this is an inline comment
# this is an inline comment
%}me{% endif %}'];
}

/**
* @dataProvider getTemplateForInlineCommentsForComment
*/
public function testInlineCommentForComment(string $template)
{
$lexer = new Lexer(new Environment(new ArrayLoader()));
$stream = $lexer->tokenize(new Source($template, 'index'));
$this->assertTrue($stream->isEOF());
}

public static function getTemplateForInlineCommentsForComment()
{
yield ['{#
Some regular comment # this is an inline comment
#}'];
}
}

0 comments on commit cb818ba

Please sign in to comment.