aboutsummaryrefslogtreecommitdiff
path: root/doc/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'doc/plugins')
-rw-r--r--doc/plugins/contrib/mscgen.mdwn136
1 files changed, 136 insertions, 0 deletions
diff --git a/doc/plugins/contrib/mscgen.mdwn b/doc/plugins/contrib/mscgen.mdwn
new file mode 100644
index 000000000..a6275aeed
--- /dev/null
+++ b/doc/plugins/contrib/mscgen.mdwn
@@ -0,0 +1,136 @@
+[[!tag type/widget]]
+
+This plugin provides the msc [[ikiwiki/directive]].
+This directive allows embedding [mscgen](http://www.mcternan.me.uk/mscgen/)
+message sequence chart graphs in a page.
+
+Here's an mscgen source example.
+
+ \[[!msc src="""
+ arcgradient = 8;
+
+ a [label="Client"],b [label="Server"];
+
+ a=>b [label="data1"];
+ a-xb [label="data2"];
+ a=>b [label="data3"];
+ a<=b [label="ack1, nack2"];
+ a=>b [label="data2", arcskip="1"];
+ |||;
+ a<=b [label="ack3"];
+ |||;
+ """]]
+
+And here's the resulting graph.
+
+[[!msc src=<<"""
+ arcgradient = 8;
+
+ a [label="Client"],b [label="Server"];
+
+ a=>b [label="data1"];
+ a-xb [label="data2"];
+ a=>b [label="data3"];
+ a<=b [label="ack1, nack2"];
+ a=>b [label="data2", arcskip="1"];
+ |||;
+ a<=b [label="ack3"];
+ |||;
+"""]]
+
+Security implications: to be determined.
+
+This plugin uses the [[!cpan Digest::SHA]] perl module.
+
+This plugin borrows heavily from the [[graphviz|plugins/graphviz]] plugin written by [[JoshTriplett]].
+
+I couldn't upload an attachment, so here's the plugin source.
+
+[[!format perl """
+#!/usr/bin/perl
+# mscgen plugin for ikiwiki: render mscgen source as an image.
+# Terry Golubiewski
+# Derived from graphviz plugin by Josh Triplett.
+package IkiWiki::Plugin::mscgen;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+use IPC::Open2;
+
+sub import {
+ hook(type => "getsetup", id => "mscgen", call => \&getsetup);
+ hook(type => "preprocess", id => "msc", call => \&graph);
+}
+
+sub getsetup () {
+ return
+ plugin => {
+ safe => 1,
+ rebuild => undef,
+ section => "widget",
+ },
+}
+
+sub render_graph (\%) {
+ my %params = %{(shift)};
+
+ my $src = "msc {\n";
+ $src .= $params{src};
+ $src .= "\n}\n";
+
+ # Use the sha1 of the mscgen code as part of its filename.
+ eval q{use Digest::SHA};
+ error($@) if $@;
+ my $dest=$params{page}."/msc-".
+ IkiWiki::possibly_foolish_untaint(Digest::SHA::sha1_hex($src)).
+ ".png";
+ will_render($params{page}, $dest);
+
+ if (! -e "$config{destdir}/$dest") {
+ my $pid;
+ my $sigpipe=0;
+ $SIG{PIPE}=sub { $sigpipe=1 };
+ $pid=open2(*IN, *OUT, 'mscgen', '-Tpng', '-i-', '-o-');
+
+ # open2 doesn't respect "use open ':utf8'"
+ binmode (OUT, ':utf8');
+
+ print OUT $src;
+ close OUT;
+
+ my $png;
+ {
+ local $/ = undef;
+ $png = <IN>;
+ }
+ close IN;
+
+ waitpid $pid, 0;
+ $SIG{PIPE}="DEFAULT";
+ error gettext("failed to run mscgen") if $sigpipe;
+
+ if (! $params{preview}) {
+ writefile($dest, $config{destdir}, $png, 1);
+ }
+ else {
+ # in preview mode, embed the image in a data uri
+ # to avoid temp file clutter
+ eval q{use MIME::Base64};
+ error($@) if $@;
+ return "<img src=\"data:image/png;base64,".
+ encode_base64($png)."\" />";
+ }
+ }
+
+ return "<img src=\"".urlto($dest, $params{destpage})."\" />\n";
+}
+
+sub graph (@) {
+ my %params=@_;
+ $params{src} = "" unless defined $params{src};
+ return render_graph(%params);
+}
+
+1
+"""]]