aboutsummaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/htmlbalance.pm
diff options
context:
space:
mode:
Diffstat (limited to 'IkiWiki/Plugin/htmlbalance.pm')
-rw-r--r--IkiWiki/Plugin/htmlbalance.pm58
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