xref: /plugin/ditaa/syntax.php (revision d402f512c4c6c58746219ee98fb5fc6701f7d5a0)
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 (Beginning of parsing)
57     */
58
59    function connectTo($mode) {
60        $this->Lexer->addEntryPattern('<ditaa.*?>(?=.*?\x3C/ditaa\x3E)', $mode, 'plugin_ditaa');
61    }
62
63    function postConnect() {
64        $this->Lexer->addExitPattern('</ditaa>', 'plugin_ditaa');
65    }
66
67
68    /**
69     * Handle the match
70     */
71    function handle($match, $state, $pos, &$handler)
72    {
73
74        switch ($state) {
75            case DOKU_LEXER_ENTER:
76                    preg_match('/width=([0-9]+)/i', substr($match,6,-1), $match_width);
77                    preg_match('/height=([0-9]+)/i', substr($match,6,-1), $match_height);
78                    preg_match('/name=([a-zA-Z_0-9]+)/i', substr($match,6,-1), $match_name);
79                    return array('begin', $match_name[1], $match_width[1], $match_height[1]);
80                    break;
81            case DOKU_LEXER_EXIT:
82                    return array('end');
83                    break;
84            case DOKU_LEXER_UNMATCHED:
85                    return array('data', $match);
86                    break;
87
88        }
89    }
90
91    /**
92     * Create output
93     */
94    function render($format, &$renderer, $data)
95    {
96
97        global $conf;
98
99        if ($data[0] == 'begin') {
100
101            list($state, $name, $width, $height) = $data;
102
103        } else if ($data[0] == 'data') {
104
105            list($state, $mydata) = $data;
106
107        } else {
108
109            $state = $data[0];
110
111        }
112
113        switch($state) {
114
115            case 'begin': return $this->_ditaa_begin($renderer, $name, $width, $height);
116            case 'data' : return $this->_ditaa_data($mydata);
117            case 'end'  : return $this->_ditaa_end($renderer);
118
119        }
120
121    }
122
123    /**
124     * Store values for later ditaa-rendering
125     *
126     * @param object    $renderer The dokuwiki-renderer
127     * @param string    $name   The name for the ditaa-object
128     * @param width     $width  The width for the ditaa-object
129     * @param height    $height The height for the ditaa-object
130     * @return  bool            All parameters are set
131     */
132
133    function _ditaa_begin(&$renderer, $name, $width, $height)
134    {
135        // Check, if name is given
136
137        $name = trim(strtolower($name));
138
139        if ($name == '') {
140
141            $renderer->doc .= '---NO NAME FOR FLOWCHART GIVEN---';
142            return true;
143
144        }
145
146        $width = trim($width);
147        $height = trim($height);
148
149        if (($width != '') && (settype($width, 'int'))) {
150
151            $this->ditaa_width = $width;
152
153        }
154
155        if (($height != '') && (settype($height, 'int'))) {
156
157            $this->ditaa_height = $height;
158
159        }
160
161        $this->ditaa_name = $name;
162
163        $this->ditaa_data = '';
164
165        return true;
166
167    }
168
169    /**
170     * Expand the data for the ditaa-object
171     *
172     * @param   string  $data   The data for the ditaa-object
173     * @return  bool            If everything was right
174     */
175
176    function _ditaa_data($data)
177    {
178
179        $this->ditaa_data .= $data;
180
181        return true;
182
183    }
184
185    /**
186     * Render the ditaa-object
187     *
188     * @param object    $renderer   The dokuwiki-Renderer
189     * @return  bool                If everything was right
190     */
191
192    function _ditaa_end(&$renderer)
193    {
194        global $conf, $INFO;
195
196        // Write a text file for ditaa
197
198        $tempfile = tempnam($this->tempdir, 'ditaa_');
199
200        $file = fopen($tempfile.'.txt', 'w');
201        fwrite($file, $this->ditaa_data);
202        fclose($file);
203
204        $md5 = md5_file($tempfile.'.txt');
205
206        $mediadir = $conf["mediadir"]."/".str_replace(":", "/",$INFO['namespace'] );
207
208        if (!is_dir($mediadir)) {
209            umask(002);
210            mkdir($mediadir,0777);
211        }
212
213        $imagefile = $mediadir.'/ditaa_'.$this->ditaa_name.'_'.$md5.'.png';
214
215        if ( !file_exists($imagefile)) {
216
217            $cmd = $this->pathToJava." -Djava.awt.headless=true -jar ".$this->pathToDitaa." ".$tempfile.".txt ".$tempfile.".png";
218
219            exec($cmd, $output, $error);
220
221            if ($error != 0) {
222                $renderer->doc .= '---ERROR CONVERTING DIAGRAM---';
223                   return false;
224            }
225
226            if (file_exists($imagefile)) {
227                unlink($imagefile);
228            }
229
230            if ( !copy($tempfile.'.png', $imagefile) ) {
231                return false;
232            }
233
234            // Remove input file
235            unlink($tempfile.'.png');
236            unlink($tempfile);
237        }
238
239        unlink($tempfile.'.txt');
240
241        // Output Img-Tag
242
243        $width = NULL;
244
245        if ($this->ditaa_width != -1) {
246            $width = $this->ditaa_width;
247        }
248
249        $height = NULL;
250
251        if ($this->ditaa_height != -1) {
252            $height = $this->ditaa_height;
253        }
254
255        $renderer->doc .= $renderer->internalmedia($INFO['namespace'].':ditaa_'.$this->ditaa_name.'_'.$md5.'.png', $this->ditaa_name, NULL, $width, $height, false);
256
257        return true;
258
259    }
260
261}
262
263
264
265
266?>
267