/** * Parse tag token. * * @return TagNode */ protected function parseTag() { $name = $this->lexer->getAdvancedToken()->value; $node = new TagNode($name, $this->lexer->getCurrentLine()); // Parse id, class, attributes token while (true) { switch ($this->lexer->predictToken()->type) { case 'id': case 'class': $token = $this->lexer->getAdvancedToken(); $node->setAttribute($token->type, $token->value); continue; case 'attributes': foreach ($this->lexer->getAdvancedToken()->attributes as $name => $value) { $node->setAttribute($name, $value); } continue; default: break 2; } } // Parse text/code token switch ($this->lexer->predictToken()->type) { case 'text': $node->setText($this->parseText(true)); break; case 'code': $node->setCode($this->parseCode()); break; } // Skip newlines while ($this->lexer->predictToken()->type === 'newline') { $this->lexer->getAdvancedToken(); } // Tag text on newline if ($this->lexer->predictToken()->type === 'text') { if ($text = $node->getText()) { $text->addLine(''); } else { $node->setText(new TextNode('', $this->lexer->getCurrentLine())); } } // Parse block indentation if ($this->lexer->predictToken()->type === 'indent') { $node->addChild($this->parseBlock()); } return $node; }