1 [[!template id=plugin name=asymptote author="[Peter Simons](http://cryp.to/)"]]
4 This plugin provides the [[ikiwiki/directive/asymptote]]
5 [[ikiwiki/directive]] which allows embedding
6 [asymptote](http://asymptote.sourceforge.net/) diagrams in a page.
8 Security implications: asymptote has functions for reading files and
9 other dangerous stuff, so enabling this plugin means that everyone who
10 can edit your Wiki can also read any file from your hard drive thats
11 accessible to the user running Ikiwiki.
13 [[!if test="enabled(asymptote)" then="""
19 triangle t = triangle((0,0), (4,0), (0.5,2));
20 show(La="$D$", Lb="$E$", Lc="", t);
22 point pD = midpoint(t.BC); dot(pD);
23 point pE = midpoint(t.AC); dot(pE);
26 point A_ = (pD-t.A)*2+t.A; dot("$A'$", A_, NE);
27 draw(t.B--A_--t.C, dashed);
28 draw(t.A--A_, dashed);
30 point E_ = midpoint(line(t.B,A_)); dot(Label("$E'$", E_, E));
35 This plugin uses the [[!cpan Digest::SHA]] perl module.
37 The full source code is:
41 package IkiWiki::Plugin::asymptote;
44 use Digest::MD5 qw(md5_hex);
45 use File::Temp qw(tempdir);
51 hook(type => "getsetup", id => "asymptote", call => \&getsetup);
52 hook(type => "preprocess", id => "asymptote", call => \&preprocess);
67 my $code = $params{src};
68 if (! defined $code && ! length $code) {
69 error gettext("missing src attribute");
71 return create($code, \%params);
75 # This function calls the image generating function and returns
76 # the <img .. /> for the generated image.
80 my $digest = md5_hex(Encode::encode_utf8($code));
82 my $imglink= $params->{page} . "/$digest.png";
83 my $imglog = $params->{page} . "/$digest.log";
84 will_render($params->{page}, $imglink);
85 will_render($params->{page}, $imglog);
87 my $imgurl=urlto($imglink, $params->{destpage});
88 my $logurl=urlto($imglog, $params->{destpage});
90 if (-e "$config{destdir}/$imglink" ||
91 gen_image($code, $digest, $params->{page})) {
92 return qq{<img src="$imgurl}
93 .(exists $params->{alt} ? qq{" alt="} . $params->{alt} : qq{})
94 .qq{" class="asymptote" />};
97 error qq{<a href="$logurl">}.gettext("failed to generate image from code")."</a>";
101 sub gen_image ($$$$) {
102 # Actually creates the image.
105 my $imagedir = shift;
107 my $tmp = eval { create_tmp_dir($digest) };
109 writefile("$digest.asy", $tmp, $code) &&
110 writefile("$imagedir/$digest.png", $config{destdir}, "") &&
111 system("asy -render=2 -offscreen -f png -o $config{destdir}/$imagedir/$digest.png $tmp/$digest.asy &>$tmp/$digest.log") == 0
119 if (open(my $f, '<', "$tmp/$digest.log")) {
125 writefile("$digest.log", "$config{destdir}/$imagedir", $log);
131 sub create_tmp_dir ($) {
132 # Create a temp directory, it will be removed when ikiwiki exits.
135 my $template = $base.".XXXXXXXXXX";
136 my $tmpdir = tempdir($template, TMPDIR => 1, CLEANUP => 1);