1903f28d7SAndreas Gohr<?php 2903f28d7SAndreas Gohr/** 3903f28d7SAndreas Gohr * graphviz-Plugin: Parses graphviz-blocks 4903f28d7SAndreas Gohr * 5903f28d7SAndreas Gohr * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6903f28d7SAndreas Gohr * @author Carl-Christian Salvesen <calle@ioslo.net> 7*517bd836SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 8903f28d7SAndreas Gohr */ 9903f28d7SAndreas Gohr 10903f28d7SAndreas Gohrif(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 11903f28d7SAndreas Gohrrequire_once(DOKU_INC.'inc/init.php'); 12903f28d7SAndreas Gohrif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 13903f28d7SAndreas Gohrrequire_once(DOKU_PLUGIN.'syntax.php'); 14903f28d7SAndreas Gohr 15903f28d7SAndreas Gohrclass syntax_plugin_graphviz extends DokuWiki_Syntax_Plugin { 16903f28d7SAndreas Gohr 17*517bd836SAndreas Gohr /** 18*517bd836SAndreas Gohr * What about paragraphs? 19*517bd836SAndreas Gohr */ 20*517bd836SAndreas Gohr function getPType(){ 21*517bd836SAndreas Gohr return 'normal'; 22903f28d7SAndreas Gohr } 23903f28d7SAndreas Gohr 24903f28d7SAndreas Gohr /** 25903f28d7SAndreas Gohr * What kind of syntax are we? 26903f28d7SAndreas Gohr */ 27903f28d7SAndreas Gohr function getType(){ 28*517bd836SAndreas Gohr return 'substition'; 29903f28d7SAndreas Gohr } 30903f28d7SAndreas Gohr 31903f28d7SAndreas Gohr /** 32903f28d7SAndreas Gohr * Where to sort in? 33903f28d7SAndreas Gohr */ 34903f28d7SAndreas Gohr function getSort(){ 35903f28d7SAndreas Gohr return 100; 36903f28d7SAndreas Gohr } 37903f28d7SAndreas Gohr 38903f28d7SAndreas Gohr /** 39903f28d7SAndreas Gohr * Connect pattern to lexer 40903f28d7SAndreas Gohr */ 41903f28d7SAndreas Gohr function connectTo($mode) { 42*517bd836SAndreas Gohr $this->Lexer->addSpecialPattern('<graphviz.*?>\n.*?\n</graphviz>',$mode,'plugin_graphviz'); 43903f28d7SAndreas Gohr } 44903f28d7SAndreas Gohr 45903f28d7SAndreas Gohr /** 46903f28d7SAndreas Gohr * Handle the match 47903f28d7SAndreas Gohr */ 48*517bd836SAndreas Gohr function handle($match, $state, $pos, &$handler) { 49*517bd836SAndreas Gohr $info = $this->getInfo(); 50903f28d7SAndreas Gohr 51*517bd836SAndreas Gohr // prepare default data FIXME 52*517bd836SAndreas Gohr $return = array( 53*517bd836SAndreas Gohr 'data' => '', 54*517bd836SAndreas Gohr 'width' => 0, 55*517bd836SAndreas Gohr 'height' => 0, 56*517bd836SAndreas Gohr 'layout' => 'dot', 57*517bd836SAndreas Gohr# 'antialias' => true, 58*517bd836SAndreas Gohr# 'edgesep' => true, 59*517bd836SAndreas Gohr# 'round' => false, 60*517bd836SAndreas Gohr# 'shadow' => true, 61*517bd836SAndreas Gohr# 'scale' => 1, 62*517bd836SAndreas Gohr 'align' => '', 63*517bd836SAndreas Gohr 'version' => $info['date'], //force rebuild of images on update 64*517bd836SAndreas Gohr ); 65903f28d7SAndreas Gohr 66*517bd836SAndreas Gohr // prepare input 67*517bd836SAndreas Gohr $lines = explode("\n",$match); 68*517bd836SAndreas Gohr $conf = array_shift($lines); 69*517bd836SAndreas Gohr array_pop($lines); 70*517bd836SAndreas Gohr 71*517bd836SAndreas Gohr // match config options 72*517bd836SAndreas Gohr if(preg_match('/\b(left|center|right)\b/i',$conf,$match)) $return['align'] = $match[1]; 73*517bd836SAndreas Gohr if(preg_match('/\b(\d+)x(\d+)\b/',$conf,$match)){ 74*517bd836SAndreas Gohr $return['width'] = $match[1]; 75*517bd836SAndreas Gohr $return['height'] = $match[2]; 76903f28d7SAndreas Gohr } 77*517bd836SAndreas Gohr if(preg_match('/\b(dot|neato|twopi|circo|fdp)\b/i',$conf,$match)){ 78*517bd836SAndreas Gohr $return['layout'] = strtolower($match[1]); 79903f28d7SAndreas Gohr } 80*517bd836SAndreas Gohr if(preg_match('/\b(\d+(\.\d+)?)X\b/',$conf,$match)) $return['scale'] = $match[1]; 81*517bd836SAndreas Gohr if(preg_match('/\bwidth=([0-9]+)\b/i', $conf,$match)) $return['width'] = $match[1]; 82*517bd836SAndreas Gohr if(preg_match('/\bheight=([0-9]+)\b/i', $conf,$match)) $return['height'] = $match[1]; 83*517bd836SAndreas Gohr // match boolean toggles 84*517bd836SAndreas Gohr if(preg_match_all('/\b(no)?(antialias|edgesep|round|shadow)\b/i',$conf,$matches,PREG_SET_ORDER)){ 85*517bd836SAndreas Gohr foreach($matches as $match){ 86*517bd836SAndreas Gohr $return[$match[2]] = ! $match[1]; 87903f28d7SAndreas Gohr } 88*517bd836SAndreas Gohr } 89*517bd836SAndreas Gohr 90*517bd836SAndreas Gohr $return['data'] = join("\n",$lines); 91*517bd836SAndreas Gohr 92*517bd836SAndreas Gohr return $return; 93*517bd836SAndreas Gohr } 94*517bd836SAndreas Gohr 95903f28d7SAndreas Gohr /** 96903f28d7SAndreas Gohr * Create output 97903f28d7SAndreas Gohr */ 98*517bd836SAndreas Gohr function render($format, &$R, $data) { 99*517bd836SAndreas Gohr if($format != 'xhtml') return; 100*517bd836SAndreas Gohr 101*517bd836SAndreas Gohr if($this->getConf('path')){ 102*517bd836SAndreas Gohr // run graphviz on our own server 103*517bd836SAndreas Gohr $img = DOKU_BASE.'lib/plugins/graphviz/img.php?'.buildURLparams($data,'&'); 104*517bd836SAndreas Gohr }else{ 105*517bd836SAndreas Gohr 106*517bd836SAndreas Gohr#FIXME 107*517bd836SAndreas Gohr // use ditaa.org for rendering 108*517bd836SAndreas Gohr $pass = array( 109*517bd836SAndreas Gohr 'grid' => $data['data'], 110*517bd836SAndreas Gohr 'scale' => $data['scale'] 111*517bd836SAndreas Gohr ); 112*517bd836SAndreas Gohr if(!$data['antialias']) $pass['A'] = 'on'; 113*517bd836SAndreas Gohr if(!$data['shadow']) $pass['S'] = 'on'; 114*517bd836SAndreas Gohr if($data['round']) $pass['r'] = 'on'; 115*517bd836SAndreas Gohr if(!$data['edgesep']) $pass['E'] = 'on'; 116*517bd836SAndreas Gohr $pass['timeout'] = 25; 117*517bd836SAndreas Gohr 118*517bd836SAndreas Gohr $img = 'http://ditaa.org/ditaa/render?'.buildURLparams($pass,'&'); 119*517bd836SAndreas Gohr $img = ml($img,array('w'=>$data['width'],'h'=>$data['height'])); 120*517bd836SAndreas Gohr } 121*517bd836SAndreas Gohr 122*517bd836SAndreas Gohr $R->doc .= '<img src="'.$img.'" class="media'.$data['align'].'" alt=""'; 123*517bd836SAndreas Gohr if($data['width']) $R->doc .= ' width="'.$data['width'].'"'; 124*517bd836SAndreas Gohr if($data['height']) $R->doc .= ' height="'.$data['height'].'"'; 125*517bd836SAndreas Gohr if($data['align'] == 'right') $ret .= ' align="right"'; 126*517bd836SAndreas Gohr if($data['align'] == 'left') $ret .= ' align="left"'; 127*517bd836SAndreas Gohr $R->doc .= '/>'; 128*517bd836SAndreas Gohr } 129*517bd836SAndreas Gohr 130*517bd836SAndreas Gohr 131*517bd836SAndreas Gohr /** 132*517bd836SAndreas Gohr * Run the graphviz program 133*517bd836SAndreas Gohr */ 134*517bd836SAndreas Gohr function _run($data,$cache) { 135903f28d7SAndreas Gohr global $conf; 136903f28d7SAndreas Gohr 137*517bd836SAndreas Gohr $temp = tempnam($conf['tmpdir'],'graphviz_'); 138*517bd836SAndreas Gohr io_saveFile($temp,$data['data']); 139903f28d7SAndreas Gohr 140*517bd836SAndreas Gohr $cmd = $this->getConf('path'); 141*517bd836SAndreas Gohr $cmd .= ' -Tpng'; 142*517bd836SAndreas Gohr $cmd .= ' -K'.$data['layout']; 143*517bd836SAndreas Gohr $cmd .= ' -o'.escapeshellarg($cache); //output 144*517bd836SAndreas Gohr $cmd .= ' '.escapeshellarg($temp); //input 145903f28d7SAndreas Gohr 146*517bd836SAndreas Gohr exec($cmd, $output, $error); 147*517bd836SAndreas Gohr @unlink($temp); 148903f28d7SAndreas Gohr 149*517bd836SAndreas Gohr if ($error != 0){ 150*517bd836SAndreas Gohr if($conf['debug']){ 151*517bd836SAndreas Gohr dbglog(join("\n",$output),'graphviz command failed: '.$cmd); 152903f28d7SAndreas Gohr } 153903f28d7SAndreas Gohr return false; 154903f28d7SAndreas Gohr } 155*517bd836SAndreas Gohr return true; 156903f28d7SAndreas Gohr } 157903f28d7SAndreas Gohr 158903f28d7SAndreas Gohr} 159903f28d7SAndreas Gohr 160*517bd836SAndreas Gohr 161*517bd836SAndreas Gohr 162