progress: Display an error if the progress cannot be parsed, and allow the percent...
[ikiwiki] / IkiWiki / Plugin / progress.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::progress;
3
4 use warnings;
5 use strict;
6 use IkiWiki 2.00;
7
8 my $percentage_pattern = qr/[0-9]+\%?/; # pattern to validate percentages
9
10 sub import { #{{{
11         hook(type => "getsetup", id => "progress", call => \&getsetup);
12         hook(type => "preprocess", id => "progress", call => \&preprocess);
13         hook(type => "format",     id => "progress", call => \&format);
14 } # }}}
15
16 sub getsetup () { #{{{
17         return 
18                 plugin => {
19                         safe => 1,
20                         rebuild => undef,
21                 },
22 } #}}}
23
24 sub preprocess (@) { #{{{
25         my %params=@_;
26         
27         my $fill;
28         
29         if (defined $params{percent}) {
30                 $fill = $params{percent};
31                 ($fill) = $fill =~ m/($percentage_pattern)/; # fill is untainted now
32                 if (! defined $fill || ! length $fill || $fill > 100 || $fill < 0) {
33                         error("illegal percent value $params{percent}");
34                 }
35                 elsif ($fill !~ /%$/) {
36                         $fill.="%";
37                 }
38         }
39         elsif (defined $params{totalpages} and defined $params{donepages}) {
40                 add_depends($params{page}, $params{totalpages});
41                 add_depends($params{page}, $params{donepages});
42
43                 my @pages=keys %pagesources;
44                 my $totalcount=0;
45                 my $donecount=0;
46                 foreach my $page (@pages) {
47                         $totalcount++ if pagespec_match($page, $params{totalpages}, location => $params{page});
48                         $donecount++ if pagespec_match($page, $params{donepages}, location => $params{page});
49                 }
50                 
51                 if ($totalcount == 0) {
52                         $fill = "100%";
53                 }
54                 else {
55                         my $number = $donecount/$totalcount*100;
56                         $fill = sprintf("%u%%", $number);
57                 }
58         }
59         else {
60                 error("need either `percent` or `totalpages` and `donepages` parameters");
61         }
62
63         return <<EODIV
64 <div class="progress">
65   <div class="progress-done" style="width: $fill">$fill</div>
66 </div>
67 EODIV
68 } # }}}
69
70 sub format(@) { #{{{
71         my %params = @_;
72
73         # If HTMLScrubber has removed the style attribute, then bring it back
74
75         $params{content} =~ s!<div class="progress-done">($percentage_pattern)</div>!<div class="progress-done" style="width: $1">$1</div>!g;
76
77         return $params{content};    
78 } #}}}
79
80 1