====== imagereference plugin ====== ---- plugin ---- description: Creates references to images/tables in your text, like the LaTeX figure references. author : Martin Heinemann, Christian Moll email : info@martinheinemann.net type : syntax lastupdate : 2009-01-07 compatible : depends : conflicts : similar : imagebox tags : media, images, references, caption, links downloadurl: http://santec.tudor.lu/_media/team/heinemann/plugin-imagereference.tar.gz ---- This syntax plugin enables the creation of image captions in MediaWiki style and additionally create in-text references to these images. I created this plugin because we are using DokuWiki for software user manuals and we were missing the caption and image reference from LaTeX to refer to figures in your text. ^Download|{{http://santec.tudor.lu/_media/team/heinemann/plugin-imagereference.tar.gz?id=team%3Aheinemann%3Adownloads|tar.gz}} (6.9KB)|2009-01-07| ^Download|{{http://santec.tudor.lu/_media/team/heinemann/plugin-imagereference.zip?id=team%3Aheinemann%3Adownloads|zip}} (9.0KB)|2009-01-07| =====Acknowledgment===== Thanks a lot to the box plugin by Christopher Smith ===== Versions ===== ⇒ **2008/09/11** Czech localisation added. Thanks to Jiri Vejda. Small bugfix in JavaScript. The toolbar buttons are now visible.\\ ⇒ **2008/09/11** localisations for English, french and German added. Toolbar buttons for creating the caption and references.\\ ⇒ **2008/08/13** included a small JavaScript which sets the right width of the box according to the image size. Also little modifications in style and syntax! ===== Syntax ===== An image caption {{:my_image.png}} You can refer to the '''' 'objects' by using '''image1''' is the internal name of the imagecaption object. They are filtered and counted and the '''''' tag will create a link to this image: Fig. 1 You can set the orientation of an imgcaption: {{:wiki:my_image.png}} {{:wiki:my_image.png}} The default orientation is center. ===== Screenshot ===== {{http://santec.tudor.lu/_media/team/heinemann/imgref_plugin.png?w=&h=&cache=cache}} ===== Known Problems ===== There are some problems with the numbering of the figures. It will generate the numbers for the imgref tags once and keep them in the cache. If you make some changes on the page, the imgref tags will be replaced with "Figure # #" until the cache is rebuild. I put the cache lifetime to 10 minutes. ==== syntax.php ==== This is the current code. Have fun. - creates a figure link to an image * | Image caption> Image/Table * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Martin Heinemann */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_imagereference extends DokuWiki_Syntax_Plugin { var $_figure_name_array = array(""); var $_figure_map = array(); /** * Get an associative array with plugin info. * *

* The returned array holds the following fields: *

*
author
Author of the plugin
*
email
Email address to contact the author
*
date
Last modified date of the plugin in * YYYY-MM-DD format
*
name
Name of the plugin
*
desc
Short description of the plugin (Text only)
*
url
Website with more information on the plugin * (eg. syntax description)
*
* @param none * @return Array Information about this plugin class. * @public * @static */ function getInfo(){ return array( 'author' => 'Martin Heinemann', 'email' => 'martin.heinemann@tudor.lu', 'date' => '2008-05-30', 'name' => 'imagereference', 'desc' => 'Create image references like latex is doing with figures', 'url' => 'http://wiki.splitbrain.org/wiki:plugins', ); } function getType(){ return 'protected';} function getAllowedTypes() { return array('container','substition','protected','disabled','formatting','paragraphs'); } function getPType(){ return 'normal';} // must return a number lower than returned by native 'code' mode (200) function getSort(){ return 196; } // override default accepts() method to allow nesting // - ie, to get the plugin accepts its own entry syntax function accepts($mode) { if ($mode == substr(get_class($this), 7)) return true; return parent::accepts($mode); } /** * Connect lookup pattern to lexer. * * @param $aMode String The desired rendermode. * @return none * @public * @see render() */ function connectTo($mode) { $this->Lexer->addSpecialPattern('',$mode, 'plugin_imagereference'); $this->Lexer->addEntryPattern('(?=.*?)',$mode,'plugin_imagereference'); $this->Lexer->addEntryPattern('.*?)',$mode,'plugin_imagereference'); } function postConnect() { $this->Lexer->addExitPattern('
', 'plugin_imagereference'); } /** * Handler to prepare matched data for the rendering process. * *

* The $aState parameter gives the type of pattern * which triggered the call to this method: *

*
*
DOKU_LEXER_ENTER
*
a pattern set by addEntryPattern()
*
DOKU_LEXER_MATCHED
*
a pattern set by addPattern()
*
DOKU_LEXER_EXIT
*
a pattern set by addExitPattern()
*
DOKU_LEXER_SPECIAL
*
a pattern set by addSpecialPattern()
*
DOKU_LEXER_UNMATCHED
*
ordinary text encountered within the plugin's syntax mode * which doesn't match any pattern.
*
* @param $aMatch String The text matched by the patterns. * @param $aState Integer The lexer state for the match. * @param $aPos Integer The character position of the matched text. * @param $aHandler Object Reference to the Doku_Handler object. * @return Integer The current lexer state for the match. * @public * @see render() * @static */ function handle($match, $state, $pos, &$handler){ switch ($state) { // ========================================================= case DOKU_LEXER_ENTER : { /* --------------------------------------------------- */ $refLabel = trim(substr($match, 11, -1)); // ----------------------------------------------------- $parsedInput = $this->_parseParam($refLabel); // ------------------------------------------------------ //$data = $this->_imgstart($parsedInput); // store the figure name from imgcaption array_push($this->_figure_name_array, $parsedInput[0]); $this->_figure_map[$parsedInput[0]] = ""; return array('caption_open', $parsedInput); // image anchor label /* --------------------------------------------------- */ } // ========================================================= case DOKU_LEXER_UNMATCHED : { /* --------------------------------------------------- */ $parsed = $this->_parseContent($match); $this->_figure_map[end($this->_figure_name_array)] = $this->_imgend($parsed[0]); return array('data', ''); /* --------------------------------------------------- */ } // ========================================================= case DOKU_LEXER_EXIT : /* --------------------------------------------------- */ return array('caption_close', $this->_figure_map[end($this->_figure_name_array)]); /* --------------------------------------------------- */ // ========================================================= case DOKU_LEXER_MATCHED : /* --------------------------------------------------- */ return array('data', "----".$match."------"); /* --------------------------------------------------- */ // ========================================================= case DOKU_LEXER_SPECIAL : { /* --------------------------------------------------- */ $ref = substr($match, 8, -1); return array('imgref', $ref); /* --------------------------------------------------- */ } } return array(); } /** * Handle the actual output creation. * *

* The method checks for the given $aFormat and returns * FALSE when a format isn't supported. $aRenderer * contains a reference to the renderer object which is currently * handling the rendering. The contents of $aData is the * return value of the handle() method. *

* @param $aFormat String The output format to generate. * @param $aRenderer Object A reference to the renderer object. * @param $aData Array The data created by the handle() * method. * @return Boolean TRUE if rendered successfully, or * FALSE otherwise. * @public * @see handle() */ function render($mode, &$renderer, $indata) { list($case, $data) = $indata; if($mode == 'xhtml'){ // --------------------------------------------- switch ($case) { case 'imgref' : { /* --------------------------------------- */ $refNumber = array_search($data, $this->_figure_name_array); if ($refNumber == null || $refNumber == "") $refNumber = "##"; $str = "".$this->getLang('figure').$refNumber." "; $renderer->doc .= $str; break; // $renderer->_xmlEntities($str);break; /* --------------------------------------- */ } case 'caption_open' : $renderer->doc .= $this->_imgstart($data); break; case 'caption_close' : { // ------------------------------------------------------- list($name, $number, $caption) = $data; $layout = "
".$this->getLang('fig').$number.": ".$caption."
"; $renderer->doc .= $layout; break; } // ------------------------------------------------------- // data is mostly empty!!! case 'data' : $renderer->doc .= $data; break; } return true; } if($mode == 'latex') { // ----------------------------------------- switch ($case) { case 'imgref' : { /* --------------------------------------- */ $renderer->doc .= "\\ref{".$data."}"; break; /* --------------------------------------- */ } case 'caption_open' : { // -------------------------------------- $orientation = "\\centering"; switch($data[1]) { case 'left' : $orientation = "\\left";break; case 'right' : $orientation = "\\right";break; } $renderer->doc .= "\\begin{figure}[H!]{".$orientation; break; // -------------------------------------- } case 'caption_close' : { // ------------------------------------------------------- list($name, $number, $caption) = $data; $layout = "\\caption{".$caption."}\\label{".$name."}\\end{figure}"; $renderer->doc .= $layout; break; } case 'data' : $renderer->doc .= trim($data); break; } return true; // ----------------------------------------- } return false; } function _parseParam($str) { if (!strlen($str)) return array(); $styles = array(); // get the img ref name. Its the first word $parsed = explode(" ", $str, 2); $imgref = $parsed[0]; $tokens = preg_split('/\s+/', $parsed[1], 9); // limit is defensive foreach ($tokens as $token) { // restrict token (class names) characters to prevent any malicious data if (preg_match('/[^A-Za-z0-9_-]/',$token)) continue; $styles['class'] = (isset($styles['class']) ? $styles['class'].' ' : '').$token; } // return imageref name , style // e.G. image1,left return array($imgref, $styles['class']); } function _imgstart($str) { // ============================================ // if (!strlen($str)) return array(); $layout = "
"; return $layout; // ============================================ // } /** * * * @param String $str the image caption * @return array(imagename, image number, image caption) */ function _imgend($str) { // ===================================================== // $figureName = end($this->_figure_name_array); // get the position of the figure in the array $refNumber = array_search($figureName, $this->_figure_name_array); return array($figureName, $refNumber, $str); $layout = "
".$this->getLang('fig').$refNumber.": _figure_name_array)."\">".$str."
"; //$layout = "
Fig. ".$refNumber.": //_figure_name_array)."\">".$str."
"; return $layout; // ===================================================== } /** * divides the image caption and the content between the tags * */ function _parseContent($str) { // ====================================================== if (!strlen($str)) return ""; // parse for '>' $parsed = explode(">", $str, 2); return $parsed; // ====================================================== } } //Setup VIM: ex: et ts=4 enc=utf-8 : ?>
==== style.css ==== Don't forget this, otherwise it will look very uargs. .scheisse {} /* this is some strange thing. If there is nothing on top of the div.imgcaption, the centered images will not have a colored bounding box and the image is left aligned. might be a bug of an older DokuWiki version. */ div.imgcaption { border: 1px solid #ccc; padding: 3px !important; background-color: #f9f9f9; font-size: 94%; text-align: center; width: auto; overflow: hidden; margin: 1px auto; float: none; } div.imgcaptionleft { border: 1px solid #ccc; padding: 3px !important; background-color: #f9f9f9; font-size: 94%; text-align: center; width: auto; overflow: hidden; margin: 1px; float: left; } div.imgcaptionright { border: 1px solid #ccc; padding: 3px !important; background-color: #f9f9f9; font-size: 94%; text-align: center; width: auto; overflow: hidden; margin: 1px; float: right; } div.imgcaption a img { border: 1px solid #ccc; background-color:#FFFFFF; } div.imgcaptionleft a img { border: 1px solid #ccc; background-color:#FFFFFF; } div.imgcaptionright a img { border: 1px solid #ccc; background-color:#FFFFFF; } div.dokuwiki .undercaption { font-size: 95%; } div.dokuwiki .undercaption a:hover { text-decoration:none; } div.dokuwiki .undercaption span { background-image:url(./magnify-clip.png); background-repeat:no-repeat; margin:2px; padding-left:15px; display:none; } div.imgcaption img.mediaright { float: none; margin: 0 0 0.5em 0; } div.imgcaption img.medialeft { float: none; margin: 0 0 0.5em 0; } ==== script.js ==== This resizes the grey box around the image to the image's size. function checkImages() { var divs=document.getElementsByTagName("DIV"); for (var i=0;i", "close":""}; toolbar[toolbar.length] = {"type":"format", "title":"Adds an ImageReference tag", "icon":"../../plugins/imagereference/refbutton.png", "key":"", "open":""}; } addInitEvent(function(){checkImages();}); ==== /lang/en/lang.php ==== default localisation file there are also German, French and Czech localisations in the downloadable archives. =====Installation===== ==== Sources: ==== To install the plugin manually, download the source to your plugin folder, ''lib/plugins'' and extract its contents. That will create a new plugin folder, ''lib/plugins/imagereference'', and install the plugin. The folder will contain: style.css style-sheet for the figures and captions syntax.php plugin script script.js javascript code magnify-clip.png a small image to display wether the image can be viewed in bigger size button.png toolbar button for inserting the image caption tag refbutton.png toolbar button for inserting the image reference tag /lang/ folder storing the localisation files The plugin is now installed. ===== Bugs ===== Current (**2008/08/13**) version conflicts with toolbar above editor (see also [[:faq:toolbar]]), probably due to new JavaScript code, pre-**2008/08/13** version works. * Can you tell me some more details about this bug? **martin** The Firefox Error console shows this error message: Error: missing ; before statement Source File: http://myside/dokuwiki/lib/exe/js.php?edit=1&write=1 Line: 1, Column: 79 Source Code: ].className=="imgcaptionright"){var children=divs[i].getElementsByTagName("IMG")var tmpImg=divs[i].childNodes[0].childNodes[0];if(tmpImg==null)tmpImg=divs[i].childNodes[0];else{var innerElements=divs[i];var iLink=innerElements.childNodes[1].childNodes[2]; It seams to be the missing ; in one var declaration in the JavaScript, that is in the downloadable tgz file. The code from the codebox above works correct. **christian** ---- jslint (www.jslint.com) reprorted several problems with the 2009-01-07 version of script.js. Here's what it said: Error: Implied global: addInitEvent 47, document 3, toolbar 31 37, window 30 Problem at line 11 character 24: Use '===' to compare with 'null'. if (tmpImg == null) Problem at line 12 character 17: Expected '{' and instead saw 'tmpImg'. tmpImg = divs[i].childNodes[0]; Problem at line 30 character 20: Use '!==' to compare with 'undefined'. if(window.toolbar!=undefined){ Global checkImages 1 checkImages() Variable divs, i, iLink, iSpan, innerElements, tmpImg Unused children 47 "addInitEvent"() Global checkImages Thanks, Kingsley ---- The image captions do not work correctly when they contain acronyms recognized by DokuWiki. The acronyms get pulled out and placed BEFORE the image tag in the HTML, and it renders badly. ---- It does not work with the [[:plugin:svg_pureinsert]] plugin as it is. This bug is caused by the iframe reporting the width as a string. To fix it, change line 24 in script.js to: divs[i].style.width=(parseInt(tmpImg.width) + 8)+"px"; Also, the box isn't sized correctly with this plugin, because it uses the object tag instead of img. ---- This plugin breaks XHTML compatibility because it adds a
tag inside a

tag. To fix it, change line 61 from function getPType(){ return 'normal';} to function getPType(){ return 'block';} ===== User wishes ===== - Is there any possibility to use this plugin for tables with own numbering and name (Table 1 etc.)? - Make possible to remove "fig. X" text (either admin panel or per image) - Get text from image alt-text if there isn't text in reference - It will be great to show a reference list when click the image reference button --- //[[lainme993@gmail.com|lainme]] 2010/08/06 08:18// - And Hope for PHP5.3 capability --- //[[lainme993@gmail.com|lainme]] 2010/08/09 11:21// - Please update to support the latest Dokuwiki 2011/06/17 11:21//