syntax_plugin_tip.php - A PHP4 class that implements * a DokuWiki plugin for small notes/tips fragments. * *

* Usage:
* <tip [c|l|r] [u|e|d] [h|i|n|w]>some text</tip> *

 *	Copyright (C) 2006, 2007  M.Watermann, D-10247 Berlin, FRG
 *			All rights reserved
 *		EMail : <support@mwat.de>
 * 
* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either * version 3 of the * License, or (at your option) any later version.
* This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. *
* @author Matthias Watermann * @version $Id: syntax_plugin_tip.php,v 1.5 2007/08/15 12:36:19 matthias Exp $ * @since created 02-Dec-2006 */ class syntax_plugin_tip extends DokuWiki_Syntax_Plugin { /** * @privatesection */ //@{ /** * HTML special characters to replace in render(). * * @private * @see render() */ var $_Chars = array('&', '<', '>'); /** * Entity replacements for HTML special characters. * * @private * @see render() */ var $_Ents = array('&', '<', '>'); //@} /** * @publicsection */ //@{ /** * Tell the parser whether the plugin accepts syntax mode * $aMode within its own markup. * * @param $aMode String The requested syntaxmode. * @return Boolean TRUE unless $aMode is * 'plugin_tip' (which would result in a FALSE * method result). * @public * @see getAllowedTypes() */ function accepts($aMode) { return ('plugin_tip' != $aMode); } // accepts() /** * Connect lookup pattern to lexer. * * @param $aMode String The desired rendermode. * @public * @see render() */ function connectTo($aMode) { $this->Lexer->addEntryPattern( '\x3Ctip(?:\s+[a-z ]*\s*)*\x3E(?=.*?\x3C\x2Ftip\x3E)', $aMode, 'plugin_tip'); } // connectTo() /** * Get an array of mode types that may be nested within the * plugin's own markup. * * @return Array Allowed nested types (i.e. all known types). * @public * @see accepts() * @static */ function getAllowedTypes() { return array( 'container', 'baseonly', 'formatting', 'substition', // sic! should be __substitution__ 'protected', 'disabled', 'paragraphs'); } // getAllowedTypes() /** * 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)
*
* @return Array Information about this plugin class. * @public * @static */ function getInfo() { return array( 'author' => 'Matthias Watermann', 'email' => 'support@mwat.de', 'date' => '2007-08-15', 'name' => 'Tip Syntax Plugin', 'desc' => 'Place hints &c. on a page ' . '[ ... ]', 'url' => 'http://wiki.splitbrain.org/plugin:tip'); } // getInfo() /** * Define how this plugin is handled regarding paragraphs. * *

* This method is important for correct XHTML nesting. * It returns one of the following values: *

*
*
normal
The plugin can be used inside paragraphs.
*
block
Open paragraphs need to be closed before * plugin output.
*
stack
Special case: Plugin wraps other paragraphs.
*
* @return String "normal" instead of the (correct) "block" * since otherwise the current DokuWiki parser wouldn't allow for * nested paragraphs. * @public * @static */ function getPType() { return 'normal'; } // getPType() /** * Where to sort in? * * @return Integer 415 (not really important here). * @public * @static */ function getSort() { return 415; } // getSort() /** * Get the type of syntax this plugin defines. * * @return String "container". * @public * @static */ function getType() { return 'container'; } // getType() /** * 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_EXIT
*
a pattern set by addExitPattern()
*
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 Array Index [0] holds the current * $aState, index [1] the match prepared for * the render() method. * @public * @see render() * @static */ function handle($aMatch, $aState, $aPos, &$aHandler) { switch ($aState) { case DOKU_LEXER_ENTER: $o = 'r'; // orientation, default: 'right' $p = 'e'; // positioning, default: 'even' $t = ''; // type, default: no image $hits = array(); $aMatch = preg_split('|\s+|', substr($aMatch, 4), -1, PREG_SPLIT_NO_EMPTY); while (list($i, $arg) = each($aMatch)) { switch ($i = strtolower($arg{0})) { case 'c': // center case 'l': // left case 'r': // right $o = $i; break; case 'd': // down case 'e': // even case 'u': // up $p = $i; break; case 'h': // hint case 'i': // info case 'n': // note case 'w': // warn $t = $i; default: break; } // switch } // while return array(DOKU_LEXER_ENTER, $o . $p . $t); case DOKU_LEXER_UNMATCHED: return array(DOKU_LEXER_UNMATCHED, $aMatch); case DOKU_LEXER_EXIT: return array(DOKU_LEXER_EXIT, ''); default: // This state isn't used by 'render()' // and causes it to do nothing at all: return array(DOKU_LEXER_SPECIAL, ''); } // switch } // handle() /** * Add exit pattern to lexer. * * @public */ function postConnect() { $this->Lexer->addExitPattern('\x3C\x2Ftip\x3E', 'plugin_tip'); } // postConnect() /** * Handle the actual output creation. * *

* The method checks for the given $aFormat and returns * FALSE when a format isn't supported. $aRenderer * is 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/returned by the * handle() method. * @return Boolean TRUE if rendered successfully, * or FALSE otherwise. * @public * @see handle() */ function render($aFormat, &$aRenderer, &$aData) { if ('xhtml' != $aFormat) { return FALSE; } // if // XXX: All those "

" and "

" tags handled here are just kind // of workaround problems with the current DokuWiki renderer; it's // needed because we've to lie (in "getPType()") about the created // markup's type. // Basically they are __wrong__ here (since they are outside the // plugin's domain of responsibility) but, alas, without them // invalid HTML would be generated :-( // If and when DokuWiki becomes more stateful // the superflous tags should be removed. switch ($aData[0]) { case DOKU_LEXER_ENTER: // Since we have to use PType 'normal' we must close the // current paragraph and open a new one for our own contents. $hits = array(); if (preg_match('|\s*

\s*$|i', $aRenderer->doc, $hits)) { $aRenderer->doc = substr($aRenderer->doc, 0, -strlen($hits[0])) . '

'; } else { $aRenderer->doc .= '

'; } // if // The "tipAll" class is meant to make CSS easier. return TRUE; case DOKU_LEXER_UNMATCHED: $aRenderer->doc .= str_replace($this->_Chars, $this->_Ents, $aData[1]); return TRUE; case DOKU_LEXER_EXIT: // Since we have to use PType 'normal' we must open // a new paragraph for the following text. $aRenderer->doc = preg_replace('|\s*

\s*

\s*|', '', $aRenderer->doc) . '

'; default: return TRUE; } // switch } // render() //@} } // class syntax_plugin_tip } // if ?>