xref: /plugin/ditaa/syntax.php (revision 3c74ed326053f4f9eec8c46a77015da4f21b9093)
1<?php
2/**
3 * Ditaa-Plugin: Converts Ascii-Flowcharts into a png-File
4 *
5 * @license     GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author      Dennis Ploeger <develop [at] dieploegers [dot] de>
7 * @author      Christoph Mertins <c [dot] mertins [at] gmail [dot] com>
8 * @author      Andreas Gohr <andi@splitbrain.org>
9 */
10
11if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
13require_once(DOKU_PLUGIN.'syntax.php');
14
15class syntax_plugin_ditaa 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 200;
36    }
37
38
39    /**
40     * Connect pattern to lexer
41     */
42
43    function connectTo($mode) {
44        $this->Lexer->addSpecialPattern('<ditaa.*?>\n.*?\n</ditaa>',$mode,'plugin_ditaa');
45    }
46
47
48
49    /**
50     * Handle the match
51     */
52    function handle($match, $state, $pos, &$handler) {
53        $info = $this->getInfo();
54
55        // prepare default data
56        $return = array(
57                        'data'      => '',
58                        'width'     => 0,
59                        'height'    => 0,
60                        'antialias' => true,
61                        'edgesep'   => true,
62                        'round'     => false,
63                        'shadow'    => true,
64                        'scale'     => 1,
65                        'align'     => '',
66                        'version'   => $info['date'], //forece rebuild of images on update
67                       );
68
69
70        // prepare input
71        $lines = explode("\n",$match);
72        $conf = array_shift($lines);
73        array_pop($lines);
74
75        // match config options
76        if(preg_match('/\b(left|center|right)\b/i',$conf,$match)) $return['align'] = $match[1];
77        if(preg_match('/\b(\d+)x(\d+)\b/',$conf,$match)){
78            $return['width']  = $match[1];
79            $return['height'] = $match[2];
80        }
81        if(preg_match('/\b(\d+(\.\d+)?)X\b/',$conf,$match)) $return['scale']  = $match[1];
82        if(preg_match('/\bwidth=([0-9]+)\b/i', $conf,$match)) $return['width'] = $match[1];
83        if(preg_match('/\bheight=([0-9]+)\b/i', $conf,$match)) $return['height'] = $match[1];
84        // match boolean toggles
85        if(preg_match_all('/\b(no)?(antialias|edgesep|round|shadow)\b/i',$conf,$matches,PREG_SET_ORDER)){
86            foreach($matches as $match){
87                $return[$match[2]] = ! $match[1];
88            }
89        }
90
91        $return['data'] = join("\n",$lines);
92
93        return $return;
94    }
95
96    /**
97     * Create output
98     */
99    function render($format, &$R, $data) {
100        if($format != 'xhtml') return;
101
102        if($this->getConf('java')){
103            // run ditaa on our own server
104            $img = DOKU_BASE.'lib/plugins/ditaa/ditaa.php?'.buildURLparams($data,'&');
105        }else{
106            // use ditaa.org for rendering
107            $pass = array(
108                'grid'  => $data['data'],
109                'scale' => $data['scale']
110            );
111            if(!$data['antialias']) $pass['A'] = 'on';
112            if(!$data['shadow'])    $pass['S'] = 'on';
113            if($data['round'])      $pass['r'] = 'on';
114            if(!$data['edgesep'])   $pass['E'] = 'on';
115            $pass['timeout'] = 25;
116
117            $img = 'http://ditaa.org/ditaa/render?'.buildURLparams($pass,'&');
118            $img = ml($img,array('w'=>$data['width'],'h'=>$data['height']));
119        }
120
121        $R->doc .= '<img src="'.$img.'" class="media'.$data['align'].'" alt=""';
122        if($data['width'])  $R->doc .= ' width="'.$data['width'].'"';
123        if($data['height']) $R->doc .= ' height="'.$data['height'].'"';
124        if($data['align'] == 'right') $ret .= ' align="right"';
125        if($data['align'] == 'left')  $ret .= ' align="left"';
126        $R->doc .= '/>';
127    }
128
129
130    /**
131     * Run the ditaa Java program
132     */
133    function _run($data,$cache) {
134        global $conf;
135
136        $temp = tempnam($conf['tmpdir'],'ditaa_');
137        io_saveFile($temp,$data['data']);
138
139        $cmd  = $this->getConf('java');
140        $cmd .= ' -Djava.awt.headless=true -jar';
141        $cmd .= ' '.escapeshellarg(dirname(__FILE__).'/ditaa/ditaa0_9.jar'); //ditaa jar
142        $cmd .= ' '.escapeshellarg($temp); //input
143        $cmd .= ' '.escapeshellarg($cache); //output
144        $cmd .= ' -s '.escapeshellarg($data['scale']);
145        if(!$data['antialias']) $cmd .= ' -A';
146        if(!$data['shadow'])    $cmd .= ' -S';
147        if($data['round'])      $cmd .= ' -r';
148        if(!$data['edgesep'])   $cmd .= ' -E';
149
150        exec($cmd, $output, $error);
151        @unlink($temp);
152
153        if ($error != 0){
154            if($conf['debug']){
155                dbglog(join("\n",$output),'ditaa command failed: '.$cmd);
156            }
157            return false;
158        }
159        return true;
160    }
161
162}
163
164
165
166