DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:definitions

Definition List plugin 2

Compatible with DokuWiki

No compatibility info given!

plugin Adds definition lists to DokuWiki's syntax.

Last updated on
2005-08-17
Provides
Syntax

This extension has not been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues.

Similar to definition, deflist, dl

Tagged with definitions, formatting, 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.

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).

style.css
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

Omniting empty definition

If you wan to create something like this:

<dl>
  <dt>First Term</dt>
  <dt>Second Term</dt>
  <dd>Their definition</dt>
</dl>

You try to do this:

= First Term : 
= Second Term : Their definition

This is problematic when you try create something like this.

So, I prepare patch for this (correctDefinitions.patch):

correctDefinitions.patch
diff -crB definitions/syntax.php definitions-ng/syntax.php
*** definitions/syntax.php	Tue Jun 23 13:50:00 2009
--- definitions-ng/syntax.php	Tue Jun 23 14:09:40 2009
***************
*** 130,150 ****
          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;
          }
--- 130,149 ----
          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";
              } else if ($data[1] == DOKU_LEXER_MATCHED){
                  // close previous description and output term and start another description
  		if (trim($data[0]) != '') {
!                     $renderer->doc .= "\t<dt>".$data[0]."</dt>\n";
  		}
              } else if ($data[1] == DOKU_LEXER_UNMATCHED){
                  // we are inside description, so pass it to renderer unchanged
!                 if (trim($data[0]) != '') {
!                         $renderer->doc .= "\t\t<dd>".$data[0]."</dd>\n";
!                 }
              } else if ($data[1] == DOKU_LEXER_EXIT){
                  // close last description and close whole block
!                 $renderer->doc .= "</dl>\n";
              }
              return true;
          }

To apply this patch, run in the dir of definition plugin

patch -p1 -i correctDefinitions.patch

You can view patch in action on my page

plugin/definitions.txt · Last modified: 2012-11-20 23:36 by Klap-in