1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) Fabien Potencier 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Twig\TokenParser; 13 14use Twig\Error\SyntaxError; 15use Twig\Node\BodyNode; 16use Twig\Node\MacroNode; 17use Twig\Node\Node; 18use Twig\Token; 19 20/** 21 * Defines a macro. 22 * 23 * {% macro input(name, value, type, size) %} 24 * <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" /> 25 * {% endmacro %} 26 */ 27final class MacroTokenParser extends AbstractTokenParser 28{ 29 public function parse(Token $token) 30 { 31 $lineno = $token->getLine(); 32 $stream = $this->parser->getStream(); 33 $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue(); 34 35 $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); 36 37 $stream->expect(/* Token::BLOCK_END_TYPE */ 3); 38 $this->parser->pushLocalScope(); 39 $body = $this->parser->subparse([$this, 'decideBlockEnd'], true); 40 if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) { 41 $value = $token->getValue(); 42 43 if ($value != $name) { 44 throw new SyntaxError(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); 45 } 46 } 47 $this->parser->popLocalScope(); 48 $stream->expect(/* Token::BLOCK_END_TYPE */ 3); 49 50 $this->parser->setMacro($name, new MacroNode($name, new BodyNode([$body]), $arguments, $lineno, $this->getTag())); 51 52 return new Node(); 53 } 54 55 public function decideBlockEnd(Token $token) 56 { 57 return $token->test('endmacro'); 58 } 59 60 public function getTag() 61 { 62 return 'macro'; 63 } 64} 65 66class_alias('Twig\TokenParser\MacroTokenParser', 'Twig_TokenParser_Macro'); 67