Nathaniel Nuss wrote:
I'd like to avoid that leading whitespace on subsequent lines and I'd like to
keep the indent filters and WRAPPER chain.
Any suggestions on how I could have my cake and ... ?
Been there, done it, had the cake, and ate it :-)
It's a far-from-elegant solution, but I use an undent filter on the
final page (applied in my site/wrapper) to remove all the leading whitespace
from <pre> tags that the indent filter added.
The slightly tricky part is preserving any leading whitespace that wasn't
added by the indent filter. I measure the length of the shortest leading
whitespace sequence on any line and then remove that from each line. I
also remove the newlines immediately after the opening tag and before the
closing tag.
e.g.
<pre> ===> <pre>FOO
FOO BAR
BAR BAZ</pre>
BAZ
</pre>
The filter code is attached below. It defaults to undenting 'pre'
tags only (that was the particular itch I was scratching at the time),
although it does accepts a 'tag' parameter:
FILTER undent(tag='textarea');
...
END
It could do with being tweaked to handle multiple tags in the same
pass. I'll probably do that at some point in the future and then
stick it in the core. But right now it's wide open, so suggestions,
updates, etc., are welcome.
You need to register it like this:
$context->define_filter( undent => \&undent_filter_factory, 1 );
And here are the factory and filter subs:
sub undent_filter_factory {
my ($context, @args) = @_;
my $params = pop(@args) || { };
my $tag = $params->{ tag } || 'pre';
my $depth = shift(@args) || 0;
return sub {
my $text = shift;
$text =~ s{ (<$tag.*?>)(.*?)(<\/$tag>) }
{ $1 . undent($2, $depth) . $3 }sexg;
return $text;
}
}
sub undent {
my $text = shift;
my (@lines, $line, $length, $min);
# expand tabs to spaces, trim leading and trailing
# whitespace, then split into lines
for ($text) {
s/\t/ /g;
s/^ *\n//;
s/(\n *)*$//;
@lines = split(/\n/);
}
# some arbitrarily large number
$min = 100;
# measure the length of the shortest leading whitespace
foreach (@lines) {
chomp;
next if s/^\s+$//;
/^(\s*)/;
$length = length $1;
$min = $length if $length < $min;
}
# remove that much whitespace from each line
if ($min) {
foreach (@lines) {
s/^ {$min}//mg;
}
}
$text = join("\n", @lines);
return $text;
}
HTH
Cheers
A
_______________________________________________
templates mailing list
templates@template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/templates