source: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/plugins/imagereference/syntax.php@ 25027

Last change on this file since 25027 was 25027, checked in by jmt12, 12 years ago

Adding the packages directory, and within it a configured version of dokuwiki all ready to run

  • Property svn:executable set to *
File size: 14.7 KB
Line 
1<?php
2/**
3 * Plugin imagereference
4 *
5 * Syntax: <imgref linkname> - creates a figure link to an image
6 * <imgcaption linkname <orientation> | Image caption> Image/Table</imgcaption>
7 *
8 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
9 * @author Martin Heinemann <[email protected]>
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
16/**
17 * All DokuWiki plugins to extend the parser/rendering mechanism
18 * need to inherit from this class
19 */
20class syntax_plugin_imagereference extends DokuWiki_Syntax_Plugin {
21
22
23 var $_figure_name_array = array("");
24 var $_figure_map = array();
25 var $_captions = array();
26
27
28 /**
29 * Get an associative array with plugin info.
30 *
31 * <p>
32 * The returned array holds the following fields:
33 * <dl>
34 * <dt>author</dt><dd>Author of the plugin</dd>
35 * <dt>email</dt><dd>Email address to contact the author</dd>
36 * <dt>date</dt><dd>Last modified date of the plugin in
37 * <tt>YYYY-MM-DD</tt> format</dd>
38 * <dt>name</dt><dd>Name of the plugin</dd>
39 * <dt>desc</dt><dd>Short description of the plugin (Text only)</dd>
40 * <dt>url</dt><dd>Website with more information on the plugin
41 * (eg. syntax description)</dd>
42 * </dl>
43 * @param none
44 * @return Array Information about this plugin class.
45 * @public
46 * @static
47 */
48 function getInfo(){
49 return array(
50 'author' => 'Martin Heinemann',
51 'email' => '[email protected]',
52 'date' => '2008-05-30',
53 'name' => 'imagereference',
54 'desc' => 'Create image references like latex is doing with figures',
55 'url' => 'http://wiki.splitbrain.org/wiki:plugins',
56 );
57 }
58
59
60 function getType(){ return 'protected';}
61 function getAllowedTypes() { return array('container','substition','protected','disabled','formatting','paragraphs'); }
62 function getPType(){ return 'normal';}
63
64 // must return a number lower than returned by native 'code' mode (200)
65 function getSort(){ return 196; }
66
67 // override default accepts() method to allow nesting
68 // - ie, to get the plugin accepts its own entry syntax
69 function accepts($mode) {
70 if ($mode == substr(get_class($this), 7)) return true;
71
72 return parent::accepts($mode);
73 }
74
75 /**
76 * Connect lookup pattern to lexer.
77 *
78 * @param $aMode String The desired rendermode.
79 * @return none
80 * @public
81 * @see render()
82 */
83 function connectTo($mode) {
84
85 $this->Lexer->addSpecialPattern('<imgref\s[^\r\n]*?>',$mode, 'plugin_imagereference');
86 $this->Lexer->addSpecialPattern('<tblref\s[^\r\n]*?>',$mode, 'plugin_imagereference');
87
88 $this->Lexer->addEntryPattern('<imgcaption\s[^\|]+\|[^>]+(?=>.*?</imgcaption>)',$mode,'plugin_imagereference');
89 $this->Lexer->addEntryPattern('<tblcaption\s[^\|]+\|[^>]+(?=>.*?</tblcaption>)',$mode,'plugin_imagereference');
90 }
91
92 function postConnect() {
93 $this->Lexer->addExitPattern('</imgcaption>', 'plugin_imagereference');
94 $this->Lexer->addExitPattern('</tblcaption>', 'plugin_imagereference');
95 }
96
97
98 /**
99 * Handler to prepare matched data for the rendering process.
100 *
101 * <p>
102 * The <tt>$aState</tt> parameter gives the type of pattern
103 * which triggered the call to this method:
104 * </p>
105 * <dl>
106 * <dt>DOKU_LEXER_ENTER</dt>
107 * <dd>a pattern set by <tt>addEntryPattern()</tt></dd>
108 * <dt>DOKU_LEXER_MATCHED</dt>
109 * <dd>a pattern set by <tt>addPattern()</tt></dd>
110 * <dt>DOKU_LEXER_EXIT</dt>
111 * <dd> a pattern set by <tt>addExitPattern()</tt></dd>
112 * <dt>DOKU_LEXER_SPECIAL</dt>
113 * <dd>a pattern set by <tt>addSpecialPattern()</tt></dd>
114 * <dt>DOKU_LEXER_UNMATCHED</dt>
115 * <dd>ordinary text encountered within the plugin's syntax mode
116 * which doesn't match any pattern.</dd>
117 * </dl>
118 * @param $aMatch String The text matched by the patterns.
119 * @param $aState Integer The lexer state for the match.
120 * @param $aPos Integer The character position of the matched text.
121 * @param $aHandler Object Reference to the Doku_Handler object.
122 * @return Integer The current lexer state for the match.
123 * @public
124 * @see render()
125 * @static
126 */
127 function handle($match, $state, $pos, &$handler){
128 switch ($state) {
129 // =========================================================
130 case DOKU_LEXER_ENTER : {
131
132 /* --------------------------------------------------- */
133 $refLabel = ''; //trim(substr($match, 11, -1));
134 $caption = '';
135 if (preg_match('/<(?:img|tbl)caption\s+([^\|]+)\|([^>]+)/', $match, $matches))
136 {
137 $refLabel = $matches[1];
138 $caption = $matches[2];
139 }
140 // -----------------------------------------------------
141 $parsedInput = $this->_parseParam($refLabel);
142
143 // ------------------------------------------------------
144 //$data = $this->_imgstart($parsedInput);
145 // store the figure name from imgcaption
146 array_push($this->_figure_name_array, $parsedInput[0]);
147
148 $this->_figure_map[$parsedInput[0]] = '';
149
150 $this->_captions[$parsedInput[0]] = $caption;
151
152 ///cho '<p>refLabel:' . $refLabel . '</p>';
153 ///cho '<p>parsedInput:' . print_r($parsedInput, true) . '</p>';
154 ///cho '<p>figure_name_array: ' . print_r($this->_figure_name_array, true) . '</p>';
155 ///cho '<p>figure_map: ' . print_r($this->_figure_map, true) . '</p>';
156 ///cho '<p>captions: ' . print_r($this->_captions, true). '</p>';
157
158 return array('caption_open', $parsedInput); // image anchor label
159 /* --------------------------------------------------- */
160 //}
161 }
162 // =========================================================
163 case DOKU_LEXER_UNMATCHED : {
164 /* --------------------------------------------------- */
165 $parsed = $this->_parseContent($match);
166 $this->_figure_map[end($this->_figure_name_array)] = $this->_imgend($parsed[0]);
167
168 return array('data', '');
169 /* --------------------------------------------------- */
170 }
171
172 // =========================================================
173 case DOKU_LEXER_EXIT :
174 /* --------------------------------------------------- */
175 return array('caption_close', $this->_figure_map[end($this->_figure_name_array)]);
176 /* --------------------------------------------------- */
177 // =========================================================
178 case DOKU_LEXER_MATCHED :
179 /* --------------------------------------------------- */
180 return array('data', "----".$match."------");
181 /* --------------------------------------------------- */
182 // =========================================================
183 case DOKU_LEXER_SPECIAL : {
184 /* --------------------------------------------------- */
185 $ref = substr($match, 8, -1);
186 return array('imgref', $ref);
187 /* --------------------------------------------------- */
188 }
189 }
190
191 return array();
192 }
193
194 /**
195 * Handle the actual output creation.
196 *
197 * <p>
198 * The method checks for the given <tt>$aFormat</tt> and returns
199 * <tt>FALSE</tt> when a format isn't supported. <tt>$aRenderer</tt>
200 * contains a reference to the renderer object which is currently
201 * handling the rendering. The contents of <tt>$aData</tt> is the
202 * return value of the <tt>handle()</tt> method.
203 * </p>
204 * @param $aFormat String The output format to generate.
205 * @param $aRenderer Object A reference to the renderer object.
206 * @param $aData Array The data created by the <tt>handle()</tt>
207 * method.
208 * @return Boolean <tt>TRUE</tt> if rendered successfully, or
209 * <tt>FALSE</tt> otherwise.
210 * @public
211 * @see handle()
212 */
213 function render($mode, &$renderer, $indata) {
214 list($case, $data) = $indata;
215 if($mode == 'xhtml'){
216 // ---------------------------------------------
217 switch ($case) {
218 case 'imgref' : {
219 /* --------------------------------------- */
220 $refNumber = array_search($data, $this->_figure_name_array);
221 if ($refNumber == null || $refNumber == '')
222 {
223 $refNumber = '##';
224 }
225 if (strpos($data,'#') === false)
226 {
227 $data = "#" . $data;
228 }
229 $str = "<a class=\"wikilink1\" href=\"".$data."\">".$this->getLang('figure'). ' ' . $refNumber."</a>";
230 $renderer->doc .= $str; break;
231// $renderer->_xmlEntities($str);break;
232 /* --------------------------------------- */
233 }
234 case 'caption_open' : $renderer->doc .= $this->_imgstart($data); break;
235 case 'caption_close' : {
236 // -------------------------------------------------------
237 list($name, $number, $caption) = $data;
238 // - retrieve the caption separately
239 $caption = $this->_captions[$name];
240 // - special case for 'hidden' tables
241 $layout = '';
242 if ($caption != '##HIDDEN##')
243 {
244 // - manual do any formatting (as leaving it to the
245 // parser (to foobar) is why we had to do this in
246 // the first place
247 $caption = preg_replace('/\/\/%%(.+?)%%\/\//','<i>\1</i>',$caption);
248 $caption = preg_replace('/\/\/(.+?)\/\//','<i>\1</i>',$caption);
249 $caption = preg_replace('/\*\*(.+?)\*\*/','<b>\1</b>',$caption);
250 $caption = str_replace('%!--', '<!--', $caption);
251 $caption = str_replace('--%', '-->', $caption);
252 // - special case: nested image ref (we can't really resolve these)
253 $caption = preg_replace('/<imgref\s+([^>]+)><\/imgref>/','\1',$caption);
254 $layout = "<div class=\"undercaption\">".$this->getLang('fig').$number.": <a name=\"".$name."\"></a>".$caption."</div>";
255 }
256 $layout .= "</div>";
257 $renderer->doc .= $layout; break;
258 }
259 // -------------------------------------------------------
260 // data is mostly empty!!!
261 case 'data' : $renderer->doc .= $data; break;
262 }
263
264 return true;
265 }
266 if($mode == 'latex') {
267 // -----------------------------------------
268 switch ($case) {
269 case 'imgref' : {
270 /* --------------------------------------- */
271 $renderer->doc .= "\\ref{".$data."}"; break;
272 /* --------------------------------------- */
273 }
274 case 'caption_open' : {
275 // --------------------------------------
276 $orientation = "\\centering";
277 switch($data[1]) {
278 case 'left' : $orientation = "\\left";break;
279 case 'right' : $orientation = "\\right";break;
280 }
281 $renderer->doc .= "\\begin{figure}[H!]{".$orientation; break;
282 // --------------------------------------
283 }
284 case 'caption_close' : {
285 // -------------------------------------------------------
286 list($name, $number, $caption) = $data;
287 $layout = "\\caption{".$caption."}\\label{".$name."}\\end{figure}";
288 $renderer->doc .= $layout; break;
289 }
290
291 case 'data' : $renderer->doc .= trim($data); break;
292 }
293
294 return true;
295 // -----------------------------------------
296 }
297
298
299 return false;
300 }
301
302
303
304 function _parseParam($str) {
305 if (!strlen($str)) return array();
306
307 $styles = array();
308
309 // get the img ref name. Its the first word
310 $parsed = explode(" ", $str, 2);
311 $imgref = $parsed[0];
312
313
314 $tokens = preg_split('/\s+/', $parsed[1], 9); // limit is defensive
315 foreach ($tokens as $token) {
316 // restrict token (class names) characters to prevent any malicious data
317 if (preg_match('/[^A-Za-z0-9_-]/',$token)) continue;
318 $styles['class'] = (isset($styles['class']) ? $styles['class'].' ' : '').$token;
319 }
320 // return imageref name , style
321 // e.G. image1,left
322 return array($imgref, $styles['class']);
323 }
324
325
326 function _imgstart($str) {
327 // ============================================ //
328 if (empty($str)) return '';
329
330 $layout = "<div class=\"imgcaption";
331 //$layout = "<div><div class=\"imgcaption";
332 if ($str[1] != "")
333 $layout = $layout.$str[1];
334 $layout = $layout."\">";
335
336 return $layout;
337 // ============================================ //
338 }
339
340
341 /**
342 *
343 *
344 * @param String $str the image caption
345 * @return array(imagename, image number, image caption)
346 */
347 function _imgend($str) {
348 // [jmt12] I think this function is unused!
349
350 // ===================================================== //
351 $figureName = end($this->_figure_name_array);
352 // get the position of the figure in the array
353 $refNumber = array_search($figureName, $this->_figure_name_array);
354
355 return array($figureName, $refNumber, $str);
356
357
358 $layout = "<div class=\"undercaption\">".$this->getLang('fig').$refNumber.":
359 <a name=\"".end($this->_figure_name_array)."\"></a>".$str."</div>";
360
361 //$layout = "<div id=\"undercaption\">Fig. ".$refNumber.":
362 //<a name=\"".end($this->_figure_name_array)."\">".$str."</a></div></div></div>";
363
364 return $layout;
365 // =====================================================
366 }
367 /**
368 * divides the image caption and the content between the tags
369 *
370 */
371
372 function _parseContent($str) {
373 // ======================================================
374 if (!strlen($str)) return "";
375 // parse for '>'
376 $parsed = explode(">", $str, 2);
377
378 return $parsed;
379 // ======================================================
380 }
381
382
383}
384
385//Setup VIM: ex: et ts=4 enc=utf-8 :
386?>
Note: See TracBrowser for help on using the repository browser.