Merge branch 'master' of ssh://git.ikiwiki.info/srv/git/ikiwiki.info
[ikiwiki] / IkiWiki / Plugin / htmlbalance.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::htmlbalance;
3
4 # htmlbalance: Parse and re-serialize HTML to ensure balanced tags
5 #
6 # Copyright 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
7 # Licensed under the GNU GPL, version 2, or any later version published by the
8 # Free Software Foundation
9
10 use warnings;
11 use strict;
12 use IkiWiki 3.00;
13 use HTML::Entities;
14
15 sub import {
16         hook(type => "getsetup", id => "htmlbalance", call => \&getsetup);
17         hook(type => "sanitize", id => "htmlbalance", call => \&sanitize);
18 }
19
20 sub getsetup () {
21         return
22                 plugin => {
23                         safe => 1,
24                         rebuild => undef,
25                 },
26 }
27
28 sub sanitize (@) {
29         my %params=@_;
30         my $ret = '';
31
32         eval q{use HTML::TreeBuilder};
33         error $@ if $@;
34         my $tree = HTML::TreeBuilder->new();
35         $tree->ignore_unknown(0);
36         $tree->ignore_ignorable_whitespace(0);
37         $tree->no_space_compacting(1);
38         $tree->p_strict(1);
39         $tree->store_comments(0);
40         $tree->store_declarations(0);
41         $tree->store_pis(0);
42         $tree->parse_content($params{content});
43         my @nodes = $tree->disembowel();
44         foreach my $node (@nodes) {
45                 if (ref $node) {
46                         $ret .= $node->as_HTML(undef, '', {});
47                         chomp $ret;
48                         $node->delete();
49                 }
50                 else {
51                         $ret .= encode_entities($node);
52                 }
53         }
54         $tree->delete();
55         return $ret;
56 }
57
58 1