/** * 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; }
/** * Dump tag node. * * @param TagNode $node tag node * @param integer $level indentation level * * @return string */ protected function dumpTag(TagNode $node, $level = 0) { $html = str_repeat(' ', $level); if (in_array($node->getName(), $this->selfClosing)) { $html .= '<' . $node->getName(); $html .= $this->dumpAttributes($node->getAttributes()); $html .= ' />'; return $html; } else { if (count($node->getAttributes())) { $html .= '<' . $node->getName(); $html .= $this->dumpAttributes($node->getAttributes()); $html .= '>'; } else { $html .= '<' . $node->getName() . '>'; } if ($node->getCode()) { if (count($node->getChildren())) { $html .= "\n" . str_repeat(' ', $level + 1) . $this->dumpCode($node->getCode()); } else { $html .= $this->dumpCode($node->getCode()); } } if ($node->getText() && count($node->getText()->getLines())) { if (count($node->getChildren())) { $html .= "\n" . str_repeat(' ', $level + 1) . $this->dumpText($node->getText()); } else { $html .= $this->dumpText($node->getText()); } } if (count($node->getChildren())) { $html .= "\n"; $children = $node->getChildren(); foreach ($children as $i => $child) { $this->nextIsIf[$level + 1] = isset($children[$i + 1]) && $children[$i + 1] instanceof CodeNode; $html .= $this->dumpNode($child, $level + 1); } $html .= "\n" . str_repeat(' ', $level); } return $html . '</' . $node->getName() . '>'; } }