diff --git a/CHANGELOG b/CHANGELOG index 496115fda..f80bf7355 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -212,7 +212,7 @@ * 1.39.2 (2019-XX-XX) - * n/a + * fixed Lexer when using custom options containing the # char * 1.39.1 (2019-04-16) diff --git a/src/Lexer.php b/src/Lexer.php index 51b6b9050..649780606 100644 --- a/src/Lexer.php +++ b/src/Lexer.php @@ -64,16 +64,17 @@ class Lexer 'interpolation' => ['#{', '}'], ], $options); + // when PHP 7.3 is the min version, we will be able to remove the '#' part in preg_quote as it's part of the default $this->regexes = [ // }} 'lex_var' => '{ \s* (?:'. - preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1]).'\s*'. // -}}\s* + preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '#').'\s*'. // -}}\s* '|'. - preg_quote($this->options['whitespace_line_trim'].$this->options['tag_variable'][1]).'['.$this->options['whitespace_line_chars'].']*'. // ~}}[ \t\0\x0B]* + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_variable'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~}}[ \t\0\x0B]* '|'. - preg_quote($this->options['tag_variable'][1]). // }} + preg_quote($this->options['tag_variable'][1], '#'). // }} ') }Ax', @@ -81,28 +82,28 @@ class Lexer 'lex_block' => '{ \s* (?:'. - preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1]).'\s*\n?'. // -%}\s*\n? + preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*\n?'. // -%}\s*\n? '|'. - preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1]).'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* '|'. - preg_quote($this->options['tag_block'][1]).'\n?'. // %}\n? + preg_quote($this->options['tag_block'][1], '#').'\n?'. // %}\n? ') }Ax', // {% endverbatim %} 'lex_raw_data' => '{'. - preg_quote($this->options['tag_block'][0]). // {% + preg_quote($this->options['tag_block'][0], '#'). // {% '('. $this->options['whitespace_trim']. // - '|'. $this->options['whitespace_line_trim']. // ~ ')?\s*endverbatim\s*'. '(?:'. - preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1]).'\s*'. // -%} + preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*'. // -%} '|'. - preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1]).'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* '|'. - preg_quote($this->options['tag_block'][1]). // %} + preg_quote($this->options['tag_block'][1], '#'). // %} ') }sx', @@ -123,32 +124,32 @@ class Lexer 'lex_block_raw' => '{ \s*verbatim\s* (?:'. - preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1]).'\s*'. // -%}\s* + preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*'. // -%}\s* '|'. - preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1]).'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* '|'. - preg_quote($this->options['tag_block'][1]). // %} + preg_quote($this->options['tag_block'][1], '#'). // %} ') }Asx', - 'lex_block_line' => '{\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1]).'}As', + 'lex_block_line' => '{\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '#').'}As', // {{ or {% or {# 'lex_tokens_start' => '{ ('. - preg_quote($this->options['tag_variable'][0]). // {{ + preg_quote($this->options['tag_variable'][0], '#'). // {{ '|'. - preg_quote($this->options['tag_block'][0]). // {% + preg_quote($this->options['tag_block'][0], '#'). // {% '|'. preg_quote($this->options['tag_comment'][0], '#'). // {# ')('. - preg_quote($this->options['whitespace_trim']). // - + preg_quote($this->options['whitespace_trim'], '#'). // - '|'. - preg_quote($this->options['whitespace_line_trim']). // ~ + preg_quote($this->options['whitespace_line_trim'], '#'). // ~ ')? }sx', - 'interpolation_start' => '{'.preg_quote($this->options['interpolation'][0]).'\s*}A', - 'interpolation_end' => '{\s*'.preg_quote($this->options['interpolation'][1]).'}A', + 'interpolation_start' => '{'.preg_quote($this->options['interpolation'][0], '#').'\s*}A', + 'interpolation_end' => '{\s*'.preg_quote($this->options['interpolation'][1], '#').'}A', ]; } diff --git a/test/Twig/Tests/LexerTest.php b/test/Twig/Tests/LexerTest.php index f483db116..9aff56580 100644 --- a/test/Twig/Tests/LexerTest.php +++ b/test/Twig/Tests/LexerTest.php @@ -341,4 +341,30 @@ bar $lexer = new Lexer(new Environment($this->getMockBuilder(LoaderInterface::class)->getMock())); $lexer->tokenize(new Source($template, 'index')); } + + public function testOverridingSyntax() + { + $template = '[# comment #]{# variable #}/# if true #/true/# endif #/'; + $lexer = new Lexer(new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock()), [ + 'tag_comment' => ['[#', '#]'], + 'tag_block' => ['/#', '#/'], + 'tag_variable' => ['{#', '#}'], + ]); + $stream = $lexer->tokenize(new Source($template, 'index')); + $stream->expect(Token::VAR_START_TYPE); + $stream->expect(Token::NAME_TYPE, 'variable'); + $stream->expect(Token::VAR_END_TYPE); + $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, 'true'); + $stream->expect(Token::BLOCK_START_TYPE); + $stream->expect(Token::NAME_TYPE, 'endif'); + $stream->expect(Token::BLOCK_END_TYPE); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } }