Extend the template syntax through normalization

In the following example, we create a custom normalization that replaces pairs of comments in the form <!-- IF FOO -->, <!-- ENDIF --> with a normal <xsl:if test="$FOO"> element. Since template normalization is automatically run on every template, this effectively extends the template syntax to support this new construct.

$configurator = new s9e\TextFormatter\Configurator;

// We prepend our callback so that it's executed before comments are removed
    function (DOMNode $template)
        $dom   = $template->ownerDocument;
        $xpath = new DOMXPath($dom);
        $query = '//comment()[. = " ENDIF "]';

        // Query all ENDIF comments
        foreach ($xpath->query($query) as $comment)
            // Iterate backwards from the ENDIF comment until we find an IF comment
            $node = $comment->previousSibling;

            while ($node)
                if ($node->nodeType === XML_COMMENT_NODE
                 && preg_match('/^ IF (\\w+) $/', $node->textContent, $m))

                $node = $node->previousSibling;

            if (empty($m))

            // Create the xsl:if element that will replace the pair of comments
            $xslIf = $dom->createElementNS('http://www.w3.org/1999/XSL/Transform', 'if');
            $xslIf->setAttribute('test', '$' . $m[1]);

            // Iterate forward from the IF comment to the ENDIF and move nodes to the xsl:if
            while (!$node->nextSibling->isSameNode($comment))

            // All that's left is to remove the ENDIF comment and replace the IF comment with xsl:if
            $node->parentNode->replaceChild($xslIf, $node);

echo $configurator->templateNormalizer->normalizeTemplate('
    <!-- IF S_USER_LOGGED_IN -->
    <!-- ENDIF -->
<xsl:if test="$S_USER_LOGGED_IN"><div>Welcome!</div></xsl:if>