1<?php 2 3/** 4 * Ditaa-Plugin: Converts Ascii-Flowcharts into a png-File 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Dennis Ploeger <develop [at] dieploegers [dot] de> 8 * @author Christoph Mertins <c [dot] mertins [at] gmail [dot] com> 9 * @author Andreas Gohr <andi@splitbrain.org> 10 */ 11 12if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 14require_once(DOKU_PLUGIN.'syntax.php'); 15 16class syntax_plugin_ditaa extends DokuWiki_Syntax_Plugin { 17 18 var $ditaa_name = ''; 19 20 var $ditaa_width = -1; 21 22 var $ditaa_height = -1; 23 24 var $ditaa_data = ''; 25 26 var $pathToJava = "/opt/blackdown-jdk-1.4.2.02/bin/java"; 27 28 var $pathToDitaa = "/var/www/sst.intern.editable/dokuwiki/htdocs/ditaa.jar"; 29 30 var $tempdir = "/tmp"; 31 32 33 /** 34 * What about paragraphs? 35 */ 36 function getPType(){ 37 return 'normal'; 38 } 39 40 /** 41 * What kind of syntax are we? 42 */ 43 function getType(){ 44 return 'substition'; 45 } 46 47 /** 48 * Where to sort in? 49 */ 50 function getSort(){ 51 return 200; 52 } 53 54 55 /** 56 * Connect pattern to lexer (Beginning of parsing) 57 */ 58 59 function connectTo($mode) { 60 $this->Lexer->addEntryPattern('<ditaa.*?>(?=.*?\x3C/ditaa\x3E)', $mode, 'plugin_ditaa'); 61 } 62 63 function postConnect() { 64 $this->Lexer->addExitPattern('</ditaa>', 'plugin_ditaa'); 65 } 66 67 68 /** 69 * Handle the match 70 */ 71 function handle($match, $state, $pos, &$handler) 72 { 73 74 switch ($state) { 75 case DOKU_LEXER_ENTER: 76 preg_match('/width=([0-9]+)/i', substr($match,6,-1), $match_width); 77 preg_match('/height=([0-9]+)/i', substr($match,6,-1), $match_height); 78 preg_match('/name=([a-zA-Z_0-9]+)/i', substr($match,6,-1), $match_name); 79 return array('begin', $match_name[1], $match_width[1], $match_height[1]); 80 break; 81 case DOKU_LEXER_EXIT: 82 return array('end'); 83 break; 84 case DOKU_LEXER_UNMATCHED: 85 return array('data', $match); 86 break; 87 88 } 89 } 90 91 /** 92 * Create output 93 */ 94 function render($format, &$renderer, $data) 95 { 96 97 global $conf; 98 99 if ($data[0] == 'begin') { 100 101 list($state, $name, $width, $height) = $data; 102 103 } else if ($data[0] == 'data') { 104 105 list($state, $mydata) = $data; 106 107 } else { 108 109 $state = $data[0]; 110 111 } 112 113 switch($state) { 114 115 case 'begin': return $this->_ditaa_begin($renderer, $name, $width, $height); 116 case 'data' : return $this->_ditaa_data($mydata); 117 case 'end' : return $this->_ditaa_end($renderer); 118 119 } 120 121 } 122 123 /** 124 * Store values for later ditaa-rendering 125 * 126 * @param object $renderer The dokuwiki-renderer 127 * @param string $name The name for the ditaa-object 128 * @param width $width The width for the ditaa-object 129 * @param height $height The height for the ditaa-object 130 * @return bool All parameters are set 131 */ 132 133 function _ditaa_begin(&$renderer, $name, $width, $height) 134 { 135 // Check, if name is given 136 137 $name = trim(strtolower($name)); 138 139 if ($name == '') { 140 141 $renderer->doc .= '---NO NAME FOR FLOWCHART GIVEN---'; 142 return true; 143 144 } 145 146 $width = trim($width); 147 $height = trim($height); 148 149 if (($width != '') && (settype($width, 'int'))) { 150 151 $this->ditaa_width = $width; 152 153 } 154 155 if (($height != '') && (settype($height, 'int'))) { 156 157 $this->ditaa_height = $height; 158 159 } 160 161 $this->ditaa_name = $name; 162 163 $this->ditaa_data = ''; 164 165 return true; 166 167 } 168 169 /** 170 * Expand the data for the ditaa-object 171 * 172 * @param string $data The data for the ditaa-object 173 * @return bool If everything was right 174 */ 175 176 function _ditaa_data($data) 177 { 178 179 $this->ditaa_data .= $data; 180 181 return true; 182 183 } 184 185 /** 186 * Render the ditaa-object 187 * 188 * @param object $renderer The dokuwiki-Renderer 189 * @return bool If everything was right 190 */ 191 192 function _ditaa_end(&$renderer) 193 { 194 global $conf, $INFO; 195 196 // Write a text file for ditaa 197 198 $tempfile = tempnam($this->tempdir, 'ditaa_'); 199 200 $file = fopen($tempfile.'.txt', 'w'); 201 fwrite($file, $this->ditaa_data); 202 fclose($file); 203 204 $md5 = md5_file($tempfile.'.txt'); 205 206 $mediadir = $conf["mediadir"]."/".str_replace(":", "/",$INFO['namespace'] ); 207 208 if (!is_dir($mediadir)) { 209 umask(002); 210 mkdir($mediadir,0777); 211 } 212 213 $imagefile = $mediadir.'/ditaa_'.$this->ditaa_name.'_'.$md5.'.png'; 214 215 if ( !file_exists($imagefile)) { 216 217 $cmd = $this->pathToJava." -Djava.awt.headless=true -jar ".$this->pathToDitaa." ".$tempfile.".txt ".$tempfile.".png"; 218 219 exec($cmd, $output, $error); 220 221 if ($error != 0) { 222 $renderer->doc .= '---ERROR CONVERTING DIAGRAM---'; 223 return false; 224 } 225 226 if (file_exists($imagefile)) { 227 unlink($imagefile); 228 } 229 230 if ( !copy($tempfile.'.png', $imagefile) ) { 231 return false; 232 } 233 234 // Remove input file 235 unlink($tempfile.'.png'); 236 unlink($tempfile); 237 } 238 239 unlink($tempfile.'.txt'); 240 241 // Output Img-Tag 242 243 $width = NULL; 244 245 if ($this->ditaa_width != -1) { 246 $width = $this->ditaa_width; 247 } 248 249 $height = NULL; 250 251 if ($this->ditaa_height != -1) { 252 $height = $this->ditaa_height; 253 } 254 255 $renderer->doc .= $renderer->internalmedia($INFO['namespace'].':ditaa_'.$this->ditaa_name.'_'.$md5.'.png', $this->ditaa_name, NULL, $width, $height, false); 256 257 return true; 258 259 } 260 261} 262 263 264 265 266?> 267