1<?php 2/** 3 * graphviz-Plugin: Parses graphviz-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 */ 9 10if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 11require_once(DOKU_INC.'inc/init.php'); 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 13require_once(DOKU_PLUGIN.'syntax.php'); 14 15class syntax_plugin_graphviz 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 100; 36 } 37 38 /** 39 * Connect pattern to lexer 40 */ 41 function connectTo($mode) { 42 $this->Lexer->addSpecialPattern('<graphviz.*?>\n.*?\n</graphviz>',$mode,'plugin_graphviz'); 43 } 44 45 /** 46 * Handle the match 47 */ 48 function handle($match, $state, $pos, &$handler) { 49 $info = $this->getInfo(); 50 51 // prepare default data FIXME 52 $return = array( 53 'data' => '', 54 'width' => 0, 55 'height' => 0, 56 'layout' => 'dot', 57# 'antialias' => true, 58# 'edgesep' => true, 59# 'round' => false, 60# 'shadow' => true, 61# 'scale' => 1, 62 'align' => '', 63 'version' => $info['date'], //force rebuild of images on update 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(dot|neato|twopi|circo|fdp)\b/i',$conf,$match)){ 78 $return['layout'] = strtolower($match[1]); 79 } 80 if(preg_match('/\b(\d+(\.\d+)?)X\b/',$conf,$match)) $return['scale'] = $match[1]; 81 if(preg_match('/\bwidth=([0-9]+)\b/i', $conf,$match)) $return['width'] = $match[1]; 82 if(preg_match('/\bheight=([0-9]+)\b/i', $conf,$match)) $return['height'] = $match[1]; 83 // match boolean toggles 84 if(preg_match_all('/\b(no)?(antialias|edgesep|round|shadow)\b/i',$conf,$matches,PREG_SET_ORDER)){ 85 foreach($matches as $match){ 86 $return[$match[2]] = ! $match[1]; 87 } 88 } 89 90 $return['data'] = join("\n",$lines); 91 92 return $return; 93 } 94 95 /** 96 * Create output 97 */ 98 function render($format, &$R, $data) { 99 if($format != 'xhtml') return; 100 101 if($this->getConf('path')){ 102 // run graphviz on our own server 103 $img = DOKU_BASE.'lib/plugins/graphviz/img.php?'.buildURLparams($data,'&'); 104 }else{ 105 106#FIXME 107 // use ditaa.org for rendering 108 $pass = array( 109 'grid' => $data['data'], 110 'scale' => $data['scale'] 111 ); 112 if(!$data['antialias']) $pass['A'] = 'on'; 113 if(!$data['shadow']) $pass['S'] = 'on'; 114 if($data['round']) $pass['r'] = 'on'; 115 if(!$data['edgesep']) $pass['E'] = 'on'; 116 $pass['timeout'] = 25; 117 118 $img = 'http://ditaa.org/ditaa/render?'.buildURLparams($pass,'&'); 119 $img = ml($img,array('w'=>$data['width'],'h'=>$data['height'])); 120 } 121 122 $R->doc .= '<img src="'.$img.'" class="media'.$data['align'].'" alt=""'; 123 if($data['width']) $R->doc .= ' width="'.$data['width'].'"'; 124 if($data['height']) $R->doc .= ' height="'.$data['height'].'"'; 125 if($data['align'] == 'right') $ret .= ' align="right"'; 126 if($data['align'] == 'left') $ret .= ' align="left"'; 127 $R->doc .= '/>'; 128 } 129 130 131 /** 132 * Run the graphviz program 133 */ 134 function _run($data,$cache) { 135 global $conf; 136 137 $temp = tempnam($conf['tmpdir'],'graphviz_'); 138 io_saveFile($temp,$data['data']); 139 140 $cmd = $this->getConf('path'); 141 $cmd .= ' -Tpng'; 142 $cmd .= ' -K'.$data['layout']; 143 $cmd .= ' -o'.escapeshellarg($cache); //output 144 $cmd .= ' '.escapeshellarg($temp); //input 145 146 exec($cmd, $output, $error); 147 @unlink($temp); 148 149 if ($error != 0){ 150 if($conf['debug']){ 151 dbglog(join("\n",$output),'graphviz command failed: '.$cmd); 152 } 153 return false; 154 } 155 return true; 156 } 157 158} 159 160 161 162