HTML-Untidy
view release on metacpan or search on metacpan
lib/HTML/Untidy.pm view on Meta::CPAN
my @BASE = qw(element class attr prop text raw note);
# source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element
my @TAGS = qw(
a abbr address area article aside audio
b base bdi bdo blockquote body br button
canvas caption cite code col colgroup
data datalist dd del details dfn dialog div dl dt
em embed
fieldset figcaption figure footer form
h1 h2 h3 h4 h5 h6 head header hgroup hr html
i iframe img input ins
kbd
label legend li link
main map mark menu menuitem meta meter
nav noframes noscript
object ol optgroup option output
p param picture pre progress
q
rp rt rtc ruby
s samp script section select slot small source span strong style sub summary sup
table tbody td template textarea tfoot th thead time title tr track
u ul
var video
wbr
);
my @COMMON = qw(
html head body title meta link script style
h1 h2 h3 h4 h5 h6
div p hr pre nav code img a b i u em strong sup sub small
table tbody thead tr th td
ul dl ol li dd dt
form input textarea select option button label
canvas
);
our @EXPORT_OK = (@BASE, @TAGS);
our %EXPORT_TAGS = (
base => [@BASE],
common => [@BASE, @COMMON],
all => [@BASE, @TAGS],
);
our @CLASS;
our @ATTR;
our @PROP;
our @BODY;
our $INDENT = 0;
my $DEPTH = 0;
sub install_sub{
no strict 'refs';
my ($name, $code) = @_;
*{"${name}"} = $code;
}
sub e ($){
goto \&escape_html;
}
sub indent {
return ' ' x ($DEPTH * $INDENT);
}
sub element ($&){
my ($tag, $code) = @_;
my $html = do {
local @CLASS;
local @ATTR;
local @PROP;
local @BODY;
++$DEPTH;
my $inner_html = $code->();
--$DEPTH;
if ($inner_html) {
push @BODY, $inner_html;
}
my @attrs;
for (my $i = 0; $i < @ATTR; $i += 2) {
push @attrs, qq{$ATTR[$i]="$ATTR[$i + 1]"};
}
my $attr = ''; $attr = ' ' . join ' ', @attrs if @attrs;
my $prop = ''; $prop = ' ' . join ' ', @PROP if @PROP;
my $class = ''; $class = sprintf ' class="%s"', join ' ', @CLASS if @CLASS;
if (@BODY) {
my $open = sprintf '%s<%s%s%s%s>', indent, $tag, $class, $attr, $prop;
my $close = sprintf '%s</%s>', indent, $tag;
join("\n", $open, join("\n", @BODY), $close);
}
else {
sprintf q{%s<%s%s%s%s></%s>}, indent, $tag, $class, $attr, $prop, $tag;
}
};
my $void = !defined wantarray;
# At root of tag stack or called in non-void context
if ($DEPTH == 0 || !$void) {
return $html;
}
# Inner-tag body call in void context
else {
push @BODY, $html;
return;
}
}
sub class (@){ push @CLASS, map{ e $_ } map{ split /\s+/, $_ } @_; return; }
sub prop (@){ push @PROP, map{ e $_ } @_; return; }
sub text (@){ push @BODY, map{ indent . e $_ } @_; return; }
sub raw (@){ push @BODY, map{ indent . $_ } @_; return; }
( run in 0.698 second using v1.01-cache-2.11-cpan-5b529ec07f3 )