00137: Add syntax for generating a 'graphviz' graph

Summary: Add syntax for generating a 'graphviz' graph
Created: 2004-11-02 10:17
Status: Closed
Category: Feature
Priority: 3
Version: 1.0.13
OS: any

Working. Check out the cookbook entry.

Description: I use pmwiki for adhoc software documentation, and it'd be great to be able to add inline dia tokens and autogenerate a graphviz diagram. Something like the following would be perfect:

digraph Alf {
    size = "6,9";
    node [ shape = record ]; 
    Decl [ label = "\n\nDecl|{name|access|decl_flags|extern_c_linkage}"]; 
    Nontype_decl [ label = "Nontype_decl|{type}"]; 
    Defined_decl [ label = "Defined_decl|{linkage}"];
    Data_decl [ label = "Data_decl|{storage_class}"];
    Function_decl [ label = "Function_decl|{formals|defaults}"];
    Data [ label = "Data|{initializer}"]; 
    Function [ label = "Function|{body}"]; 
    Constructor [ label = "Constructor|{member_initializers}"]; 
    Aggregate ->  Type_decl ; 
    Class -> Aggregate;
    Union -> Aggregate;
    Data -> Data_decl;
    Data -> Defn;
    Data_decl -> Defined_decl;
    Data_member ->  Nontype_decl ;
    Defined_decl -> Nontype_decl;
    Defn -> Defined_decl;
    Enum ->  Type_decl ;
    Enumerator ->  Nontype_decl ;
    Function -> Defn;
    Function -> Function_decl;
    Constructor -> Function;
    Destructor -> Function;
    Function_decl -> Defined_decl;
    Nontype_decl ->  Decl ;
    Template_type_arg ->  Type_decl ;
    Type_decl ->  Decl ;
    Typedef ->  Type_decl ;

This would call the graphviz tool's generator and then generate and display the graph.

I've started working on this, but I can't get the $DoubleBrackets to propogate to a higher level. I've created a graphviz.php that lives in .../local and is invoked by include_once() in config.php. if I put a "print("hello")", I see the "hello", but for some reason the addition to the DoubleBrackets array is not propogating properly. Any clues?

I've added the mapping directly to the DoubleBrackets in pmwiki.php and I've created the following function:

function graphviz( $dot_description) {
        $dot_description = preg_replace( "/>/", ">", $dot_description);
        $dot_file = fopen( "/var/www/pmwiki/graphs/a.dot","wb");
        fputs( $dot_file, $dot_description, strlen( $dot_description));
        return 'http://paulw-linux/cgi-bin/webdot/graphs/a.dot.dot.png';

This works fameously for a very simple chart:

 [graphviz[[ digraph G { Hello->World } ]]]

there are a few drawbacks:

  1. cannot yet support multiline graphs -- anything much more complex than this should be multiline
  2. can't figure out how to extend $DoubleBrackets to make a drop-in cookbook script
  3. need to determine page name at runtime to avoid overwriting the same dot file over and over again
  4. need to determine runtime directory to avoid hardcoding the dot cache directory
  5. need to examine last edit time of the page and avoid recreating an unchanged dot file. This will make the graph generation much faster as webdot already knows how to cache generated gfx.

First, I'd suggest trying something like this in PmWiki 2 instead of PmWiki 1 -- you get much more control that way. But beyond that--

1. To make things multiline, take advantage of [=...=] to do it. One easy way is to make a markup that looks like:

   =graphviz [=
     ... stuff goes here

where the [= and =] enclose the (multiline) information needed to be passed to graphviz. In PmWiki 2 I'd do it as:

   (:graphviz:) [=
     ... stuff goes here

although, as long as the graphviz code doesn't contain :) it could be done as:

      ... stuff goes here

2. It really does belong as a cookbook script. Take a look at the MimeTex cookbook entry for some ideas about handling the caching and pagename issues.


Well, I am a little leery of using a devel version of software right now, so I'd like to get this working in PmWiki 1... I've run into another "Interesting" problem:

I've changed the syntax, per Pm's first suggestion, so the markup I'm testing with looks like this:

  =graphviz [=
  digraph G {
      Hello->"From Me";

The DoubleBrackets patter is as follows:

  '/\\=graphviz (.*)/e' => 'graphviz("$1");'

What I'm seeing is that if, in the graphviz() subroutine I do this:

  function graphviz( $dot_description) {
          return( $dot_description);

I get

  digraph G { Hello->World; Hello->"From Me"; }

which is perfectly acceptable. Unfortunately as soon as I try to do something to the string other than return it, I get wonky results as follows:

  function graphviz( $dot_description) {
          return print_r( $dot_description);



Has anyone experienced this before????