note that tcc workaround is for bug fixed in tcc now
[ikiwiki] / IkiWiki / Plugin / progress.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::progress;
3
4 use warnings;
5 use strict;
6 use IkiWiki 3.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                         section => "widget",
22                 },
23 }
24
25 sub preprocess (@) {
26         my %params=@_;
27         
28         my $fill;
29         
30         if (defined $params{percent}) {
31                 $fill = $params{percent};
32                 ($fill) = $fill =~ m/($percentage_pattern)/; # fill is untainted now
33                 $fill=~s/%$//;
34                 if (! defined $fill || ! length $fill || $fill > 100 || $fill < 0) {
35                         error(sprintf(gettext("illegal percent value %s"), $params{percent}));
36                 }
37                 $fill.="%";
38         }
39         elsif (defined $params{totalpages} and defined $params{donepages}) {
40                 my $totalcount=pagespec_match_list(
41                         $params{page}, $params{totalpages},
42                         deptype => deptype("presence"));
43                 my $donecount=pagespec_match_list(
44                         $params{page}, $params{donepages},
45                         deptype => deptype("presence"));
46                 
47                 if ($totalcount == 0) {
48                         $fill = "100%";
49                 }
50                 else {
51                         my $number = $donecount/$totalcount*100;
52                         $fill = sprintf("%u%%", $number);
53                 }
54         }
55         else {
56                 error(gettext("need either `percent` or `totalpages` and `donepages` parameters"));
57         }
58
59         return <<EODIV
60 <div class="progress">
61   <div class="progress-done" style="width: $fill">$fill</div>
62 </div>
63 EODIV
64 }
65
66 sub format(@) {
67         my %params = @_;
68
69         # If HTMLScrubber has removed the style attribute, then bring it back
70
71         $params{content} =~ s!<div class="progress-done">($percentage_pattern)</div>!<div class="progress-done" style="width: $1">$1</div>!g;
72
73         return $params{content};    
74 }
75
76 1