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