Table of Contents

Definition List plugin 2

definitions plugin by Pavel Vitis
Adds definition lists to DokuWiki's syntax.

Last updated on 2005-08-17. Provides Syntax.
No compatibility info given!

Similar to definition, definitionlist, deflist, dl, yalist.

Tagged with definitions, list.

1. Description

With this plugin the syntax of DokuWiki is extended to allow definition lists. <dl><dt>term</dt><dd>Term definition</dd></dl>

2. Syntax

  = Term : Definition of term.

There should be at least two spaces before '='.

3. Example

  = Item 1 : Definition of item 1.
  = Item 2 : Definition of item 2.
  = : Second definition of item 2.
  = Item 3 : Definition of item 3.
  = Item 4 : 
  = Item 5 : 
  = Item 6 : Definition of items 4 through 6.

Will be rendered as HTML code:

<dl>
  <dt>Item 1</dt>
    <dd>Definition of item 1.</dd>
  <dt>Item 2</dt>
    <dd>Definition of item 2.</dd>
    <dd>Second definition of item 2.</dd>
  <dt>Item 3</dt>
    <dd>Definition of item 3.</dd>
  <dt>Item 4</dt>
  <dt>Item 5</dt>
  <dt>Item 6</dt>
    <dd>Definition of items 4 through 6.</dd>
</dl>

4. Plugin

Put the following PHP file in /lib/plugins/definitions/syntax.php.

<?php
/**
 * Allow creating of HTML definition lists:
 * <DL>
 *   <DT>term</DT><DD>Term explanation</DD>
 * </DL>
 *
 * Syntax:
 *   = term : definition
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Pavel Vitis <pavel [dot] vitis [at] seznam [dot] cz>
 */
 
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_definitions extends DokuWiki_Syntax_Plugin {
 
    /**
     * return some info
     */
    function getInfo(){
        return array(
            'author' => 'Pavel Vitis',
            'email'  => 'pavel [dot] vitis [at] seznam [dot] cz',
            'date'   => '2005-08-17',
            'name'   => 'Definition list plugin',
            'desc'   => 'Add HTML style definition list = term : definition',
            'url'    => 'http://www.dokuwiki.org/plugin:definitions',
        );
    }
 
    /**
     * What kind of syntax are we?
     */
    function getType(){
        return 'container';
    }
 
    function getAllowedTypes() {
        // allow all types inside <DD></DD> descriptions
        return array('container','substition','protected','disabled','formatting');
    }
 
   /**
    * Paragraph Type
    *
    * Defines how this syntax is handled regarding paragraphs. This is important
    * for correct XHTML nesting. Should return one of the following:
    *
    * '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.
    *
    * @see Doku_Handler_Block
    */
    function getPType(){
        // Normal because we don't want to have <p></p> around each block
        return 'normal';
    }
 
    /**
     * Where to sort in?
     */
    function getSort(){
        // just make sure that we render before 'code' parser otherwise it ends up as code block
        return 11;
    }
 
    /**
     * Connect pattern to lexer
     */
    function connectTo($mode) {
       // let's get all from '=' to ':' inclusive
       $this->Lexer->addEntryPattern('\n {2,}=[^:]+:',$mode,'plugin_definitions');
       $this->Lexer->addEntryPattern('\n\t{1,}=[^:]+:',$mode,'plugin_definitions');
 
       // and match all forthcoming '= term :' as well
       $this->Lexer->addPattern('\n {2,}=[^:]+:', 'plugin_definitions');
       $this->Lexer->addPattern('\n\t{1,}=[^:]+:', 'plugin_definitions');
    }
 
    function postConnect() {
        // end each definition with new line
        $this->Lexer->addExitPattern('\n','plugin_definitions');
    }
 
    /**
     * Handle the match
     */
    function handle($match, $state, $pos, &$handler){
        switch ( $state ) {
            case DOKU_LEXER_ENTER:
                // we are at the start of whole list, so strip off '=' at the beginning and ':'
                // at the end and we get the 'term'
                $match = substr(trim($match),1,-1);
                return array($match, $state);
                break;
            case DOKU_LEXER_MATCHED:
                // we are at another = line, so strip off '=' at the beginning and ':'
                // at the end and we get another 'term'
                $match = substr(trim($match),1,-1);
                return array($match, $state);
                break;
            case DOKU_LEXER_UNMATCHED:
                // we are inside description here so do nothing special
                return array($match, $state);
                break;
            case DOKU_LEXER_EXIT:
                // we are at the end of whole list so do nothing special
                return array($match, $state);
                break;
        }
    }
 
    /**
     * Create output
     */
    function render($mode, &$renderer, $data) {
        if($mode == 'xhtml'){
            if ($data[1] == DOKU_LEXER_ENTER) {
                // output starting tag and first term and start description
                $renderer->doc .= "<dl>\n\t<dt>".$data[0]."</dt>\n\t\t<dd>";
            } else if ($data[1] == DOKU_LEXER_MATCHED){
                // close previous description and output term and start another description
		if (trim($data[0]) != '') {
                    $renderer->doc .= "</dd>\n\t<dt>".$data[0]."</dt>\n\t\t<dd>";
		}
		else {
                    $renderer->doc .= "</dd>\n\t\t<dd>";
		}    
            } else if ($data[1] == DOKU_LEXER_UNMATCHED){
                // we are inside description, so pass it to renderer unchanged
                $renderer->doc .= ''.$data[0].'';
            } else if ($data[1] == DOKU_LEXER_EXIT){
                // close last description and close whole block
                $renderer->doc .= "</dd>\n</dl>\n";
            }
            return true;
        }
        return false;
    }
}
 
//Setup VIM: ex: et ts=4 enc=utf-8 :
?>

5. Stylesheet (optional)

Put the following css into file /lib/plugins/definitions/style.css (optional).

dl {
}
dt {
  font-size: 90%;
  font-weight:bold;
}
dd {
  font-size: 95%;
  margin-left:10pt;
}
 
dd p {
  display: inline;
  margin: 0px;
  padding:0px;
}

6. Bugs

None so far.

7. ToDo

8. Discussion

You can see it working on my page. — Pavel Vitis 2005-08-18 02:21

Pavel, you shouldn't pass raw wiki data unfiltered to the output document - it should at least go through an entity conversion function, e.g. $renderer→xmlEntities(). That will convert ”<” & ”>” to &lt; & &gt; and ensure no malicious html (or javascript) can be embedded in the wiki page. — Christopher Smith 2005-08-25 20:09