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