2 package IkiWiki
::Plugin
::sparkline
;
9 my $match_num=qr/[-+]?[0-9]+(?:\.[0-9]+)?/;
12 right
=> 'TEXT_RIGHT',
13 bottom
=> 'TEXT_BOTTOM',
18 hook
(type
=> "getsetup", id
=> "sparkline", call
=> \
&getsetup
);
19 hook
(type
=> "preprocess", id
=> "sparkline", call
=> \
&preprocess
);
36 my $style=(exists $params{style
} && $params{style
} eq "bar") ?
"Bar" : "Line";
38 require_once
('sparkline/Sparkline_$style.php');
39 \
$sparkline = new Sparkline_
$style();
40 \
$sparkline->SetDebugLevel(DEBUG_NONE
);
43 foreach my $param (qw{BarWidth BarSpacing YMin YMaz
}) {
44 if (exists $params{lc($param)}) {
45 $php.=qq{\
$sparkline->Set$param(}.int($params{lc($param)}).qq{);\n};
54 if ($key=~/^($match_num)(?:,($match_num))?(?:\(([a-z]+)\))?$/) {
65 if ($style eq "Bar" && defined $3) {
66 $php.=qq{\
$sparkline->SetData($x, $y, '$3');\n};
69 $php.=qq{\
$sparkline->SetData($x, $y);\n};
72 elsif (! length $value) {
73 error gettext
("parse error")." \"$key\"";
75 elsif ($key eq 'featurepoint') {
76 my ($x, $y, $color, $diameter, $text, $location)=
77 split(/\s*,\s*/, $value);
78 if (! defined $diameter || $diameter < 0) {
79 error gettext
("invalid featurepoint diameter");
84 $diameter=int($diameter);
85 $text=~s/[^-a-zA-Z0-9]+//g if defined $text;
86 if (defined $location) {
87 $location=$locmap{$location};
88 if (! defined $location) {
89 error gettext
("invalid featurepoint location");
92 $php.=qq{\
$sparkline->SetFeaturePoint($x, $y, '$color', $diameter};
93 $php.=qq{, '$text'} if defined $text;
94 $php.=qq{, $location} if defined $location;
100 error gettext
("missing values");
103 my $height=int($params{height
} || 20);
104 if ($height < 2 || $height > 100) {
105 error gettext
("invalid height value");
107 if ($style eq "Bar") {
108 $php.=qq{\
$sparkline->Render($height);\n};
111 if (! exists $params{width
}) {
112 error gettext
("missing width parameter");
114 my $width=int($params{width
});
115 if ($width < 2 || $width > 1024) {
116 error gettext
("invalid width value");
118 $php.=qq{\
$sparkline->RenderResampled($width, $height);\n};
121 $php.=qq{\
$sparkline->Output();\n?
>\n};
123 # Use the sha1 of the php code that generates the sparkline as
124 # the base for its filename.
125 eval q{use Digest::SHA};
127 my $fn=$params{page
}."/sparkline-".
128 IkiWiki
::possibly_foolish_untaint
(Digest
::SHA
::sha1_hex
($php)).
130 will_render
($params{page
}, $fn);
132 if (! -e
"$config{destdir}/$fn") {
135 $SIG{PIPE
}=sub { $sigpipe=1 };
136 $pid=open2
(*IN
, *OUT
, "php");
138 # open2 doesn't respect "use open ':utf8'"
139 binmode (OUT
, ':utf8');
152 $SIG{PIPE
}="DEFAULT";
153 if ($sigpipe || ! defined $png) {
154 error gettext
("failed to run php");
157 if (! $params{preview
}) {
158 writefile
($fn, $config{destdir
}, $png, 1);
161 # in preview mode, embed the image in a data uri
162 # to avoid temp file clutter
163 eval q{use MIME::Base64};
165 return "<img src=\"data:image/png;base64,".
166 encode_base64
($png)."\" />";
170 return '<img src="'.urlto
($fn, $params{destpage
}).'" alt="graph" />';