/**
  * Trim away the minimum indentation level for all elements in $elements.
  *
  * @param ezcTemplateBlockTstNode $parentBlock The block which owns elements in $elements.
  * @param array(ezcTemplateTstNode) $elements List of elements to trim.
  */
 public function trimBlockLevelIndentation(ezcTemplateTstNode $parentBlock, array $elements)
 {
     // First figure out the smallest amount of indentation that can be removed
     $indentation = $parentBlock->minimumWhitespaceColumn();
     $nrOfElements = sizeof($elements);
     for ($el = 0; $el < $nrOfElements; $el++) {
         $element = $elements[$el];
         if ($element instanceof ezcTemplateTextBlockTstNode) {
             $lines = $element->lines;
             $count = count($lines);
             for ($i = 0; $i < $count; ++$i) {
                 // Skip the first line if it is placed after another element (column > 0 ).
                 // We can only modify lines with leading point at column 0.
                 if ($i == 0 && $element->firstLineColumn() > 0) {
                     // It prevents some text nodes from removal.
                     continue;
                 }
                 // Trim the line and leave EOL alone
                 $lines[$i][0] = $this->trimIndentationLine($lines[$i][0], $indentation);
                 if ($i == $count - 1) {
                     if ($el < $nrOfElements - 1) {
                         if ($elements[$el + 1] instanceof ezcTemplateBlockTstNode && !$elements[$el + 1] instanceof ezcTemplateOutputBlockTstNode) {
                             $trimmed = trim($lines[$i][0], " \t");
                             if (strlen($trimmed) == 0) {
                                 $lines[$i][0] = "";
                             }
                         }
                     } else {
                         if ($parentBlock instanceof ezcTemplateBlockTstNode && !$parentBlock instanceof ezcTemplateOutputBlockTstNode) {
                             $last = sizeof($lines) - 1;
                             $trimmed = trim($lines[$last][0], " \t");
                             if (strlen(trim($lines[$last][0], " \t")) == 0) {
                                 $lines[$last][0] = "";
                             }
                         }
                     }
                 }
             }
             $element->setTextLines($lines);
         } elseif ($element instanceof ezcTemplateConditionBodyTstNode) {
             $this->trimBlockLevelIndentation($element, $element->children);
         }
     }
 }
 /**
  * Constructs a new ezcTemplateExpressionTstNode
  *
  * @param ezcTemplateSourceCode $source
  * @param ezcTemplateCursor $start
  * @param ezcTemplateCursor $end
  */
 public function __construct(ezcTemplateSourceCode $source, $start, $end)
 {
     parent::__construct($source, $start, $end);
 }
Exemple #3
0
 /**
  * Matches an open with an closing block.
  *
  * @param ezcTemplateTstNode $element
  * @throws ezcTemplateParserException for non matching open and close blocks.
  * @return void
  */
 protected function closeOpenBlock($element)
 {
     // The previous element must be a block element,
     // if not throw an exception
     if (!$this->lastBlock instanceof ezcTemplateBlockTstNode) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, "Found closing block {" . $element->name . "} without a previous block element <" . get_class($this->lastBlock) . ">");
     }
     // Check for closing blocks that do not belong to an opening block.
     if ($this->lastBlock->parentBlock === null && $element->isClosingBlock) {
         if ($element instanceof ezcTemplateCustomBlockTstNode) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->startCursor, "The custom block: {" . $element->name . "} should not have a closing block. Check the custom block definition. ");
         } else {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->startCursor, "Found closing block {/" . $element->name . "} without an opening block.");
         }
     }
     // The name of the previous element must match the closing block,
     // if not throw an exception
     if ($this->lastBlock->name != $element->name) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, "Open and close block do not match: {" . $this->lastBlock->name . "} and {/" . $element->name . "}");
     }
     // Sanity check
     if ($this->lastBlock->parentBlock === null) {
         throw new ezcTemplateInternalException("Parent block of last block <" . get_class($this->lastBlock) . "> is null, should not happen.");
     }
     // Call the closing element with the block element it closes,
     // this allows it to update the open block if required.
     $element->closeOpenBlock($this->lastBlock);
     // Tell the main parser to trim indentation for the block,
     // the whitespace trimming rules are defined within the main parser.
     $this->parser->trimBlockLevelIndentation($this->lastBlock);
     // Get rid of whitespace for the block line
     $this->parser->trimBlockLine($this->lastBlock);
     // Go up (closer to program) one level in the nested tree structure
     $this->lastBlock = $this->lastBlock->parentBlock;
 }
Exemple #4
0
 /**
  * Handles a newly parsed operand, the operand will be appended to the
  * current operator if there is one, if not it becomes the current item.
  * The element which should be the current item is returned by this function.
  *
  * @param ezcTemplateTstNode $currentOperator   The current operator/operand element, can be null.
  * @param ezcTemplateTstNode $operand           The parsed operator/operand which should be added as parameter.
  * @return ezcTemplateTstNode
  */
 public function handleOperand($currentOperator, ezcTemplateTstNode $operand)
 {
     if ($currentOperator !== null) {
         $currentOperator->appendParameter($operand);
         return $currentOperator;
     } else {
         return $operand;
     }
 }
 /**
  * Calls the accept method on the given tst node. The return value
  * replaces the $node.
  *
  * @param ezcTemplateTstNode $node
  * @return void
  */
 protected function acceptAndUpdate(ezcTemplateTstNode &$node)
 {
     $ret = $node->accept($this);
     if ($ret !== null) {
         $node = $ret;
     }
 }
 /**
  * Convenience function for outputting a node.
  * Instantiates the ezcTemplateTstTreeOutput class and calls accept() on
  * $node, the resulting text is returned.
  *
  * @param ezcTemplateAstNode $node
  * @return string
  */
 public static function output(ezcTemplateTstNode $node)
 {
     $treeOutput = new ezcTemplateTstTreeOutput();
     $node->accept($treeOutput);
     return $treeOutput->text . "\n";
 }