1<?php 2/** 3 * Ditaa-Plugin: Converts Ascii-Flowcharts into a png-File 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Dennis Ploeger <develop [at] dieploegers [dot] de> 7 * @author Christoph Mertins <c [dot] mertins [at] gmail [dot] com> 8 * @author Andreas Gohr <andi@splitbrain.org> 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 /** 18 * What about paragraphs? 19 */ 20 function getPType(){ 21 return 'normal'; 22 } 23 24 /** 25 * What kind of syntax are we? 26 */ 27 function getType(){ 28 return 'substition'; 29 } 30 31 /** 32 * Where to sort in? 33 */ 34 function getSort(){ 35 return 200; 36 } 37 38 /** 39 * Connect pattern to lexer 40 */ 41 42 function connectTo($mode) { 43 $this->Lexer->addSpecialPattern('<ditaa.*?>\n.*?\n</ditaa>',$mode,'plugin_ditaa'); 44 } 45 46 /** 47 * Handle the match 48 */ 49 function handle($match, $state, $pos, &$handler) { 50 $info = $this->getInfo(); 51 52 // prepare default data 53 $return = array( 54 'width' => 0, 55 'height' => 0, 56 'antialias' => true, 57 'edgesep' => true, 58 'round' => false, 59 'shadow' => true, 60 'scale' => 1, 61 'align' => '', 62 'version' => $info['date'], //forece rebuild of images on update 63 ); 64 65 66 // prepare input 67 $lines = explode("\n",$match); 68 $conf = array_shift($lines); 69 array_pop($lines); 70 71 // match config options 72 if(preg_match('/\b(left|center|right)\b/i',$conf,$match)) $return['align'] = $match[1]; 73 if(preg_match('/\b(\d+)x(\d+)\b/',$conf,$match)){ 74 $return['width'] = $match[1]; 75 $return['height'] = $match[2]; 76 } 77 if(preg_match('/\b(\d+(\.\d+)?)X\b/',$conf,$match)) $return['scale'] = $match[1]; 78 if(preg_match('/\bwidth=([0-9]+)\b/i', $conf,$match)) $return['width'] = $match[1]; 79 if(preg_match('/\bheight=([0-9]+)\b/i', $conf,$match)) $return['height'] = $match[1]; 80 // match boolean toggles 81 if(preg_match_all('/\b(no)?(antialias|edgesep|round|shadow)\b/i',$conf,$matches,PREG_SET_ORDER)){ 82 foreach($matches as $match){ 83 $return[$match[2]] = ! $match[1]; 84 } 85 } 86 87 $input = join("\n",$lines); 88 $return['md5'] = md5($input); // we only pass a hash around 89 90 // store input for later use 91 io_saveFile($this->_cachename($return,'txt'),$input); 92 93 return $return; 94 } 95 96 /** 97 * Create output 98 */ 99 function render($format, &$R, $data) { 100 if($format != 'xhtml') return; 101 $img = DOKU_BASE.'lib/plugins/ditaa/ditaa.php?'.buildURLparams($data,'&'); 102 103 $R->doc .= '<img src="'.$img.'" class="media'.$data['align'].'" alt=""'; 104 if($data['width']) $R->doc .= ' width="'.$data['width'].'"'; 105 if($data['height']) $R->doc .= ' height="'.$data['height'].'"'; 106 if($data['align'] == 'right') $ret .= ' align="right"'; 107 if($data['align'] == 'left') $ret .= ' align="left"'; 108 $R->doc .= '/>'; 109 } 110 111 /** 112 * Cache file is based on data 113 */ 114 function _cachename($data,$ext){ 115 unset($data['width']); 116 unset($data['height']); 117 unset($data['align']); 118 return getcachename(join('x',array_values($data)),'.ditaa.'.$ext); 119 } 120 121 /** 122 * Render the output remotely at ditaa.org 123 */ 124 function _remote($data,$in,$out){ 125 $http = new DokuHTTPClient(); 126 $http->timeout=30; 127 128 $pass = array(); 129 $pass['scale'] = $data['scale']; 130 $pass['timeout'] = 25; 131 $pass['grid'] = io_readFile($in); 132 if(!$data['antialias']) $pass['A'] = 'on'; 133 if(!$data['shadow']) $pass['S'] = 'on'; 134 if($data['round']) $pass['r'] = 'on'; 135 if(!$data['edgesep']) $pass['E'] = 'on'; 136 137 $img = $http->post('http://ditaa.org/ditaa/render',$pass); 138 if(!$img) return false; 139 140 io_saveFile($out,$img); 141 return true; 142 } 143 144 145 /** 146 * Run the ditaa Java program 147 */ 148 function _run($data,$in,$out) { 149 global $conf; 150 151 if(!file_exists($in)){ 152 if($conf['debug']){ 153 dbglog($in,'no such ditaa input file'); 154 } 155 return false; 156 } 157 158 $cmd = $this->getConf('java'); 159 $cmd .= ' -Djava.awt.headless=true -Dfile.encoding=UTF-8 -jar'; 160 $cmd .= ' '.escapeshellarg(dirname(__FILE__).'/ditaa/ditaa0_9.jar'); //ditaa jar 161 $cmd .= ' --encoding UTF-8'; 162 $cmd .= ' '.escapeshellarg($in); //input 163 $cmd .= ' '.escapeshellarg($out); //output 164 $cmd .= ' -s '.escapeshellarg($data['scale']); 165 if(!$data['antialias']) $cmd .= ' -A'; 166 if(!$data['shadow']) $cmd .= ' -S'; 167 if($data['round']) $cmd .= ' -r'; 168 if(!$data['edgesep']) $cmd .= ' -E'; 169 170 exec($cmd, $output, $error); 171 172 if ($error != 0){ 173 if($conf['debug']){ 174 dbglog(join("\n",$output),'ditaa command failed: '.$cmd); 175 } 176 return false; 177 } 178 179 return true; 180 } 181 182} 183 184