3b664f4cb29ecc4df553db0cf6722de7d00ce585
[ikiwiki.git] / 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                 },
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                 $fill=~s/%$//;
33                 if (! defined $fill || ! length $fill || $fill > 100 || $fill < 0) {
34                         error(sprintf(gettext("illegal percent value %s"), $params{percent}));
35                 }
36                 $fill.="%";
37         }
38         elsif (defined $params{totalpages} and defined $params{donepages}) {
39                 add_depends($params{page}, $params{totalpages}, content => 0);
40                 add_depends($params{page}, $params{donepages}, content => 0);
41
42                 my @pages=keys %pagesources;
43                 my $totalcount=0;
44                 my $donecount=0;
45                 foreach my $page (@pages) {
46                         $totalcount++ if pagespec_match($page, $params{totalpages}, location => $params{page});
47                         $donecount++ if pagespec_match($page, $params{donepages}, location => $params{page});
48                 }
49                 
50                 if ($totalcount == 0) {
51                         $fill = "100%";
52                 }
53                 else {
54                         my $number = $donecount/$totalcount*100;
55                         $fill = sprintf("%u%%", $number);
56                 }
57         }
58         else {
59                 error(gettext("need either `percent` or `totalpages` and `donepages` parameters"));
60         }
61
62         return <<EODIV
63 <div class="progress">
64   <div class="progress-done" style="width: $fill">$fill</div>
65 </div>
66 EODIV
67 }
68
69 sub format(@) {
70         my %params = @_;
71
72         # If HTMLScrubber has removed the style attribute, then bring it back
73
74         $params{content} =~ s!<div class="progress-done">($percentage_pattern)</div>!<div class="progress-done" style="width: $1">$1</div>!g;
75
76         return $params{content};    
77 }
78
79 1