| 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 | 184532 | use strict; | |||
| 3 | 16 | ||||||
| 3 | 86 | ||||||
| 4 | 3 | 3 | 17 | use warnings; | |||
| 3 | 6 | ||||||
| 3 | 83 | ||||||
| 5 | 3 | 3 | 1005 | use experimental 'signatures'; | |||
| 3 | 6662 | ||||||
| 3 | 15 | ||||||
| 6 | |||||||
| 7 | our $VERSION = '0.01'; | ||||||
| 8 | |||||||
| 9 | 3 | 3 | 1826 | use Template::LiquidX::Tidy::Liquid::Utility; | |||
| 3 | 8 | ||||||
| 3 | 120 | ||||||
| 10 | 3 | 3 | 1385 | use Template::Liquid; | |||
| 3 | 72799 | ||||||
| 3 | 109 | ||||||
| 11 | 3 | 3 | 41 | use Template::Liquid::Document; | |||
| 3 | 8 | ||||||
| 3 | 62 | ||||||
| 12 | 3 | 3 | 15 | use Template::Liquid::Tag::If; | |||
| 3 | 7 | ||||||
| 3 | 18 | ||||||
| 13 | 3 | 3 | 93 | use Template::Liquid::Tag::Case; | |||
| 3 | 8 | ||||||
| 3 | 19 | ||||||
| 14 | |||||||
| 15 | 3 | 3 | 94 | use Exporter 'import'; | |||
| 3 | 23 | ||||||
| 3 | 326 | ||||||
| 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 | 17 | return if $_patched++; | ||
| 33 | 3 | 3 | 20 | no warnings 'redefine'; | |||
| 3 | 7 | ||||||
| 3 | 546 | ||||||
| 34 | |||||||
| 35 | 3 | 7 | my $_if_push_block = \&Template::Liquid::Tag::If::push_block; | ||||
| 36 | *Template::Liquid::Tag::If::push_block = sub { | ||||||
| 37 | 6 | 6 | 1964 | my $self = shift; | |||
| 38 | 6 | 14 | my ($vars) = @_; | ||||
| 39 | 6 | 19 | my $block = $_if_push_block->($self, $vars); | ||||
| 40 | 6 | 360 | $block->{markup} = $vars->{markup}; | ||||
| 41 | 6 | 22 | $block | ||||
| 42 | 3 | 29 | }; | ||||
| 43 | |||||||
| 44 | 3 | 10 | 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 | 10 | }; | ||||
| 52 | |||||||
| 53 | 3 | 121 | return; | ||||
| 54 | } | ||||||
| 55 | |||||||
| 56 | BEGIN { | ||||||
| 57 | 3 | 3 | 15 | _patch_liquid_store_block_markup(); | |||
| 58 | } | ||||||
| 59 | |||||||
| 60 | package Template::Liquid::Document { | ||||||
| 61 | 3 | 3 | 19 | use strict; | |||
| 3 | 6 | ||||||
| 3 | 76 | ||||||
| 62 | 3 | 3 | 15 | use warnings; | |||
| 3 | 6 | ||||||
| 3 | 79 | ||||||
| 63 | 3 | 3 | 16 | use experimental 'signatures'; | |||
| 3 | 6 | ||||||
| 3 | 21 | ||||||
| 64 | |||||||
| 65 | 3 | 3 | 1714 | use Template::LiquidX::Tidy::impl qw(_tidy_list _tidy_make_string); | |||
| 3 | 6 | ||||||
| 3 | 2725 | ||||||
| 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 | 96 | sub tidy ($self, $args = {}, $level = 0, $clevel = 0, $list = undef) { | ||
| 3 | 5 | ||||||
| 3 | 6 | ||||||
| 3 | 6 | ||||||
| 3 | 6 | ||||||
| 3 | 14 | ||||||
| 3 | 5 | ||||||
| 80 | 3 | 17 | my @list = _tidy_list($self, $args, $level, $clevel); | ||||
| 81 | 3 | 50 | 10 | if ($list) { | |||
| 82 | @list | ||||||
| 83 | 0 | 0 | } else { | ||||
| 84 | 3 | 21 | _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 | (?: (? |
||||||
| 156 | | (? 0)(? |
||||||
| 157 | | (? |
||||||
| 158 | | (? |
||||||
| 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 |
||||||
| 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 |
||||||
| 194 | node in the document created by C |
||||||
| 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 |
||||||
| 203 | |||||||
| 204 | Indent HTML code. Defaults to on. | ||||||
| 205 | |||||||
| 206 | =item B |
||||||
| 207 | |||||||
| 208 | The number of spaces for each indentation level. Default 4. | ||||||
| 209 | |||||||
| 210 | =item B |
||||||
| 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 |
||||||
| 218 | |||||||
| 219 | The length of a text inbetween C<{% if %}> that should be exempt from force_nl | ||||||
| 220 | |||||||
| 221 | =item B |
||||||
| 222 | |||||||
| 223 | A space separated list of tags where C |
||||||
| 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 |
||||||
| 233 | node in the document created by C |
||||||
| 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 |
||||||
| 244 | node in the document created by C |
||||||
| 245 | |||||||
| 246 | It returns a tuple with the source document where all Liquid tags have | ||||||
| 247 | been replaced by HTML entities and blank C |
||||||
| 248 | C |
||||||
| 249 | before using the C |
||||||
| 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 |