Extension:MscGen

Purpose
extension to display Message Sequence Chart's. It allows to display message flows. Flowchart was my first attempt to include such in MediaWiki, but recently I found the neat tool from http://www.mcternan.me.uk/mscgen/index.html which had been inspired by graphViz.

The code needs some cleaning up, but works.

Code
dotCommand = "/usr/bin/mscgen";

$wgExtensionFunctions[] = "wfGraphVizExtension";

function wfGraphVizExtension { global $wgParser; $wgParser->setHook( "mscgen", "renderMscGen" ); }

function renderMscGen( $timelinesrc ) {   global $wgUploadDirectory, $wgUploadPath, $IP, $wgGraphVizSettings, $wgArticlePath, $wgTmpDirectory; $hash = md5( $timelinesrc ); $dest = $wgUploadDirectory."/mscgen/"; if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); } if ( ! is_dir( $wgTmpDirectory ) ) { mkdir( $wgTmpDirectory, 0777 ); }

$fname = $dest. $hash; // echo $fname; if ( ! ( file_exists( $fname.".png" ) || file_exists( $fname.".err" ) ) ) {       $handle = fopen($fname, "w"); fwrite($handle, $timelinesrc); fclose($handle);

$cmdline = wfEscapeShellArg( $wgGraphVizSettings->dotCommand). " -T png -o ". wfEscapeShellArg( $fname. ".png"). " " .         " -i ". wfEscapeShellArg( $fname ). " 2>&1 >" . wfEscapeShellArg( $fname. ".err"). " && rm ". wfEscapeShellArg( $fname. ".err"); $ret = `{$cmdline}`; #     echo $cmdline; #     exit; #     break; #     echo "ADIOS"; if ($ret) unlink ( $fname. ".err");

unlink($fname);

}

@$err=file_get_contents( $fname.".err" );

if ( $err != "" ) { $txt = "$err "; } else { $txt = ""; }   return $txt; }

?>

Conversion from Flowchart to Mscgen
You can use the following perl script to convert from flowchart to mscgen

#  $inside_flowchart = 0; foreach $line (<>) {  if ($line=~m/\<\s*flowchart\s*\>/ig) {     $line=~s/:/,/g; chomp $line; $line.=";\n"; $line=~s/\<\s*flowchart\s*\>/\\nmsc\ \{\n\ \ \ /ig; $inside_flowchart = 1; print $line; $line=""; }  if ($line=~m/\<\s*\/flowchart\s*\>/ig) {       $line=~s/\<\s*\/flowchart\s*\>/\}\n\<\/mscgen\>/ig; $inside_flowchart = 0; }  if ($inside_flowchart == 1) { 	if ($line=~m/^\s*(.+)\s+(.+)\s+(.+)/g) { 	    print "   $1->$2 \t[ label = \"$3\" ]; \n"; }  }   else {     print $line; } }
 * 1) program to convert  to
 * 1) author: shishir birmiwal
 * 2) ref: http://meta.wikimedia.org/wiki/MscGen
 * 3)      http://meta.wikimedia.org/wiki/Flowchart
 * 4) method of use:
 * 5) put flowchart syntax text into a file, say flowchart.txt
 * 6)  (don't forget to include  )
 * 7) call using
 * 8)    perl -w flowchart2mscgen.pl flowchart.txt > mscgen.txt

Extension to for other graphviz tools
see for examples: dotCommand = "/usr/bin/dot"; $wgGraphVizSettings->circoCommand = "/usr/bin/circo"; $wgGraphVizSettings->neatoCommand = "/usr/bin/neato"; $wgGraphVizSettings->twopiCommand = "/usr/bin/twopi"; $wgGraphVizSettings->fdpCommand = "/usr/bin/fdp";

$wgExtensionFunctions[] = "wfGraphVizExtension";

function wfGraphVizExtension { global $wgParser; $wgParser->setHook( "graphviz", "renderDot" ); $wgParser->setHook( "graphviz-dot", "renderDot" ); $wgParser->setHook( "graphviz-circo", "renderCirco" ); $wgParser->setHook( "graphviz-neato", "renderNeato" ); $wgParser->setHook( "graphviz-twopi", "renderTwopi" ); $wgParser->setHook( "graphviz-fdp", "renderFdp" ); }

function renderDot($timelinesrc) { error_reporting(E_ALL); global $wgGraphVizSettings; return renderGraphviz($timelinesrc, $wgGraphVizSettings->dotCommand); }

function renderCirco($timelinesrc) { global $wgGraphVizSettings; return renderGraphviz($timelinesrc, $wgGraphVizSettings->circoCommand); }

function renderNeato($timelinesrc) { global $wgGraphVizSettings; return renderGraphviz($timelinesrc, $wgGraphVizSettings->neatoCommand); }

function renderTwopi($timelinesrc) { global $wgGraphVizSettings; return renderGraphviz($timelinesrc, $wgGraphVizSettings->twopiCommand); }

function renderFdp($timelinesrc) { global $wgGraphVizSettings; return renderGraphviz($timelinesrc, $wgGraphVizSettings->fdpCommand); }

function renderGraphviz( $timelinesrc, $graphVizCommand ) { error_reporting(E_ALL); global $wgUploadDirectory, $wgUploadPath, $IP, $wgGraphVizSettings, $wgArticlePath, $wgTmpDirectory; $hash = md5( $timelinesrc ); $dest = $wgUploadDirectory."/graphviz/"; if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); } if ( ! is_dir( $wgTmpDirectory ) ) { mkdir( $wgTmpDirectory, 0777 ); }

$fname = $dest. $hash; //	echo $fname; if ( ! ( file_exists( $fname.".png" ) || file_exists( $fname.".err" ) ) ) {		$handle = fopen($fname, "w"); fwrite($handle, $timelinesrc); fclose($handle);

$cmdline = wfEscapeShellArg( $graphVizCommand ). " -Tpng -o ". wfEscapeShellArg( $fname. ".png"). " " .		 wfEscapeShellArg( $fname ) ; $cmdlinemap = wfEscapeShellArg( $graphVizCommand). " -Tcmapx -o ". wfEscapeShellArg( $fname. ".map"). " " .		 wfEscapeShellArg( $fname ) ;

//		echo $cmdline; //		exit; //		break; //		echo "ADIOS"; $ret .= `{$cmdline}`; $ret = `{$cmdlinemap}`; //		$ret = shell_exec($cmdline); //		$ret .= shell_exec($cmdlinemap); //		$ret .= shell_exec("id -Z"); unlink($fname); /*				return "CMD: $cmdline CMDMAP: $cmdlinemap 		RET: $ret		 ";

/*		if ( $ret == "" ) { // Message not localized, only relevant during install return $ret."Timeline error: Executable not found. Command line was: {$cmdline} "; }	}	@$err=file_get_contents( $fname.".err" );

if ( $err != "" ) { $txt = "$err "; } else { //echo $fname.".map"; @$map = file_get_contents( $fname.".map" ); //echo "mapa-antes:".$map; $map=preg_replace("##"," ",$map); $map=str_replace(" ","",$map);

//echo "mapa:".$map; if (substr(php_uname, 0, 7) == "Windows") { $ext = "gif"; } else { $ext = "png"; }		$txt = "{$map} ". "<img usemap=\"#{$hash}\" src=\"{$wgUploadPath}/graphviz/{$hash}.{$ext}\">"; }	return $txt; }

?>