|
Line 0
Link Here
|
| 0 |
- |
1 |
use Modern::Perl; |
|
|
2 |
use Text::WordDiff; |
| 3 |
my @tt_directives = ( |
| 4 |
qr{^\s*INCLUDE}, |
| 5 |
qr{^\s*USE}, |
| 6 |
qr{^\s*IF}, |
| 7 |
qr{^\s*UNLESS}, |
| 8 |
qr{^\s*ELSE}, |
| 9 |
qr{^\s*ELSIF}, |
| 10 |
qr{^\s*END}, |
| 11 |
qr{^\s*SET}, |
| 12 |
qr{^\s*FOR}, |
| 13 |
qr{^\s*FOREACH}, |
| 14 |
qr{^\s*MACRO}, |
| 15 |
qr{^\s*SWITCH}, |
| 16 |
qr{^\s*CASE}, |
| 17 |
qr{^\s*PROCESS}, |
| 18 |
qr{^\s*DEFAULT}, |
| 19 |
qr{^\s*TRY}, |
| 20 |
qr{^\s*CATCH}, |
| 21 |
qr{^\s*BLOCK}, |
| 22 |
qr{^\s*FILTER}, |
| 23 |
qr{^\s*STOP}, |
| 24 |
); |
| 25 |
use File::Slurp; |
| 26 |
my @files = @ARGV; |
| 27 |
my $test_mode = grep{/--test/} @files; |
| 28 |
|
| 29 |
if ( $test_mode ) { |
| 30 |
my $input = input_for_test(); |
| 31 |
my $expected = expected_for_test(); |
| 32 |
my @lines = process_tt_content($input); |
| 33 |
my $output = join "\n", @lines; |
| 34 |
$output .= "\n"; # Why? |
| 35 |
if ( $output ne $expected ) { |
| 36 |
say "KO"; |
| 37 |
say word_diff(\$expected, \$output); |
| 38 |
} else { |
| 39 |
say "OK"; |
| 40 |
} |
| 41 |
} else { |
| 42 |
for my $file ( @ARGV ) { |
| 43 |
next if $file eq '--test'; # This is really dirty but who cares? |
| 44 |
say $file; |
| 45 |
my $content = read_file($file); |
| 46 |
my @lines = process_tt_content($content); |
| 47 |
my $output = join "\n", @lines; |
| 48 |
$output .= "\n"; |
| 49 |
write_file($file, $output); |
| 50 |
} |
| 51 |
} |
| 52 |
sub process_tt_content { |
| 53 |
my ( $content ) = @_; |
| 54 |
my ( @new_lines, $i, $use_raw ); |
| 55 |
for my $line (split "\n", $content ) { |
| 56 |
my $new_line = $line; |
| 57 |
if ( $line =~ m{\[%[^%]+%\]} ) { |
| 58 |
# handle exceptions first |
| 59 |
if ( $line =~ m{^\s*\[% Asset} ) { |
| 60 |
$use_raw = 1; |
| 61 |
$new_line =~ s{\[% Asset\.(.*)\.raw %\]}{[% Asset.$1 | \$raw %]}; |
| 62 |
#$new_line =~ s{\[% Asset\.(.*)\.raw %\]}{[% Asset.$1 %]}; |
| 63 |
push @new_lines, $new_line; |
| 64 |
next; |
| 65 |
} |
| 66 |
|
| 67 |
while ( $line =~ m{ |
| 68 |
\[% |
| 69 |
(?<pre_chomp>(\s|\-|~)*) |
| 70 |
(?<tt_block>[^%\-~]+) |
| 71 |
(?<post_chomp>(\s|\-|~)*) |
| 72 |
%\]}gmxs ) { |
| 73 |
my $tt_block = $+{tt_block}; |
| 74 |
my $pre_chomp = $+{pre_chomp}; |
| 75 |
my $post_chomp = $+{post_chomp}; |
| 76 |
if ( $pre_chomp and $pre_chomp =~ m|-| ) { |
| 77 |
$pre_chomp = '- '; |
| 78 |
} elsif ( $pre_chomp and $pre_chomp =~ m|~| ) { |
| 79 |
$pre_chomp = '~ '; |
| 80 |
} else { |
| 81 |
$pre_chomp = ' '; |
| 82 |
} |
| 83 |
if ( $post_chomp and $post_chomp =~ m|-| ) { |
| 84 |
$post_chomp = ' -'; |
| 85 |
} elsif ( $post_chomp and $post_chomp =~ m|~| ) { |
| 86 |
$post_chomp = ' ~'; |
| 87 |
} else { |
| 88 |
$post_chomp = ' '; |
| 89 |
} |
| 90 |
|
| 91 |
if ( $tt_block =~ m{^(?<before>\S+)\s+UNLESS\s+(?<after>\S+)} ) { # Specific for [% foo UNLESS bar %] |
| 92 |
my $before = $+{before}; |
| 93 |
my $after = $+{after}; |
| 94 |
$new_line =~ s{$before\s+UNLESS\s+$after}{$before | html UNLESS $after}; |
| 95 |
next; |
| 96 |
} |
| 97 |
next if grep {$tt_block =~ $_} @tt_directives; |
| 98 |
|
| 99 |
next if $tt_block =~ m{\s?\|\s?\$KohaDates\s?$}; # We could escape it but should be safe |
| 100 |
next if $tt_block =~ m{^\#}; # Is a comment, skip it |
| 101 |
|
| 102 |
if ( $tt_block =~ m{\.raw} ) { |
| 103 |
$use_raw = 1; |
| 104 |
$new_line =~ s{\s*\.raw\s*%\]}{ | \$raw$post_chomp%]}; |
| 105 |
#$new_line =~ s{\s*\.raw\s*%\]}{ $post_chomp%]}; |
| 106 |
} |
| 107 |
elsif ( $tt_block =~ m{\|\s?\$raw} ) { # Already escaped correctly with raw |
| 108 |
} |
| 109 |
elsif ( $tt_block =~ m{\|\s?ur(l|i)} ) { # has url or uri filter, do nothing |
| 110 |
} |
| 111 |
elsif ( $tt_block !~ m{\|\s?html} ) { # Do not have the html filter |
| 112 |
$tt_block =~ s/^\s*|\s*$//g; # trim |
| 113 |
$new_line =~ s{ |
| 114 |
\[% |
| 115 |
\s*$pre_chomp\s* |
| 116 |
\Q$tt_block\E |
| 117 |
\s*$post_chomp\s* |
| 118 |
%\] |
| 119 |
}{[%$pre_chomp$tt_block | html$post_chomp%]}xms; |
| 120 |
} |
| 121 |
} |
| 122 |
} |
| 123 |
push @new_lines, $new_line; |
| 124 |
#last if $i++ > 10; |
| 125 |
} |
| 126 |
|
| 127 |
# Adding [% USE raw %] on top if the filter is used |
| 128 |
@new_lines = ( '[% USE raw %]', @new_lines ) |
| 129 |
if $use_raw |
| 130 |
and not $content =~ m{\[% USE raw %\]}; |
| 131 |
|
| 132 |
return @new_lines; |
| 133 |
} |
| 134 |
|
| 135 |
sub input_for_test { |
| 136 |
return <<INPUT; |
| 137 |
[% USE Asset %] |
| 138 |
[% INCLUDE 'doc-head-open.inc' %] |
| 139 |
<title>Koha › Patrons › |
| 140 |
[% UNLESS blocking_error %] |
| 141 |
Patron details for [% INCLUDE 'patron-title.inc' no_html = 1 %] |
| 142 |
[% just_a_var %] A N D [% another_one_on_same_line %] |
| 143 |
[% just_a_var_filtered |html %] |
| 144 |
[% END %] |
| 145 |
[% IF ( patron.othernames | html ) %]“[% patron.othernames %]”[% END %] |
| 146 |
[% Asset.css("css/datatables.css").raw %] |
| 147 |
[% Asset.css("lib/jquery/jquery-ui-1.11.4.min.css").raw %] |
| 148 |
</title> |
| 149 |
<a href="tel:[% patron.phone %]">[% patron.phone %]</a> |
| 150 |
<a title="[% patron.emailpro %]" href="mailto:[% patron.emailpro | url %]">[% patron.emailpro %]</a> |
| 151 |
[% patron_message.get_column('manager_surname') %] |
| 152 |
[%# do_nothing %] |
| 153 |
[% # do_nothing %] |
| 154 |
[% SWITCH var %] |
| 155 |
[% CASE 'foo' %]foo |
| 156 |
[% CASE %] |
| 157 |
[% END %] |
| 158 |
[%- SWITCH var -%] |
| 159 |
[%- CASE 'foo' -%]foo |
| 160 |
[%- CASE -%] |
| 161 |
[%- END -%] |
| 162 |
[%- var -%] |
| 163 |
[% - var - %] |
| 164 |
[%~ var ~%] |
| 165 |
[% ~ var ~ %] |
| 166 |
[% var | \$raw %] |
| 167 |
[% foo UNLESS bar %] |
| 168 |
[%END%] |
| 169 |
INPUT |
| 170 |
} |
| 171 |
sub expected_for_test { |
| 172 |
return <<EXPECTED; |
| 173 |
[% USE raw %] |
| 174 |
[% USE Asset %] |
| 175 |
[% INCLUDE 'doc-head-open.inc' %] |
| 176 |
<title>Koha › Patrons › |
| 177 |
[% UNLESS blocking_error %] |
| 178 |
Patron details for [% INCLUDE 'patron-title.inc' no_html = 1 %] |
| 179 |
[% just_a_var | html %] A N D [% another_one_on_same_line | html %] |
| 180 |
[% just_a_var_filtered |html %] |
| 181 |
[% END %] |
| 182 |
[% IF ( patron.othernames | html ) %]“[% patron.othernames | html %]”[% END %] |
| 183 |
[% Asset.css("css/datatables.css") | \$raw %] |
| 184 |
[% Asset.css("lib/jquery/jquery-ui-1.11.4.min.css") | \$raw %] |
| 185 |
</title> |
| 186 |
<a href="tel:[% patron.phone | html %]">[% patron.phone | html %]</a> |
| 187 |
<a title="[% patron.emailpro | html %]" href="mailto:[% patron.emailpro | url %]">[% patron.emailpro | html %]</a> |
| 188 |
[% patron_message.get_column('manager_surname') | html %] |
| 189 |
[%# do_nothing %] |
| 190 |
[% # do_nothing %] |
| 191 |
[% SWITCH var %] |
| 192 |
[% CASE 'foo' %]foo |
| 193 |
[% CASE %] |
| 194 |
[% END %] |
| 195 |
[%- SWITCH var -%] |
| 196 |
[%- CASE 'foo' -%]foo |
| 197 |
[%- CASE -%] |
| 198 |
[%- END -%] |
| 199 |
[%- var | html -%] |
| 200 |
[%- var | html -%] |
| 201 |
[%~ var | html ~%] |
| 202 |
[%~ var | html ~%] |
| 203 |
[% var | \$raw %] |
| 204 |
[% foo | html UNLESS bar %] |
| 205 |
[%END%] |
| 206 |
EXPECTED |
| 207 |
} |