Template-LiquidX-Tidy
view release on metacpan or search on metacpan
lib/Template/LiquidX/Tidy/impl.pm view on Meta::CPAN
package Template::LiquidX::Tidy::impl;
use strict;
use warnings;
use experimental 'signatures';
our $VERSION = '0.03';
use Exporter 'import';
our @EXPORT_OK = qw(_tidy_list _tidy_make_string);
use vars '%defaults';
*defaults = \%Template::LiquidX::Tidy::defaults;
# parser regex
our $PI_START = qr/\{%-?/;
our $PI_END = qr/-?%\}/;
our $LV_START = qr/\{\{/;
# pseudo html indenter
# $html - fragment of html to chunk into lines
# $args - indenter configuration
# $level - current level
# $clevel - current level for debugging
# $stack - additional storage for
# open_tags /
# closed_tags /
# level at return time
# returns a list of [ level, fragment ] pairs and modifies $stack
sub _tidy_html ($html, $args, $level, $clevel, $stack) {
#print ((" " x $clevel ). "_tidy_html <<$html>> <<$level>>\n");
my $nl = $html =~ /\n/;
my @return;
my $last_line_start = 0;
my $start_level = $level;
my $level_change = '';
while ($html =~ m{(?: (?<cdata> <!\[CDATA\[(.*?)\]\]> )
| (?<nl> \n )
| (?<close2> />)
| <(?<close> /)? (?<tag> \w+ )
) }gsx) {
#use Data::Dumper; warn Dumper \%+;
if ($+{cdata}) {
# ignore
}
elsif (length $+{nl}) {
1 while $level_change =~ s/\(\)//;
push @return, [ $start_level - ($level_change =~ y/)//), (substr $html, $last_line_start, (pos $html) - $last_line_start),
+{ html => 1,
($stack->{open_tags} ? (open => [$stack->{open_tags}->@*]) : ()),
($stack->{closed_tags} ? (closed => [$stack->{closed_tags}->@*]) : ()), } ];
$last_line_start = pos($html);
$start_level = $level;
$level_change = '';
}
else {
my $tag = $+{tag} ? lc $+{tag} : '';
if ($tag =~ /^(?| area | base | br | col | embed | hr | img | input | link | meta | source | track | wbr )$/ix) {
push $stack->{waiting}->@*, $tag;
}
elsif ($+{close2}) {
if ($stack->{waiting} && $stack->{waiting}->@*) {
pop $stack->{waiting}->@*;
} else {
pop $stack->{open_tags}->@*;
$level_change .= ')';
$level--;
#print ((" " x $clevel ). " close2 <<$level_change>> <<$start_level>>\n");
}
}
elsif ($+{close}) {
if ($stack->{waiting} && $stack->{waiting}->@* && $stack->{waiting}[-1] eq $tag) {
pop $stack->{waiting}->@*;
}
else {
if ($stack->{open_tags} && $stack->{open_tags}[-1] eq $tag) {
pop $stack->{open_tags}->@*;
} else {
push $stack->{closed_tags}->@*, $tag;
}
$level_change .= ')';
$level--;
$stack->{waiting}->@* = ();
#print ((" " x $clevel ). " close<<$tag>> <<$level_change>> <<$start_level>>\n");
}
}
else {
push $stack->{open_tags}->@*, $tag;
$level_change .= '(';
$level++;
$stack->{waiting}->@* = ();
#print ((" " x $clevel ). " open<<$tag>> <<$level_change>> <<$start_level>>\n");
}
}
}
if ($last_line_start < length $html) {
1 while $level_change =~ s/\(\)//;
push @return, [ $start_level - ($level_change =~ y/)//), (substr $html, $last_line_start),
+{ html => 1,
($stack->{open_tags} ? (open => [$stack->{open_tags}->@*]) : ()),
($stack->{closed_tags} ? (closed => [$stack->{closed_tags}->@*]) : ()), } ];
}
$stack->{level} = $level;
( run in 0.550 second using v1.01-cache-2.11-cpan-13bb782fe5a )