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
?>