xref: /plugin/ditaa/syntax.php (revision a34ed36b21c978430acb3f03a02c84b8eec019bc)
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 */
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    var $ditaa_name = '';
18
19    var $ditaa_width = -1;
20
21    var $ditaa_height = -1;
22
23    var $ditaa_data = '';
24
25    var $pathToJava = "/opt/blackdown-jdk-1.4.2.02/bin/java";
26
27    var $pathToDitaa = "/var/www/sst.intern.editable/dokuwiki/htdocs/ditaa.jar";
28
29    var $tempdir = "/tmp";
30
31    /**
32     * return some info
33     */
34    function getInfo(){
35        return array(
36            'author' => 'Dennis Ploeger',
37            'email'  => 'develop@dieploegers.de',
38            'date'   => '2009-05-19',
39            'name'   => 'Ditaa-Plugin',
40            'desc'   => 'Renders ascii-flowcharts contained in a dokuwiki-page to a png, that is displayed instead',
41            'url'    => 'http://wiki.splitbrain.org/plugin:ditaa',
42        );
43    }
44
45    /**
46     * What about paragraphs?
47     */
48    function getPType(){
49        return 'normal';
50    }
51
52    /**
53     * What kind of syntax are we?
54     */
55    function getType(){
56        return 'substition';
57    }
58
59    /**
60     * Where to sort in?
61     */
62    function getSort(){
63        return 200;
64    }
65
66
67    /**
68     * Connect pattern to lexer (Beginning of parsing)
69     */
70
71    function connectTo($mode) {
72        $this->Lexer->addEntryPattern('<ditaa.*?>(?=.*?\x3C/ditaa\x3E)', $mode, 'plugin_ditaa');
73    }
74
75    function postConnect() {
76        $this->Lexer->addExitPattern('</ditaa>', 'plugin_ditaa');
77    }
78
79
80    /**
81     * Handle the match
82     */
83    function handle($match, $state, $pos, &$handler)
84    {
85
86        switch ($state) {
87            case DOKU_LEXER_ENTER:
88                    preg_match('/width=([0-9]+)/i', substr($match,6,-1), $match_width);
89                    preg_match('/height=([0-9]+)/i', substr($match,6,-1), $match_height);
90                    preg_match('/name=([a-zA-Z_0-9]+)/i', substr($match,6,-1), $match_name);
91                    return array('begin', $match_name[1], $match_width[1], $match_height[1]);
92                    break;
93            case DOKU_LEXER_EXIT:
94                    return array('end');
95                    break;
96            case DOKU_LEXER_UNMATCHED:
97                    return array('data', $match);
98                    break;
99
100        }
101    }
102
103    /**
104     * Create output
105     */
106    function render($format, &$renderer, $data)
107    {
108
109        global $conf;
110
111        if ($data[0] == 'begin') {
112
113            list($state, $name, $width, $height) = $data;
114
115        } else if ($data[0] == 'data') {
116
117            list($state, $mydata) = $data;
118
119        } else {
120
121            $state = $data[0];
122
123        }
124
125        switch($state) {
126
127            case 'begin': return $this->_ditaa_begin($renderer, $name, $width, $height);
128            case 'data' : return $this->_ditaa_data($mydata);
129            case 'end'  : return $this->_ditaa_end($renderer);
130
131        }
132
133    }
134
135    /**
136     * Store values for later ditaa-rendering
137     *
138     * @param object    $renderer The dokuwiki-renderer
139     * @param string    $name   The name for the ditaa-object
140     * @param width     $width  The width for the ditaa-object
141     * @param height    $height The height for the ditaa-object
142     * @return  bool            All parameters are set
143     */
144
145    function _ditaa_begin(&$renderer, $name, $width, $height)
146    {
147        // Check, if name is given
148
149        $name = trim(strtolower($name));
150
151        if ($name == '') {
152
153            $renderer->doc .= '---NO NAME FOR FLOWCHART GIVEN---';
154            return true;
155
156        }
157
158        $width = trim($width);
159        $height = trim($height);
160
161        if (($width != '') && (settype($width, 'int'))) {
162
163            $this->ditaa_width = $width;
164
165        }
166
167        if (($height != '') && (settype($height, 'int'))) {
168
169            $this->ditaa_height = $height;
170
171        }
172
173        $this->ditaa_name = $name;
174
175        $this->ditaa_data = '';
176
177        return true;
178
179    }
180
181    /**
182     * Expand the data for the ditaa-object
183     *
184     * @param   string  $data   The data for the ditaa-object
185     * @return  bool            If everything was right
186     */
187
188    function _ditaa_data($data)
189    {
190
191        $this->ditaa_data .= $data;
192
193        return true;
194
195    }
196
197    /**
198     * Render the ditaa-object
199     *
200     * @param object    $renderer   The dokuwiki-Renderer
201     * @return  bool                If everything was right
202     */
203
204    function _ditaa_end(&$renderer)
205    {
206        global $conf, $INFO;
207
208        // Write a text file for ditaa
209
210        $tempfile = tempnam($this->tempdir, 'ditaa_');
211
212        $file = fopen($tempfile.'.txt', 'w');
213        fwrite($file, $this->ditaa_data);
214        fclose($file);
215
216        $md5 = md5_file($tempfile.'.txt');
217
218        $mediadir = $conf["mediadir"]."/".str_replace(":", "/",$INFO['namespace'] );
219
220        if (!is_dir($mediadir)) {
221            umask(002);
222            mkdir($mediadir,0777);
223        }
224
225        $imagefile = $mediadir.'/ditaa_'.$this->ditaa_name.'_'.$md5.'.png';
226
227        if ( !file_exists($imagefile)) {
228
229            $cmd = $this->pathToJava." -Djava.awt.headless=true -jar ".$this->pathToDitaa." ".$tempfile.".txt ".$tempfile.".png";
230
231            exec($cmd, $output, $error);
232
233            if ($error != 0) {
234                $renderer->doc .= '---ERROR CONVERTING DIAGRAM---';
235                   return false;
236            }
237
238            if (file_exists($imagefile)) {
239                unlink($imagefile);
240            }
241
242            if ( !copy($tempfile.'.png', $imagefile) ) {
243                return false;
244            }
245
246            // Remove input file
247            unlink($tempfile.'.png');
248            unlink($tempfile);
249        }
250
251        unlink($tempfile.'.txt');
252
253        // Output Img-Tag
254
255        $width = NULL;
256
257        if ($this->ditaa_width != -1) {
258            $width = $this->ditaa_width;
259        }
260
261        $height = NULL;
262
263        if ($this->ditaa_height != -1) {
264            $height = $this->ditaa_height;
265        }
266
267        $renderer->doc .= $renderer->internalmedia($INFO['namespace'].':ditaa_'.$this->ditaa_name.'_'.$md5.'.png', $this->ditaa_name, NULL, $width, $height, false);
268
269        return true;
270
271    }
272
273}
274
275
276
277
278?>
279