So - I went ahead and coded up the added chomp capabilities. These diffs are
taken against the 2.14 release that is on CPAN (and may not be compatible
with HEAD).
I have taken care to ensure that the changes don't add overhead to the parsing
process (and in some cases may actually reduce it).
I have included an updated Config.pod and chomp.t that have new documentation
and new tests and I made sure that all other tests continue to work.
The following is an excerpt from the new Template/Manual/Config.pod
> For reference, PRE_CHOMP and POST_CHOMP may be set to any of the following:
> Constant Value Tag Modifier
> ---------------------------------------
> CHOMP_NONE 0 +
> CHOMP_ALL 1 -
> CHOMP_COLLAPSE 2 =
> CHOMP_GREEDY 3 ~
> CHOMP_HTML 4 ^
I think people will really like these features and hopefully they will be
suitable for the 2.15 release. I would hazard a guess that people who read
the config will use the '~' modifier more often than the '-' modifier as it
comes closer to doing what people expect.
There is one change in functionality with these patches. There is a one-off
exception that TT allows for CHOMP_COLLAPSE at the end of a string. If
POST_CHOMP is set to CHOMP_COLLAPSE, TT currently will replace
"[% 1 %]\n" with "1"
This new patch will make this turn into "1 ". The new behavior is arguably
more correct as "all whitespace" on the current line is collapsed to a single
space, and because the designer of the template could put "[% 1 -%]\n" in
this one case to avoid the addition of of the space. I had written code to
allow for this edge case - but have left it out in hopes of having the
behavior be more consistent.
The following is an excerpt from the new Template/Manual/Config.pod
Any comments or feedback are welcome.
Paul Seamons
[EMAIL PROTECTED]
315c315
< s/^([-+\#])?\s*//s;
---
> s/^([-=+~^\#])?\s*//s;
321,329c321,330
< $chomp = ($1 && $1 eq '+') ? 0 : ($1 || $prechomp);
< # my $space = $prechomp == &Template::Constants::CHOMP_COLLAPSE
< my $space = $prechomp == CHOMP_COLLAPSE
< ? ' ' : '';
<
< # chomp off whitespace and newline preceding directive
< $chomp and $pre =~ s/(\n|^)([ \t]*)\Z/($1||$2) ? $space : ''/me
< and $1 eq "\n"
< and $prelines++;
---
> $chomp = $1 ? $1 : $prechomp;
> $chomp =~ tr/-=~^+/12340/;
> if ($chomp && $pre) {
> # chomp off whitespace and newline preceding directive
> if ($chomp == CHOMP_ALL ) { $pre =~ s{ (\n|^) [^\S\n]* \z }{}mx && $1 eq "\n" && $prelines++ }
> elsif ($chomp == CHOMP_COLLAPSE) { $pre =~ s{ (\n|^) [^\S\n]* \z }{ }mx && $1 eq "\n" && $prelines++ }
> # chomp off any whitespace preceding directive
> elsif ($chomp == CHOMP_GREEDY ) { $pre =~ s{ (\s+) \z }{}x && ($prelines += $1=~y/\n//) }
> elsif ($chomp == CHOMP_HTML ) { $pre =~ s{ (\s+) \z }{ }x && ($prelines += $1=~y/\n//) }
> }
333,345c334,344
< s/\s*([-+])?\s*$//s;
< $chomp = ($1 && $1 eq '+') ? 0 : ($1 || $postchomp);
< my $space = $postchomp == &Template::Constants::CHOMP_COLLAPSE
< ? ' ' : '';
<
< $postlines++
< if $chomp and $text =~ s/
< ^
< ([ \t]*)\n # whitespace to newline
< (?:(.|\n)|$) # any char (not EOF)
< /
< (($1||$2) ? $space : '') . (defined $2 ? $2 : '')
< /ex;
---
> s/\s*([-=+~^])?\s*$//s;
> $chomp = $1 ? $1 : $postchomp;
> $chomp =~ tr/-=~^+/12340/;
> if ($chomp) {
> # whitespace to newline
> if ($chomp == CHOMP_ALL ) { $text =~ s{ ^ ([^\S\n]* \n) }{}x && $postlines++ }
> elsif ($chomp == CHOMP_COLLAPSE) { $text =~ s{ ^ ([^\S\n]* \n) }{ }x && $postlines++ }
> # any trailing whitespace
> elsif ($chomp == CHOMP_GREEDY ) { $text =~ s{ ^ (\s+) }{}x && ($postlines += $1=~y/\n//) }
> elsif ($chomp == CHOMP_HTML ) { $text =~ s{ ^ (\s+) }{ }x && ($postlines += $1=~y/\n//) }
> }
31a32,33
> match( CHOMP_GREEDY, 3 );
> match( CHOMP_HTML, 4 );
35a38,40
> my $bing = "[% foo ~%]\n\n!";
> my $bang = "[% foo ^%]\n\n!";
> my $bong = "[% foo =%]\n\n!";
40a46,48
> bing => $bing,
> bang => $bang,
> bong => $bong,
56a65,73
> $out = '';
> ok( $tt2->process('bing', $vars, \$out), $tt2->error() );
> match( $out, "3.14!" );
> $out = '';
> ok( $tt2->process('bang', $vars, \$out), $tt2->error() );
> match( $out, "3.14 !" );
> $out = '';
> ok( $tt2->process('bong', $vars, \$out), $tt2->error() );
> match( $out, "3.14 \n!" );
76a94,104
> $tt2 = Template->new({
> POST_CHOMP => '~',
> BLOCKS => {
> foo => "[% foo %]\n\n\n",
> },
> });
>
> $out = '';
> ok( $tt2->process('foo', $vars, \$out), $tt2->error() );
> match( $out, "3.14" );
>
170,172c170,171
< You may use the CHOMP_NONE, CHOMP_ALL, and CHOMP_COLLAPSE constants
< from the Template::Constants module to deactivate chomping, remove
< all whitespace, or collapse whitespace to a single space.
---
> With POST_CHOMP is set to 3, all adjacent whitespace (including newlines)
> will be removed (as opposed to removing just the whitespace on the same line).
174c173,193
< PRE_CHOMP and POST_CHOMP can be activated for individual directives by
---
> With PRE_CHOMP or POST_CHOMP set to 4, all adjacent whitespace will
> be collapsed to a single space (as opposed to just collapsing the whitespace
> on the same line).
>
> You may use the CHOMP_NONE, CHOMP_ALL, and CHOMP_COLLAPSE,
> CHOMP_GREEDY, and CHOMP_HTML constants from the Template::Constants
> module to deactivate chomping, remove all whitespace, or collapse
> whitespace to a single space, remove all whitespace including
> newlines, or collapse all whitespace including newlines to a single
> space.
>
> Additionally the chomp tag modifiers listed below may also be used for
> the PRE_CHOMP and POST_CHOMP configuration.
>
> my $template = Template->new({
> PRE_CHOMP => '~',
> POST_CHOMP => '-',
> });
>
>
> Pre CHOMP_ALL and post CHOMP_ALL can be activated for individual directives by
177a197
>
181c201
< The '-' characters activate both PRE_CHOMP and POST_CHOMP for the one
---
> The '-' characters activate both pre CHOMP_ALL and post CHOMP_ALL for the one
184a205,234
> [% FOREACH user = userlist %]
> [% user %][% END %]
>
> Pre CHOMP_COLLAPSE and post CHOMP_COLLAPSE can be activated for individual directives by
> placing an '=' immediately at the start and/or end of the directive.
>
> [% FOREACH user = userlist %]
>
> [%= user =%]
> [% END %]
>
> The '=' characters activate both pre CHOMP_COLLAPSE and post CHOMP_COLLAPSE for the one
> directive '[%= name =%]'. Thus, the template will be processed as if
> written:
>
> [% FOREACH user = userlist %]
> [% user %] [% END %]
>
> Pre CHOMP_GREEDY and post CHOMP_GREEDY can be activated for individual directives by
> placing a '~' immediately at the start and/or end of the directive.
>
> [% FOREACH user = userlist %]
>
> [%~ user ~%]
> [% END %]
>
> The '~' characters activate both pre CHOMP_GREEDY and post CHOMP_GREEDY for the one
> directive '[%~ name ~%]'. Thus, the template will be processed as if
> written:
>
187,191c237,238
< Note that this is the same as if PRE_CHOMP and POST_CHOMP were set
< to CHOMP_ALL; the only way to get the CHOMP_COLLAPSE behavior is
< to set PRE_CHOMP or POST_CHOMP accordingly. If PRE_CHOMP or POST_CHOMP
< is already set to CHOMP_COLLAPSE, using '-' will give you CHOMP_COLLAPSE
< behavior, not CHOMP_ALL behavior.
---
> Pre CHOMP_HTML and post CHOMP_HTML can be activated for individual directives by
> placing a '^' immediately at the start and/or end of the directive.
193,194c240,253
< Similarly, '+' characters can be used to disable PRE_CHOMP or
< POST_CHOMP (i.e. leave the whitespace/newline intact) options on a
---
> [% FOREACH user = userlist %]
>
> [%^ user ^%]
> [% END %]
>
> The '^' characters activate both pre CHOMP_GREEDY and post CHOMP_GREEDY for the one
> directive '[%^ name ^%]'. Thus, the template will be processed as if
> written:
>
> [% FOREACH user = userlist %] [% user %] [% END %]
>
>
> Similarly, '+' characters can be used to force no chomping to occur
> (i.e. leave the whitespace/newlines intact) on a
201c260
< With POST_CHOMP enabled, the above example would be parsed as if written:
---
> With POST_CHOMP set to CHOMP_ALL, the above example would be parsed as if written:
205a265
> For reference, PRE_CHOMP and POST_CHOMP may be set to any of the following:
207c267,273
<
---
> Constant Value Tag Modifier
> ---------------------------------------
> CHOMP_NONE 0 +
> CHOMP_ALL 1 -
> CHOMP_COLLAPSE 2 =
> CHOMP_GREEDY 3 ~
> CHOMP_HTML 4 ^
60c60
< use constant CHOMP_ALL => 1; # remove whitespace
---
> use constant CHOMP_ALL => 1; # remove whitespace on current line
61a62,63
> use constant CHOMP_GREEDY => 3; # remove all whitespace including on adjacent lines
> use constant CHOMP_HTML => 4; # collapse all whitespace including on adjacent lines to a single space
103c105
< @CHOMP = qw( CHOMP_NONE CHOMP_ALL CHOMP_COLLAPSE );
---
> @CHOMP = qw( CHOMP_NONE CHOMP_ALL CHOMP_COLLAPSE CHOMP_GREEDY CHOMP_HTML );