diff options
Diffstat (limited to 'IkiWiki/Plugin/htmlbalance.pm')
-rw-r--r-- | IkiWiki/Plugin/htmlbalance.pm | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/IkiWiki/Plugin/htmlbalance.pm b/IkiWiki/Plugin/htmlbalance.pm new file mode 100644 index 000000000..da450eea7 --- /dev/null +++ b/IkiWiki/Plugin/htmlbalance.pm @@ -0,0 +1,58 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::htmlbalance; + +# htmlbalance: Parse and re-serialize HTML to ensure balanced tags +# +# Copyright 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/> +# Licensed under the GNU GPL, version 2, or any later version published by the +# Free Software Foundation + +use warnings; +use strict; +use IkiWiki 3.00; +use HTML::Entities; + +sub import { + hook(type => "getsetup", id => "htmlbalance", call => \&getsetup); + hook(type => "sanitize", id => "htmlbalance", call => \&sanitize); +} + +sub getsetup () { + return + plugin => { + safe => 1, + rebuild => undef, + }, +} + +sub sanitize (@) { + my %params=@_; + my $ret = ''; + + eval q{use HTML::TreeBuilder}; + error $@ if $@; + my $tree = HTML::TreeBuilder->new(); + $tree->ignore_unknown(0); + $tree->ignore_ignorable_whitespace(0); + $tree->no_space_compacting(1); + $tree->p_strict(1); + $tree->store_comments(0); + $tree->store_declarations(0); + $tree->store_pis(0); + $tree->parse_content($params{content}); + my @nodes = $tree->disembowel(); + foreach my $node (@nodes) { + if (ref $node) { + $ret .= $node->as_HTML(undef, '', {}); + chomp $ret; + $node->delete(); + } + else { + $ret .= encode_entities($node); + } + } + $tree->delete(); + return $ret; +} + +1 |