1<?php 2/** 3 * plot-Plugin: Parses gnuplot-blocks 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Wizardry and Steamworks <wizardry.steamworks@outlook.com>, 7 * Alexander 'E-Razor' Krause <alexander.krause@erazor-zone.de> 8 * 9 * [WaS] The following plugin is a revision of the GNUplot Plugin by 10 * Alexander 'E-Razor' Krause from 2005 that uses the original gnuplot binary 11 * in order to render graphs that has been patched up to work on modern 12 * DokuWiki versions. 13 * 14 */ 15 16if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 17 18/** 19 * All DokuWiki plugins to extend the parser/rendering mechanism 20 * need to inherit from this class 21 */ 22class syntax_plugin_plotwas extends DokuWiki_Syntax_Plugin { 23 24 function getType() { return 'protected'; } 25 function getPType() { return 'normal'; } 26 function getSort() { return 200; } 27 28 /** 29 * Connect pattern to lexer 30 */ 31 function connectTo($mode) { 32 $this->Lexer->addEntryPattern('<plot(?=.*\x3C/plot\x3E)', $mode, 'plugin_plotwas'); 33 } 34 35 function postConnect() { 36 $this->Lexer->addExitPattern('</plot>', 'plugin_plotwas'); 37 } 38 39 /** 40 * Handle the match 41 */ 42 function handle($match, $state, $pos, Doku_Handler $handler) { 43 if ( $state == DOKU_LEXER_UNMATCHED ) { 44 $matches = preg_split('/>/u', $match, 2); 45 $matches[0] = trim($matches[0]); 46 if ( trim($matches[0]) == '' ) { 47 $matches[0] = NULL; 48 } 49 return array($matches[1],$matches[0]); 50 } 51 return array($state, '', ''); 52 } 53 54 /** 55 * Create output 56 */ 57 function render($mode, Doku_Renderer $renderer, $data) { 58 global $conf; 59 if($mode == 'xhtml' && strlen($data[0]) > 1) { 60 $plotdir = $conf['mediadir'] . '/plot'; 61 if ( !is_dir($plotdir) ) { 62 mkdir($plotdir, 0777 - $conf['dmask'], true); 63 } 64 65 $hash = md5(serialize($data[0])); 66 $filename = $plotdir.'/'.$hash.'.png'; 67 $size_str = $data[1]; 68 69 // If image already exists, render it immediately 70 if ( is_readable($filename) ) { 71 $renderer->doc .= $this->plugin_render('{{'.'plot:'.$hash.'.png'."$size_str}}"); 72 return true; 73 } 74 75 // Attempt to create image and check for true success 76 if ($this->createImage($filename, $data[0])) { 77 $renderer->doc .= $this->plugin_render('{{'.'plot:'.$hash.'.png'."$size_str}}"); 78 } else { 79 $renderer->doc .= '**ERROR RENDERING GNUPLOT**'; 80 } 81 return true; 82 } 83 84 return false; 85 } 86 87 function createImage($filename, &$data) { 88 $tmpfname = tempnam(sys_get_temp_dir(), "dokuwiki.plot"); 89 90 $gnuplot_data = 'set terminal png transparent nocrop enhanced font arial 8 size 420,320'."\n". 91 "set output '".$filename."'\n" . $data; 92 93 file_put_contents($tmpfname, $gnuplot_data); 94 95 // Execute and capture status 96 exec('/usr/bin/gnuplot '.$tmpfname, $output, $return_var); 97 98 unlink($tmpfname); 99 100 // gnuplot returns 0 on success 101 return ($return_var === 0); 102 } 103 104 // output text string through the parser, allows dokuwiki markup to be used 105 function plugin_render($text, $format='xhtml') { 106 $info = array(); 107 return p_render($format, p_get_instructions($text), $info); 108 } 109} 110