File Coverage

blib/lib/Template/AutoFilter/Parser.pm
Criterion Covered Total %
statement 54 54 100.0
branch 19 20 95.0
condition 7 8 87.5
subroutine 10 10 100.0
pod 5 5 100.0
total 95 97 97.9


line stmt bran cond sub pod time code
1 2     2   9 use strict;
  2         3  
  2         57  
2 2     2   7 use warnings;
  2         2  
  2         82  
3              
4             package Template::AutoFilter::Parser;
5              
6             our $VERSION = '0.143050'; # VERSION
7             # ABSTRACT: parses TT templates and automatically adds filters to tokens
8              
9              
10 2     2   6 use base 'Template::Parser';
  2         4  
  2         1170  
11 2     2   45791 use List::MoreUtils qw< part >;
  2         1857  
  2         928  
12              
13             sub new {
14 18     18 1 29 my ( $class, $params ) = @_;
15              
16 18         80 my $self = $class->SUPER::new( $params );
17 18   100     2177 $self->{AUTO_FILTER} = $params->{AUTO_FILTER} || 'html';
18 18   66     63 $self->{SKIP_DIRECTIVES} = $self->make_skip_directives( $params->{SKIP_DIRECTIVES} ) || $self->default_skip_directives;
19              
20 18         92 return $self;
21             }
22              
23             sub split_text {
24 20     20 1 38824 my ( $self, @args ) = @_;
25 20 50       76 my $tokens = $self->SUPER::split_text( @args ) or return;
26              
27 20         3273 for my $token ( @{$tokens} ) {
  20         54  
28 63 100       124 next if !ref $token;
29 23 100       68 next if !ref $token->[2]; # Skip ITEXT ($bar)
30              
31             # Split a compound statement into individual directives
32 22         46 my ($part, $is_directive) = (0, 1);
33             my @directives = part {
34             # Skip over interpolated fields; they are unpaired
35 218 100   218   301 unless (ref) {
36 216 100 100     527 $part++ if $is_directive and $_ eq ';';
37 216         218 $is_directive = !$is_directive;
38             }
39 218         230 $part;
40 22         98 } @{$token->[2]};
  22         98  
41              
42 22         82 for my $directive (@directives) {
43             # Filter out interpolated values in strings; they don't matter for
44             # our decision of whether to autofilter or not (e.g. an existing
45             # filter). Note, this is not the same as ITEXT. Also ignore
46             # semi-colon tokens, as they may make an empty directive look
47             # non-empty. They are also inconsequential to our decision to
48             # autofilter or not.
49 26 100       39 my %fields = grep { !ref and $_ ne ';' } @$directive;
  218         645  
50 26 100       83 next if $self->has_skip_field( \%fields );
51 12 100       51 next if ! %fields;
52              
53 11         48 push @$directive, qw( FILTER | IDENT ), $self->{AUTO_FILTER};
54             }
55              
56 22         37 $token->[2] = [ map { @$_ } @directives ];
  26         184  
57             }
58 20         54 return $tokens;
59             }
60              
61             sub has_skip_field {
62 26     26 1 29 my ( $self, $fields ) = @_;
63              
64 26         37 my $skip_directives = $self->{SKIP_DIRECTIVES};
65              
66 26         21 for my $field ( keys %{$fields} ) {
  26         63  
67 60 100       175 return 1 if $skip_directives->{$field};
68             }
69              
70 12         37 return 0;
71             }
72              
73             sub default_skip_directives {
74 17     17 1 23 my ( $self ) = @_;
75 17         122 my @skip_directives = qw(
76             CALL SET DEFAULT INCLUDE PROCESS WRAPPER BLOCK IF UNLESS ELSIF ELSE
77             END SWITCH CASE FOREACH FOR WHILE FILTER USE MACRO TRY CATCH FINAL
78             THROW NEXT LAST RETURN STOP CLEAR META TAGS DEBUG ASSIGN PERL RAWPERL
79             );
80 17         36 return $self->make_skip_directives( \@skip_directives );
81             }
82              
83             sub make_skip_directives {
84 35     35 1 43 my ( $self, $skip_directives_list ) = @_;
85 35 100       128 return if !$skip_directives_list;
86              
87 18         23 my %skip_directives = map { $_ => 1 } @{$skip_directives_list};
  595         743  
  18         43  
88 18         131 return \%skip_directives;
89             }
90              
91             1;
92              
93             __END__