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