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\Token; 18 19/** 20 * Defines a macro. 21 * 22 * {% macro input(name, value, type, size) %} 23 * <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" /> 24 * {% endmacro %} 25 * 26 * @final 27 */ 28class MacroTokenParser extends AbstractTokenParser 29{ 30 public function parse(Token $token) 31 { 32 $lineno = $token->getLine(); 33 $stream = $this->parser->getStream(); 34 $name = $stream->expect(Token::NAME_TYPE)->getValue(); 35 36 $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); 37 38 $stream->expect(Token::BLOCK_END_TYPE); 39 $this->parser->pushLocalScope(); 40 $body = $this->parser->subparse([$this, 'decideBlockEnd'], true); 41 if ($token = $stream->nextIf(Token::NAME_TYPE)) { 42 $value = $token->getValue(); 43 44 if ($value != $name) { 45 throw new SyntaxError(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); 46 } 47 } 48 $this->parser->popLocalScope(); 49 $stream->expect(Token::BLOCK_END_TYPE); 50 51 $this->parser->setMacro($name, new MacroNode($name, new BodyNode([$body]), $arguments, $lineno, $this->getTag())); 52 } 53 54 public function decideBlockEnd(Token $token) 55 { 56 return $token->test('endmacro'); 57 } 58 59 public function getTag() 60 { 61 return 'macro'; 62 } 63} 64 65class_alias('Twig\TokenParser\MacroTokenParser', 'Twig_TokenParser_Macro'); 66