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 57 */ 58 59 function connectTo($mode) { 60 $this->Lexer->addSpecialPattern('<ditaa.*?>\n.*?\n</ditaa>',$mode,'plugin_ditaa'); 61 } 62 63 64 65 /** 66 * Handle the match 67 */ 68 function handle($match, $state, $pos, &$handler) { 69 // prepare default data 70 $return = array( 71 'data' => '', 72 'width' => 0, 73 'height' => 0, 74 'antialias' => true, 75 'edgesep' => true, 76 'round' => false, 77 'shadow' => true, 78 'scale' => 1, 79 'align' => '', 80 ); 81 82 83 // prepare input 84 $lines = explode("\n",$match); 85 $conf = array_shift($lines); 86 array_pop($lines); 87 88 // match config options 89 if(preg_match('/\b(left|center|right)\b/i',$conf,$match)) $return['align'] = $match[1]; 90 if(preg_match('/\b(\d+)x(\d+)\b/',$conf,$match)){ 91 $return['width'] = $match[1]; 92 $return['height'] = $match[2]; 93 } 94 if(preg_match('/\b(\d+)X\b/',$conf,$match)) $return['scale'] = $match[1]; 95 if(preg_match('/\bwidth=([0-9]+)\b/i', $conf,$match)) $return['width'] = $match[1]; 96 if(preg_match('/\bheight=([0-9]+)\b/i', $conf,$match)) $return['height'] = $match[1]; 97 // match boolean toggles 98 if(preg_match_all('/\b(no)?(antialias|edgesep|round|shadow)\b/i',$conf,$matches,PREG_SET_ORDER)){ 99 foreach($matches as $match){ 100 $return[$match[2]] = ! $match[1]; 101 } 102 } 103 104 $return['data'] = join("\n",$lines); 105 106 return $return; 107 } 108 109 /** 110 * Create output 111 */ 112 function render($format, &$R, $data) { 113 if($format != 'xhtml') return; 114 115 // prepare data for ditaa.org 116 $pass = array( 117 'grid' => $data['data'], 118 'scale' => $data['scale'] 119 ); 120 if(!$data['antialias']) $pass['A'] = 'on'; 121 if(!$data['shadow']) $pass['S'] = 'on'; 122 if($data['round']) $pass['r'] = 'on'; 123 if(!$data['edgesep']) $pass['E'] = 'on'; 124 $pass['timeout'] = 25; 125 126 $img = 'http://ditaa.org/ditaa/render?'.buildURLparams($pass,'&'); 127 $img = ml($img,array('w'=>$data['width'],'h'=>$data['height'])); 128 129 $R->doc .= '<img src="'.$img.'" alt="x">'; 130 131 } 132 133 /** 134 * Store values for later ditaa-rendering 135 * 136 * @param object $renderer The dokuwiki-renderer 137 * @param string $name The name for the ditaa-object 138 * @param width $width The width for the ditaa-object 139 * @param height $height The height for the ditaa-object 140 * @return bool All parameters are set 141 */ 142 143 function _ditaa_begin(&$renderer, $name, $width, $height) 144 { 145 // Check, if name is given 146 147 $name = trim(strtolower($name)); 148 149 if ($name == '') { 150 151 $renderer->doc .= '---NO NAME FOR FLOWCHART GIVEN---'; 152 return true; 153 154 } 155 156 $width = trim($width); 157 $height = trim($height); 158 159 if (($width != '') && (settype($width, 'int'))) { 160 161 $this->ditaa_width = $width; 162 163 } 164 165 if (($height != '') && (settype($height, 'int'))) { 166 167 $this->ditaa_height = $height; 168 169 } 170 171 $this->ditaa_name = $name; 172 173 $this->ditaa_data = ''; 174 175 return true; 176 177 } 178 179 /** 180 * Expand the data for the ditaa-object 181 * 182 * @param string $data The data for the ditaa-object 183 * @return bool If everything was right 184 */ 185 186 function _ditaa_data($data) 187 { 188 189 $this->ditaa_data .= $data; 190 191 return true; 192 193 } 194 195 /** 196 * Render the ditaa-object 197 * 198 * @param object $renderer The dokuwiki-Renderer 199 * @return bool If everything was right 200 */ 201 202 function _ditaa_end(&$renderer) 203 { 204 global $conf, $INFO; 205 206 // Write a text file for ditaa 207 208 $tempfile = tempnam($this->tempdir, 'ditaa_'); 209 210 $file = fopen($tempfile.'.txt', 'w'); 211 fwrite($file, $this->ditaa_data); 212 fclose($file); 213 214 $md5 = md5_file($tempfile.'.txt'); 215 216 $mediadir = $conf["mediadir"]."/".str_replace(":", "/",$INFO['namespace'] ); 217 218 if (!is_dir($mediadir)) { 219 umask(002); 220 mkdir($mediadir,0777); 221 } 222 223 $imagefile = $mediadir.'/ditaa_'.$this->ditaa_name.'_'.$md5.'.png'; 224 225 if ( !file_exists($imagefile)) { 226 227 $cmd = $this->pathToJava." -Djava.awt.headless=true -jar ".$this->pathToDitaa." ".$tempfile.".txt ".$tempfile.".png"; 228 229 exec($cmd, $output, $error); 230 231 if ($error != 0) { 232 $renderer->doc .= '---ERROR CONVERTING DIAGRAM---'; 233 return false; 234 } 235 236 if (file_exists($imagefile)) { 237 unlink($imagefile); 238 } 239 240 if ( !copy($tempfile.'.png', $imagefile) ) { 241 return false; 242 } 243 244 // Remove input file 245 unlink($tempfile.'.png'); 246 unlink($tempfile); 247 } 248 249 unlink($tempfile.'.txt'); 250 251 // Output Img-Tag 252 253 $width = NULL; 254 255 if ($this->ditaa_width != -1) { 256 $width = $this->ditaa_width; 257 } 258 259 $height = NULL; 260 261 if ($this->ditaa_height != -1) { 262 $height = $this->ditaa_height; 263 } 264 265 $renderer->doc .= $renderer->internalmedia($INFO['namespace'].':ditaa_'.$this->ditaa_name.'_'.$md5.'.png', $this->ditaa_name, NULL, $width, $height, false); 266 267 return true; 268 269 } 270 271} 272 273 274 275