@@ -, +, @@
---
add_html_filters.pl | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 207 insertions(+)
create mode 100644 add_html_filters.pl
--- a/add_html_filters.pl
+++ a/add_html_filters.pl
@@ -0,0 +1,207 @@
+use Modern::Perl;
+use Text::WordDiff;
+my @tt_directives = (
+ qr{^\s*INCLUDE},
+ qr{^\s*USE},
+ qr{^\s*IF},
+ qr{^\s*UNLESS},
+ qr{^\s*ELSE},
+ qr{^\s*ELSIF},
+ qr{^\s*END},
+ qr{^\s*SET},
+ qr{^\s*FOR},
+ qr{^\s*FOREACH},
+ qr{^\s*MACRO},
+ qr{^\s*SWITCH},
+ qr{^\s*CASE},
+ qr{^\s*PROCESS},
+ qr{^\s*DEFAULT},
+ qr{^\s*TRY},
+ qr{^\s*CATCH},
+ qr{^\s*BLOCK},
+ qr{^\s*FILTER},
+ qr{^\s*STOP},
+);
+use File::Slurp;
+my @files = @ARGV;
+my $test_mode = grep{/--test/} @files;
+
+if ( $test_mode ) {
+ my $input = input_for_test();
+ my $expected = expected_for_test();
+ my @lines = process_tt_content($input);
+ my $output = join "\n", @lines;
+ $output .= "\n"; # Why?
+ if ( $output ne $expected ) {
+ say "KO";
+ say word_diff(\$expected, \$output);
+ } else {
+ say "OK";
+ }
+} else {
+ for my $file ( @ARGV ) {
+ next if $file eq '--test'; # This is really dirty but who cares?
+ say $file;
+ my $content = read_file($file);
+ my @lines = process_tt_content($content);
+ my $output = join "\n", @lines;
+ $output .= "\n";
+ write_file($file, $output);
+ }
+}
+sub process_tt_content {
+ my ( $content ) = @_;
+ my ( @new_lines, $i, $use_raw );
+ for my $line (split "\n", $content ) {
+ my $new_line = $line;
+ if ( $line =~ m{\[%[^%]+%\]} ) {
+ # handle exceptions first
+ if ( $line =~ m{^\s*\[% Asset} ) {
+ $use_raw = 1;
+ $new_line =~ s{\[% Asset\.(.*)\.raw %\]}{[% Asset.$1 | \$raw %]};
+ #$new_line =~ s{\[% Asset\.(.*)\.raw %\]}{[% Asset.$1 %]};
+ push @new_lines, $new_line;
+ next;
+ }
+
+ while ( $line =~ m{
+ \[%
+ (?(\s|\-|~)*)
+ (?[^%\-~]+)
+ (?(\s|\-|~)*)
+ %\]}gmxs ) {
+ my $tt_block = $+{tt_block};
+ my $pre_chomp = $+{pre_chomp};
+ my $post_chomp = $+{post_chomp};
+ if ( $pre_chomp and $pre_chomp =~ m|-| ) {
+ $pre_chomp = '- ';
+ } elsif ( $pre_chomp and $pre_chomp =~ m|~| ) {
+ $pre_chomp = '~ ';
+ } else {
+ $pre_chomp = ' ';
+ }
+ if ( $post_chomp and $post_chomp =~ m|-| ) {
+ $post_chomp = ' -';
+ } elsif ( $post_chomp and $post_chomp =~ m|~| ) {
+ $post_chomp = ' ~';
+ } else {
+ $post_chomp = ' ';
+ }
+
+ if ( $tt_block =~ m{^(?\S+)\s+UNLESS\s+(?\S+)} ) { # Specific for [% foo UNLESS bar %]
+ my $before = $+{before};
+ my $after = $+{after};
+ $new_line =~ s{$before\s+UNLESS\s+$after}{$before | html UNLESS $after};
+ next;
+ }
+ next if grep {$tt_block =~ $_} @tt_directives;
+
+ next if $tt_block =~ m{\s?\|\s?\$KohaDates\s?$}; # We could escape it but should be safe
+ next if $tt_block =~ m{^\#}; # Is a comment, skip it
+
+ if ( $tt_block =~ m{\.raw} ) {
+ $use_raw = 1;
+ $new_line =~ s{\s*\.raw\s*%\]}{ | \$raw$post_chomp%]};
+ #$new_line =~ s{\s*\.raw\s*%\]}{ $post_chomp%]};
+ }
+ elsif ( $tt_block =~ m{\|\s?\$raw} ) { # Already escaped correctly with raw
+ }
+ elsif ( $tt_block =~ m{\|\s?ur(l|i)} ) { # has url or uri filter, do nothing
+ }
+ elsif ( $tt_block !~ m{\|\s?html} ) { # Do not have the html filter
+ $tt_block =~ s/^\s*|\s*$//g; # trim
+ $new_line =~ s{
+ \[%
+ \s*$pre_chomp\s*
+ \Q$tt_block\E
+ \s*$post_chomp\s*
+ %\]
+ }{[%$pre_chomp$tt_block | html$post_chomp%]}xms;
+ }
+ }
+ }
+ push @new_lines, $new_line;
+ #last if $i++ > 10;
+ }
+
+ # Adding [% USE raw %] on top if the filter is used
+ @new_lines = ( '[% USE raw %]', @new_lines )
+ if $use_raw
+ and not $content =~ m{\[% USE raw %\]};
+
+ return @new_lines;
+}
+
+sub input_for_test {
+ return <Koha › Patrons ›
+ [% UNLESS blocking_error %]
+ Patron details for [% INCLUDE 'patron-title.inc' no_html = 1 %]
+ [% just_a_var %] A N D [% another_one_on_same_line %]
+ [% just_a_var_filtered |html %]
+ [% END %]
+ [% IF ( patron.othernames | html ) %]“[% patron.othernames %]”[% END %]
+ [% Asset.css("css/datatables.css").raw %]
+ [% Asset.css("lib/jquery/jquery-ui-1.11.4.min.css").raw %]
+
+[% patron.phone %]
+[% patron.emailpro %]
+[% patron_message.get_column('manager_surname') %]
+[%# do_nothing %]
+[% # do_nothing %]
+[% SWITCH var %]
+[% CASE 'foo' %]foo
+[% CASE %]
+[% END %]
+[%- SWITCH var -%]
+[%- CASE 'foo' -%]foo
+[%- CASE -%]
+[%- END -%]
+[%- var -%]
+[% - var - %]
+[%~ var ~%]
+[% ~ var ~ %]
+[% var | \$raw %]
+[% foo UNLESS bar %]
+[%END%]
+INPUT
+}
+sub expected_for_test {
+ return <Koha › Patrons ›
+ [% UNLESS blocking_error %]
+ Patron details for [% INCLUDE 'patron-title.inc' no_html = 1 %]
+ [% just_a_var | html %] A N D [% another_one_on_same_line | html %]
+ [% just_a_var_filtered |html %]
+ [% END %]
+ [% IF ( patron.othernames | html ) %]“[% patron.othernames | html %]”[% END %]
+ [% Asset.css("css/datatables.css") | \$raw %]
+ [% Asset.css("lib/jquery/jquery-ui-1.11.4.min.css") | \$raw %]
+
+[% patron.phone | html %]
+[% patron.emailpro | html %]
+[% patron_message.get_column('manager_surname') | html %]
+[%# do_nothing %]
+[% # do_nothing %]
+[% SWITCH var %]
+[% CASE 'foo' %]foo
+[% CASE %]
+[% END %]
+[%- SWITCH var -%]
+[%- CASE 'foo' -%]foo
+[%- CASE -%]
+[%- END -%]
+[%- var | html -%]
+[%- var | html -%]
+[%~ var | html ~%]
+[%~ var | html ~%]
+[% var | \$raw %]
+[% foo | html UNLESS bar %]
+[%END%]
+EXPECTED
+}
--