Hi everybody and thank you for the Template Toolkit. I want to use Template
Toolkit to generate textual configuration files. One problem i came accross
is that i want my config files to be correctly indented but i also want my
template be correctly indented. These two goals conflict. This template:
| [% IF foo > bar %]
| bla
| [% END %]
should (on a true condition) output this:
| bla
This means that the indentation of two spaces which was made only because of
the IF-Block shall be removed from the output. On the other hand, indentation
added by purpose shall be preserved. This template:
| Hallo
| [% IF foo > bar %]
| bla
| [% END %]
should output
| Hallo
| bla
The identation of the 'bla' line was shortened by two spaces because of the
identation which is due to the IF-Block.
I append to this mail a patch which adds a SMART_INDENT config variable.
This variable indicates the number of spaces for each indent step, e.g.
2 for the examples above. The code does one more thing: If a line only
contains directives and whitespace but no other contents, it is assumed
that this line was only added for more readability of the code (as in
the above examples). The code will then remove all whitespace in this
line an the trailing newline so that this line will cause no output.
The code is a crude hack as it makes it own analysis of the directives
but having it run before split_text made it much more simple to program.
Feel free to suggest better ways to do this. I also ask for general
feedback. Thank you.
Regards
Michael
--
It's an insane world, but i'm proud to be a part of it. -- Bill Hicks
diff -Naur Template-Toolkit-2.19/lib/Template/Parser.pm
Template-Toolkit-2.19-smartindent/lib/Template/Parser.pm
--- Template-Toolkit-2.19/lib/Template/Parser.pm 2007-04-27
19:56:05.000000000 +0200
+++ Template-Toolkit-2.19-smartindent/lib/Template/Parser.pm 2007-12-30
03:32:14.000000000 +0100
@@ -118,6 +118,7 @@
INTERPOLATE => 0,
PRE_CHOMP => 0,
POST_CHOMP => 0,
+ SMART_INDENT => 0,
V1DOLLAR => 0,
EVAL_PERL => 0,
FILE_INFO => 1,
@@ -248,6 +249,9 @@
$self->{ _ERROR } = '';
+ # do indentation if requested
+ $text = $self->smart_indent($text) if ( $self->{'SMART_INDENT'} );
+
# split file into TEXT/DIRECTIVE chunks
$tokens = $self->split_text($text)
|| return undef; ## RETURN ##
@@ -272,6 +276,59 @@
}
+#------------------------------------------------------------------------
+# smart_indent($text)
+#
+# Remove added indentation and newlinews due to template formatting
+#------------------------------------------------------------------------
+sub smart_indent {
+ my ($self, $text) = @_;
+ my ($indentlevel,$textout);
+ my $style = $self->{ STYLE }->[-1];
+ my ($start, $end, $smart_indent ) =
+ @$style{ qw( START_TAG END_TAG) };
+
+ $indentlevel = 0;
+ $textout = '';
+
+ foreach my $line (split(/\n/,$text)) {
+ # Strip identation according to indentlevel
+ # Strip added identation due to identlevel
+ my $ws = ' ' x ($self->{'SMART_INDENT'} * $indentlevel);
+ $line =~ s/^$ws//;
+
+ # Process each directive
+ foreach my $directive ($line =~ m/$start(.*?)$end/g) {
+ # strip optional chomp flags and leading whitespace
+ $directive =~ s/^($CHOMP_FLAGS)?\s*//so;
+
+ # increase indentlevel for each block opening directive
+ $indentlevel++
+ if ( $directive =~
/^(BLOCK|IF|SWITCH|FOREACH|WHILE|FILTER|MACRO|PERL|TRY)\s/ );
+
+ # decrease indentlevel for block closing directive
+ $indentlevel--
+ if ( $directive =~ /^END\s/ );
+
+ }
+
+ # if line contains only whitespace and directives...
+ if ( $line =~ /^\s*($start(.*?)$end\s*)*$/ ) {
+ # ...remove all whitespace and add line without
+ # trailing newline
+ $line =~ s/^\s*//;
+ $line =~ s/($start.*?$end\s*)/$1/g;
+ $textout .= $line;
+ } else {
+ # else add reindented line plus newline to output
+ $textout .= "$line\n";
+ }
+ }
+
+ return $textout;
+}
+
+
#------------------------------------------------------------------------
# split_text($text)
_______________________________________________
templates mailing list
[email protected]
http://mail.template-toolkit.org/mailman/listinfo/templates