<?php
/**
 * plot-Plugin: Parses gnuplot-blocks
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Wizardry and Steamworks <wizardry.steamworks@outlook.com>,
 *             Alexander 'E-Razor' Krause <alexander.krause@erazor-zone.de>
 *
 * [WaS] The following plugin is a revision of the GNUplot Plugin by 
 * Alexander 'E-Razor' Krause from 2005 that uses the original gnuplot binary 
 * in order to render graphs that has been patched up to work on modern
 * DokuWki versions.
 *
 */

if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');

/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_plotwas extends DokuWiki_Syntax_Plugin {
    /**
    * What kind of syntax are we?
    */
    //function accepts($m) { return true; }
    function getType() { return 'protected'; }
    function getPType() { return 'normal'; }
    function getSort() { return 200; }
 
    /**
     * Connect pattern to lexer
     */
    function connectTo($mode) {
        $this->Lexer->addEntryPattern('<plot(?=.*\x3C/plot\x3E)', $mode, 'plugin_plotwas');
    }
    
    function postConnect() {
        $this->Lexer->addExitPattern('</plot>', 'plugin_plotwas');
    }
    
    /**
     * Handle the match
     */
    function handle($match, $state, $pos, Doku_Handler $handler) {
      if ( $state == DOKU_LEXER_UNMATCHED ) {
        $matches = preg_split('/>/u', $match, 2);
        $matches[0] = trim($matches[0]);
        if ( trim($matches[0]) == '' ) {
          $matches[0] = NULL;
        }
        return array($matches[1],$matches[0]);
      }
      return array($state, '', '');
    }
    /**
     * Create output
     */
    function render($mode, Doku_Renderer $renderer, $data) {
      global $conf;
      if($mode == 'xhtml' && strlen($data[0]) > 1) {
        if ( !is_dir($conf['mediadir'] . '/plot') ) {
            mkdir($conf['mediadir'] . '/plot', 0777 - $conf['dmask']);
        }
        
        $hash = md5(serialize($data[0]));
        $filename = $conf['mediadir'] . '/plot/'.$hash.'.png';

        $size_str=$data[1];

        if ( is_readable($filename) ) {
          $renderer->doc .=  $this->plugin_render('{{'.'plot:'.$hash.'.png'."$size_str}}");
          return true;
        }
 
        if (!$this->createImage($filename, $data[0])) {
          $renderer->doc .=  $this->plugin_render('{{'.'plot:'.$hash.'.png'."$size_str}}");
       } else {
          $renderer->doc .= '**ERROR RENDERING GNUPLOT**';
        }
        return true;
      }
      
      return false;
    }
 
    function createImage($filename, &$data) {
      $tmpfname = tempnam("/tmp", "dokuwiki.plot");

      $data = 'set terminal png transparent nocrop enhanced font arial 8 size 420,320'."\n".
               "set output '".$filename."'\n" . $data;

      file_put_contents($tmpfname, $data);

      $retval = exec('/usr/bin/gnuplot '.$tmpfname);

      unlink($tmpfname);
      return 0;
    }

    // output text string through the parser, allows dokuwiki markup to be used
    // very ineffecient for small pieces of data - try not to use
    function plugin_render($text, $format='xhtml') {
      return p_render($format, p_get_instructions($text),$info); 
    }
}