xref: /plugin/graphviz/syntax.php (revision 517bd8367891ed3eeda89c7608688f50ccdd0d7a)
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