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