1<?php 2/** 3 * seqdia-Plugin: Parses seqdia-blocks 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Carl-Christian Salvesen <calle@ioslo.net> 7 * @author Andreas Gohr <andi@splitbrain.org> 8 * @author Ruslan Popov <ruslan.popov@gmail.com> 9 * @author Willi Schönborn <w.schoenborn@googlemail.com> 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_seqdia extends DokuWiki_Syntax_Plugin { 17 18 /** 19 * What about paragraphs? 20 */ 21 function getPType(){ 22 return 'normal'; 23 } 24 25 /** 26 * What kind of syntax are we? 27 */ 28 function getType(){ 29 return 'substition'; 30 } 31 32 /** 33 * Where to sort in? 34 */ 35 function getSort(){ 36 return 200; 37 } 38 39 /** 40 * Connect pattern to lexer 41 */ 42 function connectTo($mode) { 43 $this->Lexer->addSpecialPattern('<seqdia.*?>\n.*?\n</seqdia>',$mode,'plugin_seqdia'); 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 'data' => '', 55 'width' => 0, 56 'height' => 0, 57 'style' => 'default', 58 'align' => '', 59 'version' => $info['date'], //force rebuild of images on update 60 ); 61 62 // prepare input 63 $lines = explode("\n",$match); 64 $conf = array_shift($lines); 65 array_pop($lines); 66 67 // match config options 68 if(preg_match('/\b(left|center|right)\b/i',$conf,$match)) $return['align'] = $match[1]; 69 if(preg_match('/\b(\d+)x(\d+)\b/',$conf,$match)){ 70 $return['width'] = $match[1]; 71 $return['height'] = $match[2]; 72 } 73 if(preg_match('/\b(default|rose|qsd|napkin|vs2010|mscgen|omegapple|modern-blue|earth|roundgreen)\b/i',$conf,$match)){ 74 $return['style'] = strtolower($match[1]); 75 } 76 if(preg_match('/\bwidth=([0-9]+)\b/i', $conf,$match)) $return['width'] = $match[1]; 77 if(preg_match('/\bheight=([0-9]+)\b/i', $conf,$match)) $return['height'] = $match[1]; 78 79 $input = join("\n",$lines); 80 $return['md5'] = md5($input); // we only pass a hash around 81 82 // store input for later use 83 io_saveFile($this->_cachename($return,'txt'),$input); 84 85 return $return; 86 } 87 88 /** 89 * Cache file is based on parameters that influence the result image 90 */ 91 function _cachename($data,$ext){ 92 unset($data['width']); 93 unset($data['height']); 94 unset($data['align']); 95 return getcachename(join('x',array_values($data)),'.seqdia.'.$ext); 96 } 97 98 /** 99 * Create output 100 */ 101 function render($format, &$R, $data) { 102 if($format == 'xhtml'){ 103 $img = DOKU_BASE.'lib/plugins/seqdia/img.php?'.buildURLparams($data); 104 $R->doc .= '<img src="'.$img.'" class="media'.$data['align'].'" alt=""'; 105 if($data['width']) $R->doc .= ' width="'.$data['width'].'"'; 106 if($data['height']) $R->doc .= ' height="'.$data['height'].'"'; 107 if($data['align'] == 'right') $R->doc .= ' align="right"'; 108 if($data['align'] == 'left') $R->doc .= ' align="left"'; 109 $R->doc .= '/>'; 110 return true; 111 }elseif($format == 'odt'){ 112 $src = $this->_imgfile($data); 113 $R->_odtAddImage($src,$data['width'],$data['height'],$data['align']); 114 return true; 115 } 116 return false; 117 } 118 119 /** 120 * Return path to the rendered image on our local system 121 */ 122 function _imgfile($data){ 123 $cache = $this->_cachename($data,'png'); 124 125 // create the file if needed 126 if(!file_exists($cache)){ 127 $in = $this->_cachename($data,'txt'); 128 $ok = $this->_remote($data,$in,$cache); 129 if(!$ok) return false; 130 clearstatcache(); 131 } 132 133 // resized version 134 if($data['width']){ 135 $cache = media_resize_image($cache,'png',$data['width'],$data['height']); 136 } 137 138 // something went wrong, we're missing the file 139 if(!file_exists($cache)) return false; 140 141 return $cache; 142 } 143 144 /** 145 * Render the output remotely at ditaa.org 146 */ 147 function _remote($data,$in,$out){ 148 if(!file_exists($in)){ 149 if($conf['debug']){ 150 dbglog($in,'no such seqdia input file'); 151 } 152 return false; 153 } 154 155 $http = new DokuHTTPClient(); 156 $http->timeout=30; 157 158 $pass = array(); 159 $pass['style'] = $data['style']; 160 $pass['message'] = io_readFile($in); 161 162 $result = $http->post('http://www.websequencediagrams.com/index.php',$pass); 163 if(!$result) return false; 164 165 $json = new JSON(JSON_LOOSE_TYPE); 166 $json->skipnative = true; 167 $json_data = $json->decode($result); 168 169 $img = $http->get('http://www.websequencediagrams.com/index.php'.$json_data['img']); 170 if(!$img) return false; 171 172 return io_saveFile($out,$img); 173 } 174 175} 176