xref: /plugin/ditaa/syntax.php (revision 72a2bf1d595eb32a998cbccddaca46cfb6e8cec0)
1<?php
2
3/**
4 * Ditaa-Plugin: Converts Ascii-Flowcharts into a png-File
5 *
6 * @license     GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author      Dennis Ploeger <develop [at] dieploegers [dot] de>
8 * @author      Christoph Mertins <c [dot] mertins [at] gmail [dot] com>
9 * @author      Andreas Gohr <andi@splitbrain.org>
10 */
11
12if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
14require_once(DOKU_PLUGIN.'syntax.php');
15
16class syntax_plugin_ditaa extends DokuWiki_Syntax_Plugin {
17
18    var $ditaa_name = '';
19
20    var $ditaa_width = -1;
21
22    var $ditaa_height = -1;
23
24    var $ditaa_data = '';
25
26    var $pathToJava = "/opt/blackdown-jdk-1.4.2.02/bin/java";
27
28    var $pathToDitaa = "/var/www/sst.intern.editable/dokuwiki/htdocs/ditaa.jar";
29
30    var $tempdir = "/tmp";
31
32
33    /**
34     * What about paragraphs?
35     */
36    function getPType(){
37        return 'normal';
38    }
39
40    /**
41     * What kind of syntax are we?
42     */
43    function getType(){
44        return 'substition';
45    }
46
47    /**
48     * Where to sort in?
49     */
50    function getSort(){
51        return 200;
52    }
53
54
55    /**
56     * Connect pattern to lexer
57     */
58
59    function connectTo($mode) {
60        $this->Lexer->addSpecialPattern('<ditaa.*?>\n.*?\n</ditaa>',$mode,'plugin_ditaa');
61    }
62
63
64
65    /**
66     * Handle the match
67     */
68    function handle($match, $state, $pos, &$handler) {
69        // prepare default data
70        $return = array(
71                        'data'      => '',
72                        'width'     => 0,
73                        'height'    => 0,
74                        'antialias' => true,
75                        'edgesep'   => true,
76                        'round'     => false,
77                        'shadow'    => true,
78                        'scale'     => 1,
79                        'align'     => '',
80                       );
81
82
83        // prepare input
84        $lines = explode("\n",$match);
85        $conf = array_shift($lines);
86        array_pop($lines);
87
88        // match config options
89        if(preg_match('/\b(left|center|right)\b/i',$conf,$match)) $return['align'] = $match[1];
90        if(preg_match('/\b(\d+)x(\d+)\b/',$conf,$match)){
91            $return['width']  = $match[1];
92            $return['height'] = $match[2];
93        }
94        if(preg_match('/\b(\d+)X\b/',$conf,$match)) $return['scale']  = $match[1];
95        if(preg_match('/\bwidth=([0-9]+)\b/i', $conf,$match)) $return['width'] = $match[1];
96        if(preg_match('/\bheight=([0-9]+)\b/i', $conf,$match)) $return['height'] = $match[1];
97        // match boolean toggles
98        if(preg_match_all('/\b(no)?(antialias|edgesep|round|shadow)\b/i',$conf,$matches,PREG_SET_ORDER)){
99            foreach($matches as $match){
100                $return[$match[2]] = ! $match[1];
101            }
102        }
103
104        $return['data'] = join("\n",$lines);
105
106        return $return;
107    }
108
109    /**
110     * Create output
111     */
112    function render($format, &$R, $data) {
113        if($format != 'xhtml') return;
114
115        // prepare data for ditaa.org
116        $pass = array(
117            'grid'  => $data['data'],
118            'scale' => $data['scale']
119        );
120        if(!$data['antialias']) $pass['A'] = 'on';
121        if(!$data['shadow'])    $pass['S'] = 'on';
122        if($data['round'])      $pass['r'] = 'on';
123        if(!$data['edgesep'])   $pass['E'] = 'on';
124        $pass['timeout'] = 25;
125
126        $img = 'http://ditaa.org/ditaa/render?'.buildURLparams($pass,'&');
127        $img = ml($img,array('w'=>$data['width'],'h'=>$data['height']));
128
129        $R->doc .= '<img src="'.$img.'" alt="x">';
130
131    }
132
133    /**
134     * Store values for later ditaa-rendering
135     *
136     * @param object    $renderer The dokuwiki-renderer
137     * @param string    $name   The name for the ditaa-object
138     * @param width     $width  The width for the ditaa-object
139     * @param height    $height The height for the ditaa-object
140     * @return  bool            All parameters are set
141     */
142
143    function _ditaa_begin(&$renderer, $name, $width, $height)
144    {
145        // Check, if name is given
146
147        $name = trim(strtolower($name));
148
149        if ($name == '') {
150
151            $renderer->doc .= '---NO NAME FOR FLOWCHART GIVEN---';
152            return true;
153
154        }
155
156        $width = trim($width);
157        $height = trim($height);
158
159        if (($width != '') && (settype($width, 'int'))) {
160
161            $this->ditaa_width = $width;
162
163        }
164
165        if (($height != '') && (settype($height, 'int'))) {
166
167            $this->ditaa_height = $height;
168
169        }
170
171        $this->ditaa_name = $name;
172
173        $this->ditaa_data = '';
174
175        return true;
176
177    }
178
179    /**
180     * Expand the data for the ditaa-object
181     *
182     * @param   string  $data   The data for the ditaa-object
183     * @return  bool            If everything was right
184     */
185
186    function _ditaa_data($data)
187    {
188
189        $this->ditaa_data .= $data;
190
191        return true;
192
193    }
194
195    /**
196     * Render the ditaa-object
197     *
198     * @param object    $renderer   The dokuwiki-Renderer
199     * @return  bool                If everything was right
200     */
201
202    function _ditaa_end(&$renderer)
203    {
204        global $conf, $INFO;
205
206        // Write a text file for ditaa
207
208        $tempfile = tempnam($this->tempdir, 'ditaa_');
209
210        $file = fopen($tempfile.'.txt', 'w');
211        fwrite($file, $this->ditaa_data);
212        fclose($file);
213
214        $md5 = md5_file($tempfile.'.txt');
215
216        $mediadir = $conf["mediadir"]."/".str_replace(":", "/",$INFO['namespace'] );
217
218        if (!is_dir($mediadir)) {
219            umask(002);
220            mkdir($mediadir,0777);
221        }
222
223        $imagefile = $mediadir.'/ditaa_'.$this->ditaa_name.'_'.$md5.'.png';
224
225        if ( !file_exists($imagefile)) {
226
227            $cmd = $this->pathToJava." -Djava.awt.headless=true -jar ".$this->pathToDitaa." ".$tempfile.".txt ".$tempfile.".png";
228
229            exec($cmd, $output, $error);
230
231            if ($error != 0) {
232                $renderer->doc .= '---ERROR CONVERTING DIAGRAM---';
233                   return false;
234            }
235
236            if (file_exists($imagefile)) {
237                unlink($imagefile);
238            }
239
240            if ( !copy($tempfile.'.png', $imagefile) ) {
241                return false;
242            }
243
244            // Remove input file
245            unlink($tempfile.'.png');
246            unlink($tempfile);
247        }
248
249        unlink($tempfile.'.txt');
250
251        // Output Img-Tag
252
253        $width = NULL;
254
255        if ($this->ditaa_width != -1) {
256            $width = $this->ditaa_width;
257        }
258
259        $height = NULL;
260
261        if ($this->ditaa_height != -1) {
262            $height = $this->ditaa_height;
263        }
264
265        $renderer->doc .= $renderer->internalmedia($INFO['namespace'].':ditaa_'.$this->ditaa_name.'_'.$md5.'.png', $this->ditaa_name, NULL, $width, $height, false);
266
267        return true;
268
269    }
270
271}
272
273
274
275