Mediawiki/Erweiterung/GnuplotBasic
< Mediawiki | Erweiterung
Die Mediawiki-Erweiterung GnuplotBasic erlaubt die Erzeugung und Anzeige von grafischen Darstellungen. Dabei wird das Programm Gnuplot verwendet.
Installation
1. Voraussetzung ist die Installation des Pakets "gnuplot".
# apt-get install gnuplot
2. Anlegen der Datei "extensions/Gnuplot.php" und Einfügen des folgenden PHP-Codes: GnuplotBasic 0.9.3 (2009-01-15).
# mkdir extensions/GnuplotBasic # chown wiki:wiki extensions/GnuplotBasic # vi extensions/GnuplotBasic/GnuplotBasic.php
<?php
/*****************************************************************************
* PURPOSE
* Extension script to use Gnuplot in a MediaWiki instance.
* Insert the Gnuplot code between the tags <gnuplot>...</gnuplot>.
*
* Within <gnuplot> ... </gnuplot> this extension accepts (inline) plotdata
* within <plotdata> ... </plotdata>. If there is plotdata the source
* is spilt in a plotscript-part and a plotdata-part. Note that <plotdata> is
* not a MediaWiki hook.
*
* AUTHOR
* Gérard de Smaele
*
* NOTES
* Include this in the LocalSettings.php:
* 1) add 'require_once("extensions/GnuplotBasic/GnuplotBasic.php")'
* 2) Set $wgGnuplotCommand to the Gnuplot executable.
* For windows: "C:\\Program files\\Gnuplot\\pgnuplot.exe"
* Default: "/usr/bin/gnuplot"
* 3) Set $wgGnuplotRefreshRate to desired refresh rate
* (in seconds) of a graph in case it already exists.
* - (24*60*60) Refresh after one day (x seconds)
* - (0) Refresh always (zero)
* - (-1) Refresh never (minus one)
* 4) Set $wgGnuplotDefaultTerminal to standard terminal e.g.
* - set terminal png transparent small (default)
* - set terminal png transparent font verdana 8
*******************************************************************************/
// Extension credits that will show up on Special:Version
$wgExtensionCredits['parserhook'][] = array(
'name' => 'GnuplotBasic',
'author' => 'Gérard de Smaele',
'version' => '0.9.3',
'description' => 'Adds the tag <code><gnuplot></code> to use Gnuplot',
'url' => 'http://www.mediawiki.org/wiki/Extension:GnuplotBasic',
);
$wgGnuplotCommand = '/usr/bin/gnuplot'; // Unix
#$wgGnuplotCommand = 'C:\\Wamp\\bin\\gnuplot\\bin\\pgnuplot.exe'; // Windows
$wgGnuplotDefaultTerminal = 'set terminal png transparent small';
$wgGnuplotDefaultSize = 'set size 0.5, 0.5';
$wgGnuplotRefreshRate = -1; // Refresh never if gnuplot call hasn't changed (default)
// Avoid unstubbing $wgParser too early on modern (1.12+) MW versions, as per r35980
if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
$wgHooks['ParserFirstCallInit'][] = 'wfGnuplotBasicExtension';
} else {
$wgExtensionFunctions[] = 'wfGnuplotBasicExtension';
}
function wfGnuplotBasicExtension() {
global $wgParser;
$wgParser->setHook( 'gnuplot', 'renderPlot' );
return true;
}
function renderPlot( $gnuplotsrc ) {
global $wgGnuplotDefaultTerminal, $wgGnuplotDefaultSize;
global $wgGnuplotCommand, $wgGnuplotRefreshRate;
global $wgUploadDirectory, $wgUploadPath;
// create directory for storing the plot files
$gnuplotDir = "/gnuplot/";
$dest = $wgUploadDirectory . $gnuplotDir;
if( !is_dir( $dest ) ) {
mkdir($dest, 0777);
chmod($dest, 0777);
}
// make sure the path is correct for both Windows and UNIX
chdir($dest);
$dest = getcwd();
// get the filename of the graph to be produced
$name = getFileName( $gnuplotsrc );
$graphname = $dest . DIRECTORY_SEPARATOR .$name;
$fname = $graphname . ".tmp"; //gnuplot plotscript
$dname = $graphname . ".dat"; //gnuplot plotdata
$makeGraph = true;
if( ( file_exists( $graphname ) ) and ( ( $wgGnuplotRefreshRate ) <> 0 ) ) {
// the file already exists it won't be refreshed when
// it is newer than the refreshrate OR setting set to never refresh
if( (time() - filemtime($graphname)) < ($wgGnuplotRefreshRate) ) $makeGraph = false;
if( ($wgGnuplotRefreshRate) == -1 ) $makeGraph = false;
}
if( $makeGraph ) {
// Step 1: Check if there is plotdata defined
$pos1 = strpos($gnuplotsrc, "<plotdata>");
if( $pos1 !== false ){
// split gnuplotsrc in a plotscript-part and a plotdata-part
$pos2 = strpos($gnuplotsrc, "</plotdata>");
if( $pos2 === false ) $pos2 = strlen($gnuplotsrc);
$plotdata = substr($gnuplotsrc, $pos1+10, $pos2-($pos1+10));
$gnuplotsrc = substr($gnuplotsrc, 0, $pos1);
// replace gnuplot inline filename(s) '-' to the plotdata filename
$gnuplotsrc = str_replace("'-'", "'$dname'", $gnuplotsrc);
// save the plotdata-part
$handle2 = fopen($dname, 'w');
fwrite($handle2, trim($plotdata));
fclose($handle2);
}
// Step 2: Parse the plotscript-part and do some basic syntax checking
$unparsedScriptArray = explode( "\n", $gnuplotsrc );
$parsedScriptArray = array_filter( $unparsedScriptArray, "parsePlotScript" );
$gnuplotsrc = implode( "\n", $parsedScriptArray );
// write the default settings and the input code from wiki into a
// temporary file to be executed by gnuplot, then execute the command
$handle = fopen($fname, 'w');
// if terminal and size are not set in the gnuplot source we do it here
if( strpos($gnuplotsrc, 'set terminal ') === false ) {
fwrite($handle, $wgGnuplotDefaultTerminal . "\n");
}
if( strpos($gnuplotsrc, 'set size ') === false ) {
fwrite($handle, $wgGnuplotDefaultSize . "\n");
}
fwrite($handle, "\nset output '" . $graphname . "'\n");
// save the plotscript-part
fwrite($handle, $gnuplotsrc . "\n");
fwrite($handle, "exit" . "\n");
fclose($handle);
// execute the gnuplot command
$cmdlinePlot = $wgGnuplotCommand . ' ' . $fname;
shell_exec($cmdlinePlot);
// cleanup temporary files
unlink($fname);
if( $pos1 !== false ) unlink($dname);
}
return '<p><b><img src="' . htmlspecialchars($wgUploadPath . $gnuplotDir . $name) .
'" alt="GnuplotBasic Plot"></b></p>';
}
/***
* Function: parsePlotScript
* Purpose : Basic syntax checks and replaces unwanted and potentially harmful commands.
* Note that gnuplot allows far more advanced syntax than is allowed
* and recognised here. This should however suffice most graph needs from
* within a MediaWiki instance.
* Input : &$scriptline - a line from the scriptpart (by reference because we do
* some modifications here).
* Output : false if the line ends up empty.
*/
function parsePlotScript( &$scriptline ) {
$unwantedCommands = array(
"`" => "",
"set output " => "xxx xxxxxx ",
"shell" => "xxxxx", // potentially harmful
"system" => "xxxxxx", // potentially harmful
"load " => "xxxx ",
"call " => "xxxx ",
"save " => "xxxx ",
"cd '" => "xx ",
"cd \"" => "xx ",
"update " => "xxxxxx "
);
$scriptline = trim($scriptline);
if( strlen($scriptline) == 0 ) return false;
// Step 1: Delete everything after the first comment character
$p = strpos($scriptline, "#");
if( $p !== false ) {
$scriptline = substr($scriptline, 0, $p);
$scriptline = trim($scriptline);
if( strlen($scriptline) == 0 ) return false;
}
// Step 2: Replace unwanted commands with substitutes
$scriptline = strtr($scriptline, $unwantedCommands);
$scriptline = trim($scriptline);
if( strlen($scriptline) == 0 ) return false;
return true;
}
/***
* Function: getFileName
* Purpose : Determines the unique name of the output file.
* The filename is computed by a hash function and therefore always unique
* for the script plus its (optional) inline plotdata.
* The file extension is extracted from de format in the "set terminal"
* command. If this format is not found or there is a syntax error it is
* set to "xxx".
* Input : $gnuplotsrc - the <gnuplot> input code from the wiki markup
* Output : The file name with its extension
*/
function getFileName ( $gnuplotsrc ) {
// determine the file format of the plotted graph image - default is png
$format = "png";
$tpos = strpos($gnuplotsrc, "set terminal ");
if( $tpos !== false ) {
$format = '';
$tpos = $tpos + strlen("set terminal ");
// extract the fileformat from this command, this is considered
// to be the next word either ending with " ", "\n" or "\t"
$done = false;
do {
$char = substr($gnuplotsrc, $tpos, 1);
$tpos = $tpos + 1;
if( $char !== false ) {
if( ($char == " ") || ($char == "\n") || ($char == "\t") ) {
$done = true;
} else {
$format .= $char;
}
} else {
$done = true;
}
} while( !$done );
$format = trim($format);
if( (strlen($format) == 0) || (strlen($format) > 6) ) $format = "xxx";
}
$filename = md5($gnuplotsrc) . "." . $format;
return $filename;
}
?>
|
3. Anpassung der Rechte.
# chown wiki:wiki extensions/GnuplotBasic/GnuplotBasic.php
4. Einfügen der folgenden Zeile in die Datei "LocalSettings.php".
## Extension: GnuplotBasic require_once("$IP/extensions/GnuplotBasic/GnuplotBasic.php"); $wgGnuplotCommand = "/usr/bin/gnuplot";
Weblinks
- Extension:GnuplotBasic (Mediawiki.org)