1<?php
2/**
3 * Add Note capability to dokuwiki
4 *
5 * <note>This is note</note>
6 * <note classic>This is note</note>
7 * <note important>This is an important note</note>
8 * <note warning>This is a big warning</note>
9 * <note tip>This is a tip</note>
10 *
11 * by Olivier Cortès <olive@deep-ocean.net>
12 * under the terms of the GNU GPL v2.
13 *
14 * Originaly derived from the work of :
15 * Stephane Chamberland <stephane.chamberland@ec.gc.ca> (Side Notes PlugIn)
16 * Carl-Christian Salvesen <calle@ioslo.net> (Graphviz plugin)
17 *
18 * Contributions by Eric Hameleers <alien [at] slackware [dot] com> :
19 *   use <div> instead of <table>,
20 *   contain the images and stylesheet inside the plugin,
21 *   permit nesting of notes,
22 *
23 * Contributed by Christopher Smith <chris [at] jalakai [dot] co [dot] uk>
24 *   fix some parsing problems and a security hole.
25 *   make note types case independent
26 *   simplify code reading
27 *   modernise the plugin for changes/fixes/improvements to the underlying Dokuwiki plugin class,
28 *   improve efficiency.
29 *
30 * Contributed by Aurélien Bompard <aurelien [at] bompard [dot] org>
31 *   support for the ODT output format.
32 *
33 * @license    GNU_GPL_v2
34 * @author     Olivier Cortes <olive@deep-ocean.net>
35 */
36
37if (!defined('DOKU_INC')) {
38    define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
39}
40if (!defined('DOKU_PLUGIN')) {
41    define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
42}
43require_once DOKU_PLUGIN.'syntax.php';
44
45
46class syntax_plugin_note extends DokuWiki_Syntax_Plugin {
47
48    var $notes = array(
49        'noteimportant' => array('important', 'importante'),
50        'notewarning'   => array('warning','bloquante','critique'),
51        'notetip'       => array('tip','tuyau','idée'),
52        'noteclassic'   => array('','classic','classique')
53      );
54
55    var $default = 'plugin_note noteclassic';
56
57    function getType(){ return 'container'; }
58    function getPType(){ return 'block'; }
59    function getAllowedTypes() {
60        return array('container','substition','protected','disabled','formatting','paragraphs');
61    }
62
63    function getSort(){ return 195; }
64
65    // override default accepts() method to allow nesting
66    // - ie, to get the plugin accepts its own entry syntax
67    function accepts($mode) {
68        if ($mode == substr(get_class($this), 7)) {
69            return true;
70        }
71        return parent::accepts($mode);
72    }
73
74    function connectTo($mode) {
75        $this->Lexer->addEntryPattern('<note.*?>(?=.*?</note>)',$mode,'plugin_note');
76    }
77
78    function postConnect() {
79        $this->Lexer->addExitPattern('</note>','plugin_note');
80    }
81
82    function handle($match, $state, $pos, Doku_Handler $handler) {
83        switch ($state) {
84            case DOKU_LEXER_ENTER:
85                $note = strtolower(trim(substr($match,5,-1)));
86
87                foreach( $this->notes as $class => $names ) {
88                    if (in_array($note, $names))
89                        return array($state, $class);
90                }
91                return array($state, $this->default);
92
93            case DOKU_LEXER_UNMATCHED:
94                return array($state, $match);
95
96            default:
97                return array($state);
98        }
99    }
100
101    function render($mode, Doku_Renderer $renderer, $indata) {
102        if($mode == 'xhtml'){
103            list($state, $data) = $indata;
104
105            switch ($state) {
106                case DOKU_LEXER_ENTER :
107                    $renderer->doc .= '<div class="plugin_note '.$data.'">';
108                break;
109
110                case DOKU_LEXER_UNMATCHED :
111                    $renderer->doc .= $renderer->_xmlEntities($data);
112                break;
113
114                case DOKU_LEXER_EXIT :
115                    $renderer->doc .= "\n</div>";
116                break;
117            }
118            return true;
119        } elseif ($mode == 'odt'){
120            list($state, $data) = $indata;
121
122            $this->render_odt ($renderer, $state, $data);
123            return true;
124        }
125
126        // unsupported $mode
127        return false;
128    }
129
130    protected function render_odt ($renderer, $state, $data) {
131        static $first = true;
132        static $new;
133
134        if ($first == true) {
135            $new = method_exists ($renderer, 'getODTPropertiesFromElement');
136            $first = false;
137        }
138
139        if (!$new) {
140            // Render with older ODT plugin version.
141            $this->render_odt_old ($renderer, $state, $data);
142        } else {
143            // Render with newer ODT plugin version.
144            $this->render_odt_new ($renderer, $state, $data);
145        }
146    }
147
148    protected function render_odt_old ($renderer, $state, $data) {
149        switch ($state) {
150            case DOKU_LEXER_ENTER:
151                $type = substr($data, 4);
152                if ($type == 'classic') {
153                    // The icon for classic notes is named note.png
154                    $type = 'note';
155                }
156                $colors = array('note' => '#eeeeff', 'warning' => '#ffdddd', 'important' => '#ffffcc', 'tip' => '#ddffdd');
157
158                // Content
159                $properties = array();
160                $properties ['width'] = '100%';
161                $properties ['align'] = 'center';
162                $properties ['shadow'] = '#808080 0.18cm 0.18cm';
163                $renderer->_odtTableOpenUseProperties($properties);
164
165                $properties = array();
166                $properties ['width'] = '1.5cm';
167                $renderer->_odtTableAddColumnUseProperties($properties);
168
169                $properties = array();
170                $properties ['width'] = '13.5cm';
171                $renderer->_odtTableAddColumnUseProperties($properties);
172
173                $renderer->tablerow_open();
174
175                $properties = array();
176                $properties ['vertical-align'] = 'middle';
177                $properties ['text-align'] = 'center';
178                $properties ['padding'] = '0.1cm';
179                $properties ['border'] = '0.002cm solid #000000';
180                $properties ['background-color'] = $colors[$type];
181                $renderer->_odtTableCellOpenUseProperties($properties);
182
183                $src = DOKU_PLUGIN.'note/images/'.$type.'.png';
184                $renderer->_odtAddImage($src);
185
186                $renderer->tablecell_close();
187
188                $properties = array();
189                $properties ['vertical-align'] = 'middle';
190                $properties ['padding'] = '0.3cm';
191                $properties ['border'] = '0.002cm solid #000000';
192                $properties ['background-color'] = $colors[$type];
193                $renderer->_odtTableCellOpenUseProperties($properties);
194            break;
195
196            case DOKU_LEXER_UNMATCHED :
197                $renderer->cdata($data);
198            break;
199
200            case DOKU_LEXER_EXIT :
201                $renderer->tablecell_close();
202                $renderer->tablerow_close();
203                $renderer->_odtTableClose();
204                $renderer->p_open();
205            break;
206        }
207    }
208
209    /**
210     * ODT rendering for new versions of the ODT plugin.
211     *
212     * @param $renderer the renderer to use
213     * @param $state    the current state
214     * @param $data     data from handle()
215     * @author LarsDW223
216     */
217    protected function render_odt_new ($renderer, $state, $data) {
218        switch ($state) {
219            case DOKU_LEXER_ENTER:
220                $css_properties = array ();
221
222                // Get CSS properties for ODT export.
223                $renderer->getODTPropertiesNew ($css_properties, 'div', 'class="'.$data.'"', NULL, true);
224
225                // Create Content
226                // (We only use the CSS parameters that are meaningful for creating the ODT table)
227                $properties = array();
228                $properties ['width'] = '100%';
229                $properties ['align'] = 'center';
230                $properties ['shadow'] = '#808080 0.18cm 0.18cm';
231                $renderer->_odtTableOpenUseProperties($properties);
232
233                $properties = array();
234                $properties ['width'] = '1.5cm';
235                $renderer->_odtTableAddColumnUseProperties($properties);
236
237                $properties = array();
238                $properties ['width'] = '13.5cm';
239                $renderer->_odtTableAddColumnUseProperties($properties);
240
241                $renderer->tablerow_open();
242
243                $properties = array();
244                $properties ['vertical-align'] = $css_properties ['vertical-align'];
245                $properties ['text-align'] = 'center';
246                $properties ['padding'] = '0.1cm';
247                $properties ['border'] = '0.002cm solid #000000';
248                $properties ['background-color'] = $css_properties ['background-color'];
249                $renderer->_odtTableCellOpenUseProperties($properties);
250
251                if ($css_properties ['background-image']) {
252                    $renderer->_odtAddImage($css_properties ['background-image']);
253                }
254
255                $renderer->tablecell_close();
256
257                $properties = array();
258                $properties ['vertical-align'] = $css_properties ['vertical-align'];
259                $properties ['text-align'] = $css_properties ['text-align'];
260                $properties ['padding'] = '0.3cm';
261                $properties ['border'] = '0.002cm solid #000000';
262                $properties ['background-color'] = $css_properties ['background-color'];
263                $renderer->_odtTableCellOpenUseProperties($properties);
264            break;
265
266            case DOKU_LEXER_UNMATCHED :
267                $renderer->cdata($data);
268            break;
269
270            case DOKU_LEXER_EXIT :
271                $renderer->tablecell_close();
272                $renderer->tablerow_close();
273                $renderer->_odtTableClose();
274                $renderer->p_open();
275            break;
276        }
277    }
278}
279
280//Setup VIM: ex: et ts=4 enc=utf-8 :
281