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 );

Reply via email to