graphviz: Support wikilinks embedded in the graph.
authorJoey Hess <joey@kitenet.net>
Wed, 30 Nov 2011 19:42:42 +0000 (15:42 -0400)
committerJoey Hess <joey@kitenet.net>
Wed, 30 Nov 2011 19:47:13 +0000 (15:47 -0400)
(Sponsored by The TOVA Company.)

IkiWiki/Plugin/graphviz.pm
debian/changelog
doc/ikiwiki/directive/graph.mdwn

index 4268f42..0889bc9 100644 (file)
@@ -11,7 +11,7 @@ use IPC::Open2;
 sub import {
        hook(type => "getsetup", id => "graphviz", call => \&getsetup);
        hook(type => "needsbuild", id => "version", call => \&needsbuild);
-       hook(type => "preprocess", id => "graph", call => \&graph);
+       hook(type => "preprocess", id => "graph", call => \&graph, scan => 1);
 }
 
 sub getsetup () {
@@ -94,7 +94,42 @@ sub render_graph (\%) {
 
 sub graph (@) {
        my %params=@_;
-       $params{src} = "" unless defined $params{src};
+
+       # Support wikilinks in the graph source.
+       my $src=$params{src};
+       $src="" unless defined $src;
+       $src=IkiWiki::linkify($params{page}, $params{destpage}, $params{src});
+       return unless defined wantarray; # scan mode short-circuit
+       if ($src ne $params{src}) {
+               # linkify makes html links, but graphviz wants plain
+               # urls. This is, frankly a hack: Process source as html,
+               # throw out everything inside tags that is not a href.
+               my $s;
+               my $nested=0;
+               use HTML::Parser;
+               error $@ if $@;
+               my $p=HTML::Parser->new(api_version => 3);
+               $p->handler(start => sub {
+                       my %attrs=%{shift()};
+                       if (exists $attrs{href}) {
+                               $s.="\"$attrs{href}\"";
+                       }
+                       $nested++;
+               }, "attr");
+               $p->handler(end => sub {
+                       $nested--;
+               });
+               $p->handler(default => sub {
+                       $s.=join("", @_) unless $nested;
+               }, "text");
+               $p->parse($src);
+               $p->eof;
+               $params{src}=$s;
+       }
+       else {
+               $params{src}=$src;
+       }
+
        $params{type} = "digraph" unless defined $params{type};
        $params{prog} = "dot" unless defined $params{prog};
        error gettext("prog not a valid graphviz program") unless $graphviz_programs{$params{prog}};
index c77fbbe..885ce97 100644 (file)
@@ -8,6 +8,8 @@ ikiwiki (3.20111107) UNRELEASED; urgency=low
     difficult in yaml setup files. (smcv)
   * graphviz: Support urls embedded in the graph, by having graphviz
     generate an imagemap.
+  * graphviz: Support wikilinks embedded in the graph.
+    (Sponsored by The TOVA Company.)
 
  -- Joey Hess <joeyh@debian.org>  Thu, 17 Nov 2011 18:52:23 -0400
 
index 2828921..6584a21 100644 (file)
@@ -5,6 +5,19 @@ graphs in a page.  Example usage:
 
        \[[!graph src="a -> b -> c; a -> c;"]]
 
+Nodes on the graph can link to external urls using regular graphviz syntax,
+and a clickable imagemap will be created. As a special extension for
+ikiwiki, [[WikiLinks|ikiwiki/wikilink]] can also be used. For example:
+
+       \[[!graph src=""""
+       google [ href="http://google.com/" ]
+       sandbox [ href=[[SandBox]] ]
+       help [ href=[[ikiwiki/formatting]] ]
+       newpage [ href=[[NewPage]] ]
+       
+       google -> sandbox -> help -> newpage -> help -> google;
+       """"]]
+
 The `graph` directive supports the following parameters:
 
 - `src` - The graphviz source to render.