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> 7517bd836SAndreas 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 17517bd836SAndreas Gohr /** 18517bd836SAndreas Gohr * What about paragraphs? 19517bd836SAndreas Gohr */ 20517bd836SAndreas Gohr function getPType(){ 21517bd836SAndreas Gohr return 'normal'; 22903f28d7SAndreas Gohr } 23903f28d7SAndreas Gohr 24903f28d7SAndreas Gohr /** 25903f28d7SAndreas Gohr * What kind of syntax are we? 26903f28d7SAndreas Gohr */ 27903f28d7SAndreas Gohr function getType(){ 28517bd836SAndreas 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) { 42517bd836SAndreas Gohr $this->Lexer->addSpecialPattern('<graphviz.*?>\n.*?\n</graphviz>',$mode,'plugin_graphviz'); 43903f28d7SAndreas Gohr } 44903f28d7SAndreas Gohr 45903f28d7SAndreas Gohr /** 46903f28d7SAndreas Gohr * Handle the match 47903f28d7SAndreas Gohr */ 48517bd836SAndreas Gohr function handle($match, $state, $pos, &$handler) { 49517bd836SAndreas Gohr $info = $this->getInfo(); 50903f28d7SAndreas Gohr 51*67682e69SAndreas Gohr // prepare default data 52517bd836SAndreas Gohr $return = array( 53517bd836SAndreas Gohr 'data' => '', 54517bd836SAndreas Gohr 'width' => 0, 55517bd836SAndreas Gohr 'height' => 0, 56517bd836SAndreas Gohr 'layout' => 'dot', 57517bd836SAndreas Gohr 'align' => '', 58517bd836SAndreas Gohr 'version' => $info['date'], //force rebuild of images on update 59517bd836SAndreas Gohr ); 60903f28d7SAndreas Gohr 61517bd836SAndreas Gohr // prepare input 62517bd836SAndreas Gohr $lines = explode("\n",$match); 63517bd836SAndreas Gohr $conf = array_shift($lines); 64517bd836SAndreas Gohr array_pop($lines); 65517bd836SAndreas Gohr 66517bd836SAndreas Gohr // match config options 67517bd836SAndreas Gohr if(preg_match('/\b(left|center|right)\b/i',$conf,$match)) $return['align'] = $match[1]; 68517bd836SAndreas Gohr if(preg_match('/\b(\d+)x(\d+)\b/',$conf,$match)){ 69517bd836SAndreas Gohr $return['width'] = $match[1]; 70517bd836SAndreas Gohr $return['height'] = $match[2]; 71903f28d7SAndreas Gohr } 72517bd836SAndreas Gohr if(preg_match('/\b(dot|neato|twopi|circo|fdp)\b/i',$conf,$match)){ 73517bd836SAndreas Gohr $return['layout'] = strtolower($match[1]); 74903f28d7SAndreas Gohr } 75517bd836SAndreas Gohr if(preg_match('/\bwidth=([0-9]+)\b/i', $conf,$match)) $return['width'] = $match[1]; 76517bd836SAndreas Gohr if(preg_match('/\bheight=([0-9]+)\b/i', $conf,$match)) $return['height'] = $match[1]; 77517bd836SAndreas Gohr 78517bd836SAndreas Gohr $return['data'] = join("\n",$lines); 79517bd836SAndreas Gohr 80517bd836SAndreas Gohr return $return; 81517bd836SAndreas Gohr } 82517bd836SAndreas Gohr 83903f28d7SAndreas Gohr /** 84903f28d7SAndreas Gohr * Create output 85*67682e69SAndreas Gohr * 86*67682e69SAndreas Gohr * @todo latex and ODT support 87903f28d7SAndreas Gohr */ 88517bd836SAndreas Gohr function render($format, &$R, $data) { 89517bd836SAndreas Gohr if($format != 'xhtml') return; 90517bd836SAndreas Gohr 91*67682e69SAndreas Gohr $img = $this->_imgurl($data); 92517bd836SAndreas Gohr $R->doc .= '<img src="'.$img.'" class="media'.$data['align'].'" alt=""'; 93517bd836SAndreas Gohr if($data['width']) $R->doc .= ' width="'.$data['width'].'"'; 94517bd836SAndreas Gohr if($data['height']) $R->doc .= ' height="'.$data['height'].'"'; 95517bd836SAndreas Gohr if($data['align'] == 'right') $ret .= ' align="right"'; 96517bd836SAndreas Gohr if($data['align'] == 'left') $ret .= ' align="left"'; 97517bd836SAndreas Gohr $R->doc .= '/>'; 98517bd836SAndreas Gohr } 99517bd836SAndreas Gohr 100*67682e69SAndreas Gohr /** 101*67682e69SAndreas Gohr * Build the image URL using either our own generator or 102*67682e69SAndreas Gohr * the Google Chart API 103*67682e69SAndreas Gohr */ 104*67682e69SAndreas Gohr function _imgurl($data){ 105*67682e69SAndreas Gohr if($this->getConf('path')){ 106*67682e69SAndreas Gohr // run graphviz on our own server 107*67682e69SAndreas Gohr $img = DOKU_BASE.'lib/plugins/graphviz/img.php?'.buildURLparams($data,'&'); 108*67682e69SAndreas Gohr }else{ 109*67682e69SAndreas Gohr // go through google 110*67682e69SAndreas Gohr $pass = array( 111*67682e69SAndreas Gohr 'cht' => 'gv:'.$data['layout'], 112*67682e69SAndreas Gohr 'chl' => $data['data'], 113*67682e69SAndreas Gohr ); 114*67682e69SAndreas Gohr if($data['width'] && $data['height']){ 115*67682e69SAndreas Gohr $pass['chs'] = $data['width'].'x'.$data['height']; 116*67682e69SAndreas Gohr } 117*67682e69SAndreas Gohr 118*67682e69SAndreas Gohr $img = 'http://chart.apis.google.com/chart?'.buildURLparams($pass,'&'); 119*67682e69SAndreas Gohr $img = ml($img,array('w'=>$data['width'],'h'=>$data['height'])); 120*67682e69SAndreas Gohr } 121*67682e69SAndreas Gohr return $img; 122*67682e69SAndreas Gohr } 123517bd836SAndreas Gohr 124517bd836SAndreas Gohr /** 125517bd836SAndreas Gohr * Run the graphviz program 126517bd836SAndreas Gohr */ 127517bd836SAndreas Gohr function _run($data,$cache) { 128903f28d7SAndreas Gohr global $conf; 129903f28d7SAndreas Gohr 130517bd836SAndreas Gohr $temp = tempnam($conf['tmpdir'],'graphviz_'); 131517bd836SAndreas Gohr io_saveFile($temp,$data['data']); 132903f28d7SAndreas Gohr 133517bd836SAndreas Gohr $cmd = $this->getConf('path'); 134517bd836SAndreas Gohr $cmd .= ' -Tpng'; 135517bd836SAndreas Gohr $cmd .= ' -K'.$data['layout']; 136517bd836SAndreas Gohr $cmd .= ' -o'.escapeshellarg($cache); //output 137517bd836SAndreas Gohr $cmd .= ' '.escapeshellarg($temp); //input 138903f28d7SAndreas Gohr 139517bd836SAndreas Gohr exec($cmd, $output, $error); 140517bd836SAndreas Gohr @unlink($temp); 141903f28d7SAndreas Gohr 142517bd836SAndreas Gohr if ($error != 0){ 143517bd836SAndreas Gohr if($conf['debug']){ 144517bd836SAndreas Gohr dbglog(join("\n",$output),'graphviz command failed: '.$cmd); 145903f28d7SAndreas Gohr } 146903f28d7SAndreas Gohr return false; 147903f28d7SAndreas Gohr } 148517bd836SAndreas Gohr return true; 149903f28d7SAndreas Gohr } 150903f28d7SAndreas Gohr 151903f28d7SAndreas Gohr} 152903f28d7SAndreas Gohr 153517bd836SAndreas Gohr 154517bd836SAndreas Gohr 155