- 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":"
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. 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//