File Coverage

blib/lib/Template/LiquidX/Tidy.pm
Criterion Covered Total %
statement 64 125 51.2
branch 2 38 5.2
condition 0 5 0.0
subroutine 18 22 81.8
pod 1 4 25.0
total 85 194 43.8


line stmt bran cond sub pod time code
1              
2             use strict;
3 3     3   212088 use warnings;
  3         14  
  3         73  
4 3     3   14 use experimental 'signatures';
  3         5  
  3         67  
5 3     3   772  
  3         5712  
  3         16  
6             our $VERSION = '0.03';
7              
8             use Template::LiquidX::Tidy::Liquid::Utility;
9 3     3   1434 use Template::Liquid;
  3         9  
  3         98  
10 3     3   1178 use Template::Liquid::Document;
  3         79055  
  3         107  
11 3     3   44 use Template::Liquid::Tag::If;
  3         6  
  3         56  
12 3     3   13 use Template::Liquid::Tag::Case;
  3         13  
  3         24  
13 3     3   88  
  3         5  
  3         22  
14             use Exporter 'import';
15 3     3   83 our @EXPORT_OK = qw(transform_back);
  3         23  
  3         278  
16              
17             our %defaults = (
18             indent => 4,
19             force_nl => 0,
20             force_nl_tags => 'for endfor '
21             .'comment endcomment '
22             .'if unless elsif else endif endunless '
23             # .'capture '
24             .'case when endcase',
25             short_if => 8,
26             html => 1,
27             );
28              
29             our $_patched;
30             return if $_patched++;
31             no warnings 'redefine';
32 3 50   3   20  
33 3     3   17 my $_if_push_block = \&Template::Liquid::Tag::If::push_block;
  3         5  
  3         565  
34             *Template::Liquid::Tag::If::push_block = sub {
35 3         7 my $self = shift;
36             my ($vars) = @_;
37 6     6   1768 my $block = $_if_push_block->($self, $vars);
38 6         11 $block->{markup} = $vars->{markup};
39 6         17 $block
40 6         324 };
41 6         12  
42 3         31 my $_case_push_block = \&Template::Liquid::Tag::Case::push_block;
43             *Template::Liquid::Tag::Case::push_block = sub {
44 3         8 my $self = shift;
45             my ($vars) = @_;
46 0     0   0 my $block = $_case_push_block->($self, $vars);
47 0         0 $block->{markup} = $vars->{markup};
48 0         0 $block
49 0         0 };
50 0         0  
51 3         10 return;
52             }
53 3         140  
54             BEGIN {
55             _patch_liquid_store_block_markup();
56             }
57 3     3   16  
58             use strict;
59             use warnings;
60             use experimental 'signatures';
61 3     3   14  
  3         13  
  3         67  
62 3     3   12 use Template::LiquidX::Tidy::impl qw(_tidy_list _tidy_make_string);
  3         5  
  3         111  
63 3     3   18  
  3         5  
  3         19  
64             my $return = '';
65 3     3   1883 $return .= $self->{markup} if defined $self->{markup};
  3         20  
  3         2572  
66             for my $node (@{$self->{nodelist}},
67 0     0 0 0 @{$self->{blocks}}) {
  0         0  
  0         0  
68 0         0 my $rendering = ref $node ? $node->dump() : $node;
69 0 0       0 $return .= $rendering if defined $rendering;
70 0         0 }
  0         0  
71 0         0 $return .= $self->{markup_2} if defined $self->{markup_2};
72 0 0       0 $return
73 0 0       0 }
74              
75 0 0       0 my @list = _tidy_list($self, $args, $level, $clevel);
76 0         0 if ($list) {
77             @list
78             } else {
79 3     3 0 102 _tidy_make_string($self, $args, @list)
  3         5  
  3         6  
  3         6  
  3         5  
  3         4  
  3         5  
80 3         10 }
81 3 50       10 }
82              
83 0         0 my $return = '';
84 3         11 $trans_map->{__i} ||= 1;
85             my $i = $trans_map->{__i}++;
86             $trans_map->{ $i } = $self;
87              
88 0     0 0   if (defined $self->{markup}) {
  0            
  0            
  0            
  0            
  0            
89 0           my $ent = '&#' . (1_040_000 + $i) . ';';
90 0   0       if ($self->{markup} =~ /^\s*\{\{/) {
91 0           $return .= $ent;
92 0           }
93             elsif ($self->{blocks}) {
94 0 0         $return .= '<div id="' . $ent . '">';
95 0           }
96 0 0         else {
    0          
97 0           $return .= '<i id="' . $ent . '"></i>';
98             }
99             }
100 0            
101             if ($self->{nodelist}) {
102             for my $node ($self->{nodelist}->@*) {
103 0           my $rendering;
104             if (ref $node) {
105             ($rendering) = $node->transform($args, $trans_map);
106             }
107 0 0         else {
108 0           $rendering = $node;
109 0           }
110 0 0          
111 0           $return .= $rendering if defined $rendering;
112             }
113             }
114 0            
115             if ($self->{blocks}) {
116             for my $block ($self->{blocks}->@*) {
117 0 0         my $rendering;
118             if (ref $block) {
119             ($rendering) = $block->transform($args, $trans_map, 1);
120             }
121 0 0         else {
122 0           $rendering = $block;
123 0           }
124 0 0          
125 0           $return .= $rendering if defined $rendering;
126             }
127             }
128 0            
129             if (defined $self->{markup_2}) {
130             my $ent = '&#' . (1_041_000 + $i) . ';';
131 0 0         if ($self->{markup} =~ /^\s*\{\{/) {
132             $return .= $ent;
133             }
134             elsif (defined $self->{markup} && $self->{blocks}) {
135 0 0         $return .= '</div><!-- id="' . $ent . '" -->';
136 0           }
137 0 0 0       else {
    0          
138 0           $return .= '<i id="' . $ent . '"></i>';
139             }
140             }
141 0            
142             ($return, $trans_map)
143             }
144 0           };
145              
146              
147             $trans =~ s{
148 0           (?: (?<command> <i \s+ id\s*=\s*"&\#104(?<content_part> [01])(?<id> [0-9]{3});"></i> )
149             | (?<opentag> <div \s+ id\s*=\s*"&\#104(?<content_part> 0)(?<id> [0-9]{3});">)
150             | (?<closetag> </div><!-- \s+ id\s*=\s*"&\#104(?<content_part> 1)(?<id> [0-9]{3});" \s+ --> )
151             | (?<content> &\#104(?<content_part> [01])(?<id> [0-9]{3}); )
152             )
153 0     0 1   }{
  0            
  0            
  0            
154 0           $map->{ $+{id} + 0 }{ $+{content_part} ? 'markup_2' : 'markup' }
155             }grex;
156             }
157              
158             1;
159              
160             =head1 NAME
161 0 0          
162             Template::LiquidX::Tidy - Indentation for Liquid template documents
163              
164             =head1 SYNOPSIS
165              
166             use Template::LiquidX::Tidy;
167             use Template::Liquid;
168             use Template::LiquidX::Tag::...; # any additional tag modules you need
169              
170             my $parsed = Template::Liquid->parse($template_string);
171             my $tidy_string = $parsed->{document}->tidy(\%options);
172              
173             =head1 DESCRIPTION
174              
175             The LiquidX::Tidy module enhances a parsed Template::Liquid::Document
176             with a method to indent the document source code according to some
177             options.
178              
179             You can also use the command line client L<liquid_tidy> to indent your
180             template source codes.
181              
182             =head1 METHODS
183              
184             =head2 Template::Liquid::Document::tidy(%options)
185              
186             This method is to be called on a L<Template::Liquid::Document>, i.e. some
187             node in the document created by C<Template::Liquid-E<gt>parse>.
188              
189             It returns a string of the formatted and indented document node.
190              
191             Th following options are possible:
192              
193             =over 4
194              
195             =item B<html> =E<gt> boolean
196              
197             Indent HTML code. Defaults to on.
198              
199             =item B<indent> =E<gt> number
200              
201             The number of spaces for each indentation level. Default 4.
202              
203             =item B<force_nl> =E<gt> boolean
204              
205             Whether to forcibly add line breaks into tags listed as
206             force_nl_tags.
207              
208             Default no for the module, yes for the command line client.
209              
210             =item B<short_if> =E<gt> number
211              
212             The length of a text inbetween C<{% if %}> that should be exempt from force_nl
213              
214             =item B<force_nl_tags> =E<gt> 'for endfor ...'
215              
216             A space separated list of tags where C<force_nl> will add line breaks.
217              
218             Default tags: for endfor comment endcomment if unless elsif else endif
219             endunless case when endcase
220              
221             =back
222              
223             =head2 Template::Liquid::Document::dump()
224              
225             This method is to be called on a L<Template::Liquid::Document>, i.e. some
226             node in the document created by C<Template::Liquid-E<gt>parse>.
227              
228             It returns a copy of the source document.
229              
230             =head2 Template::Liquid::Document::transform()
231              
232             my ($transformed_document, $replacement_map) = $document->transform();
233             my $new_document = Template::LiquidX::Tidy::transform_back(
234             $transformed_document, $replacement_map);
235              
236             This method is to be called on a L<Template::Liquid::Document>, i.e. some
237             node in the document created by C<Template::Liquid-E<gt>parse>.
238              
239             It returns a tuple with the source document where all Liquid tags have
240             been replaced by HTML entities and blank C<E<lt>divE<gt>> and
241             C<E<lt>iE<gt>> tags. This HTML document can the be further processed
242             before using the C<transform_back> method to put back the Liquid tags.
243              
244             =head2 Template::LiquidX::Tidy::transform_back($transformed_document, $replacement_map)
245              
246             This method returns a new template string undoing a transform
247             operation.
248              
249             =cut
250