Remove whitespace around tag content

daun
Member | 6
+
0
-

I'm trying to remove whitespace inside a tag, i.e. around its contents.

<h1 n:trim>  Hello world  </h1>

should turn into

<h1>Hello world</h1>

spaceless and trim don't seem to work — spaceless keeps the space around the content and trim is a filter, not a macro.

Is there an easy way to achieve this?

The macro below is how I solved it with regex. However, I'm not sure if this is very performant or if there's a much more obvious solution. I'd love to get rid of the regex if possible.

<?php

/**
 * n:trim
 */
public function macroTrimEnd(MacroNode $node, PhpWriter $writer)
{
    $node->validate(false);
    $node->openingCode = "<?php ob_start(); ?>";
    $node->closingCode = '<?php $__output = ob_get_clean(); ?>';
    if ($node->prefix === MacroNode::PREFIX_INNER) {
        // Simple case: n:inner-trim -> just trim content
        $node->closingCode .= '<?php $__output = trim($__output); ?>';
    } else {
        // Trickier case: n:trim
        // remove whitespace *inside* outer tags
        // while preserving whitespace *outside* of outer tags
        // Before: "   <h1>   Title   </h1>   "
        // After:  "   <h1>Title</h1>   "
        $node->closingCode = $node->closingCode .
            // Remove whitespace after opening tag
            '<?php $__output = preg_replace(\'~^(\s*<[^>]+>)\s+~s\', "\$1", $__output); ?>' .
            // Remove whitespace before closing tag
            '<?php $__output = preg_replace(\'~\s+(</[^>]+>\s*)$~s\', "\$1", $__output); ?>';
    }
    $node->closingCode .= '<?php echo $__output; ?>';
}

?>

Thanks for your input.

dakur
Member | 493
+
+2
-

@daun I believe something like this is possible:

<h1>{block |trim}   Hello world   {/block}</h1>

or:

<h1>{='  Hello world  '|trim}<h1>

whatever you like more. You can find it in docs as well – the first way is demonstrated on indent filter, the second on trim filter itself.

And, actually trim is a text processing/filtering function (it filters out characters), so it makes sense it should be filter. 🙂

daun
Member | 6
+
0
-

@dakur You're right, blocks seem like the way to go here. Part of my problem is that the contents could also be HTML from an {include}, so the pure filter wouldn't work. Blocks will, though.

I guess I'm just a bit hung up on the much nicer n:macro notation and prefer it to the verbose {block} syntax.

David Grudl
Nette Core | 8110
+
+1
-

n:spaceless could be modified so that it doesn't leave spaces after the opening and before the closing tag. But it would get pretty complicated.

daun
Member | 6
+
0
-

@DavidGrudl While it'd be cool to have n:spaceless remove space around the content as well, it's not a priority if it's making things complicated. No worries.