Наследование: extends Node
Пример #1
0
 function __construct()
 {
     parent::__construct(null, 'body', array());
 }
Пример #2
0
 /**
  * Parse the input as text until a closing tag has been found for the node.
  *
  * @param TagNode $node
  * @param string  $name
  */
 private function parseAsText($node, $name)
 {
     $closer = '/' . $name;
     if (($first = next($this->tokens)) === false) {
         return;
     }
     if (($second = next($this->tokens)) === false) {
         return;
     }
     if (($third = next($this->tokens)) === false) {
         return;
     }
     // Check that the inputs are [$closer]. If not then keep cycling until closed.
     while ($first !== '[' || $second !== $closer || $third !== ']') {
         $node->curText->text .= $first;
         $first = $second;
         $second = $third;
         if (($third = next($this->tokens)) === false) {
             $node->curText->text .= $first . $second;
             return;
         }
     }
     // Success!
     $node->close();
 }
Пример #3
0
 private function to_struct($message)
 {
     // Initialize a few useful things.
     // Such as the current position within the string.
     $cur_pos = 0;
     // The index within $struct that contains the last text index, this way
     // we can append anything to it if we have to (we don't want one text
     // node after another).
     $last_text_index = -1;
     $length = $this->strlen($message);
     $prev_pos = 0;
     $struct = array();
     // We also don't want to recalculate the size of $struct over and over
     // again.
     $struct_length = 0;
     // The current level.
     $current_level = 0;
     $opened_tags = array();
     $opened_count = 0;
     // Let's look for a possible tag.
     while (($pos = $this->strpos($message, '[', $cur_pos)) !== false && $pos + 1 < $length && $this->substr($message, $pos + 1, 1) != ' ') {
         // Before we handle the possible preceding text, why don't we make sure
         // that this tag will work?
         $last_pos = $pos;
         while ($pos < $length) {
             $amp_pos = $this->strpos($message, '&', $pos);
             $brk_pos = $this->strpos($message, ']', $pos);
             // Does the bracket come before the ampersand?
             // But the ampersand may not even be a quote as well!
             if ($amp_pos === false || $brk_pos === false || $brk_pos < $amp_pos || !in_array($quote_type = $this->substr($message, $amp_pos, 6), array('&quot;', '&#039;'))) {
                 // Sweet!
                 $pos = $brk_pos;
                 break;
             }
             // Now, can we find the next quote?
             while ($amp_pos + 6 < $length && ($amp_pos = $this->strpos($message, $quote_type, $amp_pos + 6)) !== false && $this->substr($message, $amp_pos - 1, 1) == '\\') {
             }
             // Did our search come up with nothing?
             if ($amp_pos + 6 >= $length || $amp_pos === false) {
                 break;
             }
             $pos = $amp_pos + 6;
         }
         // So, did we find a valid tag?
         if ($this->substr($message, $pos, 1) == ']') {
             // Yup, we sure did! So we will want to make a node to contain the
             // text preceding the tag.
             $saved = false;
             if ($prev_pos != $last_pos) {
                 $node = new TextNode($this->substr($message, $prev_pos, $last_pos - $prev_pos), $current_level);
                 $struct[$struct_length++] = $node;
                 $last_text_index = $struct_length - 1;
                 $saved = true;
             }
             // Now for the tag itself.
             $node = new TagNode($this->substr($message, $last_pos, $pos - $last_pos + 1), $this->substr($message, $last_pos + 1, 1) == '/', 0, $this);
             // Woah there, horsey! Do we even have a tag by that name?
             if (isset($this->index['names'][$node->getTag()])) {
                 // Yup, we do.
                 $struct[$struct_length++] = $node;
                 $last_text_index = -1;
                 // Maybe this tag is being opened?
                 if (!$node->is_closing()) {
                     // Set the tag nodes current level, along with adding it to the
                     // list of opened tags.
                     $node->setLevel($current_level);
                     // We need to set the parent node of $node, along with adding
                     // $node to the children of the parent.
                     // This is pretty straightforward, as it is the most recently
                     // opened tag.
                     $node->parentNode($opened_count > 0 ? $opened_tags[$opened_count - 1]['tag'] : null);
                     // If there was no parent node, then it can't really be a child,
                     // can it?
                     if ($node->parentNode() !== null) {
                         // This will add this node along with its other children.
                         $node->parentNode()->childNodes($node);
                     }
                     // Before we add this to the list of opened tags, we will check
                     // whether it is an empty tag, because if it is, it doesn't get
                     // opened, so it won't need to be closed ;-)
                     if (!$this->tag_is_empty($node->getTag())) {
                         $opened_tags[$opened_count++] = array('tag' => $node->getTag(), 'level' => $current_level++, 'pos' => $struct_length - 1);
                     }
                 } else {
                     // First we need to see if this tag was ever opened.
                     $stop = $opened_count;
                     for ($index = $opened_count - 1; $index >= 0; $index--) {
                         if ($opened_tags[$index]['tag'] == $node->getTag()) {
                             // It looks like the tag was opened, at some point.
                             $stop = $index;
                             break;
                         }
                     }
                     // Did we find the opening tag?
                     if ($stop < $opened_count) {
                         // We may need to move the current node back so we can insert
                         // any tags that need closing.
                         $current = $opened_count - 1;
                         // We will want to overwrite the current node (which will be
                         // added back after the loop).
                         $struct_length = $struct_length - 1;
                         while ($current > $stop) {
                             // Take off the last tag...
                             $opened_tag = $opened_tags[$current];
                             unset($opened_tags[$current]);
                             // Also subtract one from the total opened tag count.
                             $opened_count--;
                             // Add the closing tag to the structure.
                             $struct[$struct_length++] = new TagNode('[/' . $opened_tag['tag'] . ']', true, $opened_tag['level']);
                             // !!! Do closing tags need parents?
                             // Let's tell the opening tag where the ending tag is
                             // located, which will make some things quite a bit faster
                             // later.
                             $struct[$opened_tag['pos']]->setClosingAt($struct_length - 1);
                             // Move to the next.
                             $current--;
                         }
                         // Now add the current tag we were supposed to be dealing with
                         // back to $struct.
                         $struct[$struct_length++] = $node;
                         // Set a couple important things.
                         $node->setLevel($opened_tags[$opened_count - 1]['level']);
                         $struct[$opened_tags[$opened_count - 1]['pos']]->setClosingAt($struct_length - 1);
                         // !!! Do closing tags need parents?
                         // Now remove it from the list of opened tags.
                         unset($opened_tags[--$opened_count]);
                         // Now set the proper level.
                         $current_level = $node->level() - 1;
                     } else {
                         // We will just ignore this tag, then.
                         $node->setIgnore(true);
                     }
                 }
                 // Now, everything has been handled up to this point.
                 $prev_pos = $pos + 1;
             } elseif (!empty($saved)) {
                 // We want to save this with the previous text node if we can.
                 if ($last_text_index > -1) {
                     $struct[$last_text_index]->appendText($node->text());
                 } else {
                     $struct[$struct_length++] = new TextNode($node->text(), $current_level);
                     $last_text_index = $struct_length - 1;
                     // Text nodes have parents, but they don't have any children.
                     if ($opened_count > 0) {
                         $struct[$struct_length - 1]->parentNode($opened_tags[$opened_count - 1]['tag']);
                     }
                 }
                 $prev_pos = $pos + 1;
             }
         }
         // Alright, let's move on!
         $cur_pos = $pos + 1;
     }
     // Was there some text left?
     if ($prev_pos < $length) {
         // Yup, and we don't want to leave it out!
         $node = new TextNode($this->substr($message, $prev_pos), $current_level);
         $struct[$struct_length++] = $node;
     }
     // Were there any tags that weren't closed by the end of the message?
     // That's fine, we can fix that.
     if ($opened_count > 0) {
         while (--$opened_count >= 0) {
             $struct[$struct_length++] = new TagNode('[/' . $opened_tags[$opened_count]['tag'] . ']', true, $opened_tags[$opened_count]['level']);
             $struct[$opened_tags[$opened_count]['pos']]->setClosingAt($struct_length - 1);
         }
     }
     $start_time = microtime(true);
     for ($index = 0; $index < $struct_length; $index++) {
         if ($struct[$index]->type() == 'tag') {
             $struct[$index]->checkConstraints();
             if ($struct[$index]->ignore()) {
                 $struct[$struct[$index]->closingAt()]->setIgnore(true);
             }
         }
     }
     // And here you go. I did my job... We will send along the structure
     // length as well. No need to have the other method recalculate it.
     return array($struct, $struct_length);
 }
Пример #4
0
 /**
  * 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 ('newline' === $this->lexer->predictToken()->type) {
         $this->lexer->getAdvancedToken();
     }
     // Tag text on newline
     if ('text' === $this->lexer->predictToken()->type) {
         if ($text = $node->getText()) {
             $text->addLine('');
         } else {
             $node->setText(new TextNode('', $this->lexer->getCurrentLine()));
         }
     }
     // Parse block indentation
     if ('indent' === $this->lexer->predictToken()->type) {
         $node->addChild($this->parseBlock());
     }
     return $node;
 }
Пример #5
0
 private function generateTagContent()
 {
     $content = $this->getSpaces() . "<?php " . $this->_code . " ?>\n";
     $content .= $this->renderChildren();
     $compiler = $this->getCompiler();
     // checking if there is an appended tag
     $currLine = $this->getLineNumber() + $this->getChildrenCount() + 1;
     do {
         $line = $compiler->getLine($currLine);
         $currLine++;
     } while ($line !== null && (trim($line) == '' || $this->getIndentOfLine($line) > $this->getIndentationLevel()));
     $nextLineTag = null;
     if ($line !== null && $this->isTag($line)) {
         $nextLineTag = new TagNode($line);
     }
     if (!($nextLineTag !== null && strtolower($nextLineTag->getTagName()) !== 'if' && strlen($nextLineTag->getSpaces()) == strlen($this->getSpaces()) && !$nextLineTag->isLoud())) {
         $content .= $this->getSpaces() . "<?php " . $this->_tags[$this->_tag] . "; ?>";
     } else {
         $content = rtrim($content);
     }
     return $content;
 }