GraphViz Formatter
This is the code to generate and display directed and undirected graphs in WikkaWiki using the GraphViz utilities.
Contact: Christopher Vo for more details or bugs.
Note: This code is licensed under Apache License 2.0 as shown in the graphviz.php header.
To use it:
- Back up your wiki. Just in case.
- Make sure your web server has imagemagick (the convert command) and graphviz (dot and neato commands)
- Create an empty directory where the images of the graphs will be stored. It should be accessible to the outside. If the folder is inside your wikkawiki directory you may need to create .htaccess rules to prevent the URL rewriting. Furthermore, make sure your web server software has permissions to the directory you created.
- Drop the graphviz.php (see below) into the "formatters" folder in wikkawiki.
- Modify the options at the top of graphviz.php to make sure that it outputs to the correct folder, and points to the right convert, dot, and neato commands.
It should work now. Use the same syntax as on FormattingRules page.
You might notice that wikkawiki still surrounds the image in the code div (by default, this is a box with a yellow background). To remove that stuff you have to edit formatters/wakka.php to add in a special case.
Look for this in wakka.php (including the comment):
// use internal Wikka highlighter
$output = '<div class="code">'."\n";
$output .= $wakka->Format($code, $language);
$output .= "</div>\n";
$output = '<div class="code">'."\n";
$output .= $wakka->Format($code, $language);
$output .= "</div>\n";
Replace it with this (wakka.php):
if($language == 'graphviz') {
// suppress code div for graphviz environment blocks
$output = $wakka->Format($code, $language);
} else {
// use internal Wikka highlighter
$output = '<div class="code">'."\n";
$output .= $wakka->Format($code, $language);
$output .= "</div>\n";
}
// suppress code div for graphviz environment blocks
$output = $wakka->Format($code, $language);
} else {
// use internal Wikka highlighter
$output = '<div class="code">'."\n";
$output .= $wakka->Format($code, $language);
$output .= "</div>\n";
}
graphviz.php:
<?php
/*
GraphViz Formatter for WikkaWiki
Copyright 2009 Christopher Vo
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
class GraphViz
{
// the output folder
public $ofolder = 'images/graphviz';
// the URI to the output folder
public $url = 'http://domain.com/wiki/images/graphviz';
// Locations for commands
public $convert = '/usr/bin/convert';
public $dot = '/usr/bin/dot';
public $neato = '/usr/bin/neato';
public function render($fulltext) {
$outstr = '';
preg_match_all("#\[dot\](.*?)\[/dot\]#si",$fulltext,$dot_matches);
preg_match_all("#\[neato\](.*?)\[/neato\]#si",$fulltext,$neato_matches);
for ($i=0; $i < count($dot_matches[0]); $i++) {
$data = $dot_matches[1][$i];
// figure out hashes
$hash = md5($data);
$orig = sprintf("%s/%s.gviz",$this->ofolder,$hash);
$psout = sprintf("%s/%s.ps",$this->ofolder,$hash);
$out = sprintf("%s/%s.png",$this->ofolder,$hash);
// check that out doesn't already exist
if(!file_exists($out)) {
// write the file to a temp file
$origh = fopen($orig,"w");
fwrite($origh,$data);
fclose($origh);
// run graphviz and generate an output
$cmd = sprintf("%s -Tps -o%s %s 2>&1", $this->dot, $psout, $orig);
$cmd2 = sprintf("%s -channel RGBA -density 288 -filter Sinc -support 0.2 ".
"-resize 25%s -trim +repage %s %s", $this->convert, '%', $psout, $out);
$errormsg = shell_exec($cmd);
@unlink($orig);
// check if there were any errors
if(strlen($errormsg) > 0) {
$outstr .= "GraphViz threw up: $errormsg\n";
} else {
$errormsg = shell_exec($cmd2);
@unlink($psout);
$outstr .= sprintf('<img src="%s/%s.png" />',$this->url,$hash);
}
}
else {
$outstr .= sprintf('<img src="%s/%s.png" />',$this->url,$hash);
}
}
for ($i=0; $i < count($neato_matches[0]); $i++) {
$data = $neato_matches[1][$i];
// figure out hashes
$hash = md5($data);
$orig = sprintf("%s/%s.neato",$this->ofolder,$hash);
$psout = sprintf("%s/%s.ps",$this->ofolder,$hash);
$out = sprintf("%s/%s.png",$this->ofolder,$hash);
// check that out doesn't already exist
if(!file_exists($out)) {
// write the file to a temp file
$origh = fopen($orig,"w");
fwrite($origh,$data);
fclose($origh);
// run graphviz and generate an output
$cmd = sprintf("%s -Tps -o%s %s 2>&1", $this->neato, $psout, $orig);
$cmd2 = sprintf("%s -channel RGBA -density 288 -filter Sinc -support 0.2 ".
"-resize 25%s -trim +repage %s %s", $this->convert, ''%,$psout,$out);
$errormsg = shell_exec($cmd);
@unlink($orig);
// check if there were any errors
if(strlen($errormsg) > 0) {
$outstr .= "Neato threw up: $errormsg\n";
} else {
$errormsg = shell_exec($cmd2);
@unlink($psout);
$outstr .= sprintf('<img src="%s/%s.png" />',$this->url,$hash);
}
}
else {
$outstr .= sprintf('<img src="%s/%s.png" />',$this->url,$hash);
}
}
return $outstr;
}
}
$gv = new GraphViz;
$output = $gv->render($text);
echo $output;
?>
/*
GraphViz Formatter for WikkaWiki
Copyright 2009 Christopher Vo
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
class GraphViz
{
// the output folder
public $ofolder = 'images/graphviz';
// the URI to the output folder
public $url = 'http://domain.com/wiki/images/graphviz';
// Locations for commands
public $convert = '/usr/bin/convert';
public $dot = '/usr/bin/dot';
public $neato = '/usr/bin/neato';
public function render($fulltext) {
$outstr = '';
preg_match_all("#\[dot\](.*?)\[/dot\]#si",$fulltext,$dot_matches);
preg_match_all("#\[neato\](.*?)\[/neato\]#si",$fulltext,$neato_matches);
for ($i=0; $i < count($dot_matches[0]); $i++) {
$data = $dot_matches[1][$i];
// figure out hashes
$hash = md5($data);
$orig = sprintf("%s/%s.gviz",$this->ofolder,$hash);
$psout = sprintf("%s/%s.ps",$this->ofolder,$hash);
$out = sprintf("%s/%s.png",$this->ofolder,$hash);
// check that out doesn't already exist
if(!file_exists($out)) {
// write the file to a temp file
$origh = fopen($orig,"w");
fwrite($origh,$data);
fclose($origh);
// run graphviz and generate an output
$cmd = sprintf("%s -Tps -o%s %s 2>&1", $this->dot, $psout, $orig);
$cmd2 = sprintf("%s -channel RGBA -density 288 -filter Sinc -support 0.2 ".
"-resize 25%s -trim +repage %s %s", $this->convert, '%', $psout, $out);
$errormsg = shell_exec($cmd);
@unlink($orig);
// check if there were any errors
if(strlen($errormsg) > 0) {
$outstr .= "GraphViz threw up: $errormsg\n";
} else {
$errormsg = shell_exec($cmd2);
@unlink($psout);
$outstr .= sprintf('<img src="%s/%s.png" />',$this->url,$hash);
}
}
else {
$outstr .= sprintf('<img src="%s/%s.png" />',$this->url,$hash);
}
}
for ($i=0; $i < count($neato_matches[0]); $i++) {
$data = $neato_matches[1][$i];
// figure out hashes
$hash = md5($data);
$orig = sprintf("%s/%s.neato",$this->ofolder,$hash);
$psout = sprintf("%s/%s.ps",$this->ofolder,$hash);
$out = sprintf("%s/%s.png",$this->ofolder,$hash);
// check that out doesn't already exist
if(!file_exists($out)) {
// write the file to a temp file
$origh = fopen($orig,"w");
fwrite($origh,$data);
fclose($origh);
// run graphviz and generate an output
$cmd = sprintf("%s -Tps -o%s %s 2>&1", $this->neato, $psout, $orig);
$cmd2 = sprintf("%s -channel RGBA -density 288 -filter Sinc -support 0.2 ".
"-resize 25%s -trim +repage %s %s", $this->convert, ''%,$psout,$out);
$errormsg = shell_exec($cmd);
@unlink($orig);
// check if there were any errors
if(strlen($errormsg) > 0) {
$outstr .= "Neato threw up: $errormsg\n";
} else {
$errormsg = shell_exec($cmd2);
@unlink($psout);
$outstr .= sprintf('<img src="%s/%s.png" />',$this->url,$hash);
}
}
else {
$outstr .= sprintf('<img src="%s/%s.png" />',$this->url,$hash);
}
}
return $outstr;
}
}
$gv = new GraphViz;
$output = $gv->render($text);
echo $output;
?>
List of Resource Pages in MASC