raster pushed a commit to branch master.

http://git.enlightenment.org/website/www.git/commit/?id=8e7c7d18d5d360b1f29ac9a0e4f5cc24b930452b

commit 8e7c7d18d5d360b1f29ac9a0e4f5cc24b930452b
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Thu Apr 16 13:40:32 2015 +0900

    www plugins - add exttab3, itemtable and yalist
---
 public_html/lib/plugins/exttab3/README.md         |  26 ++
 public_html/lib/plugins/exttab3/action.php        |  53 +++
 public_html/lib/plugins/exttab3/images/d.png      | Bin 0 -> 520 bytes
 public_html/lib/plugins/exttab3/images/sample.png | Bin 0 -> 15655 bytes
 public_html/lib/plugins/exttab3/images/table.png  | Bin 0 -> 892 bytes
 public_html/lib/plugins/exttab3/plugin.info.txt   |   7 +
 public_html/lib/plugins/exttab3/style.css         |  13 +
 public_html/lib/plugins/exttab3/syntax.php        | 392 ++++++++++++++++++++++
 public_html/lib/plugins/itemtable/syntax.php      | 227 +++++++++++++
 public_html/lib/plugins/yalist/LICENSE            | 339 +++++++++++++++++++
 public_html/lib/plugins/yalist/README.md          |  19 ++
 public_html/lib/plugins/yalist/plugin.info.txt    |   7 +
 public_html/lib/plugins/yalist/print.css          |  37 ++
 public_html/lib/plugins/yalist/style.css          |  37 ++
 public_html/lib/plugins/yalist/syntax.php         | 334 ++++++++++++++++++
 15 files changed, 1491 insertions(+)

diff --git a/public_html/lib/plugins/exttab3/README.md 
b/public_html/lib/plugins/exttab3/README.md
new file mode 100644
index 0000000..75bb27d
--- /dev/null
+++ b/public_html/lib/plugins/exttab3/README.md
@@ -0,0 +1,26 @@
+DokuWiki plugin ExtTab3
+=======================
+
+The third trial to implement extended (MediaWiki-style) table syntax in 
DokuWiki
+
+Syntax
+------
+
+http://www.mediawiki.org/wiki/Help:Tables
+
+| markup | description |
+|:--     |:--          |
+|<code>{&#124;</code>  | table start |
+|<code>{+</code>       | table caption |
+|<code>{-</code>       | table row |
+|<code>!</code>        | table header |
+|<code>&#124;</code>   | table data |
+|<code>&#124;}</code>  | table end |
+
+----
+Licensed under the GNU Public License (GPL) version 2
+
+More infomation is available:
+  * http://www.dokuwiki.org/plugin:exttab3
+
+(c) 2014 Satoshi Sahara \<sahara.sato...@gmail.com>
diff --git a/public_html/lib/plugins/exttab3/action.php 
b/public_html/lib/plugins/exttab3/action.php
new file mode 100644
index 0000000..7f87a0e
--- /dev/null
+++ b/public_html/lib/plugins/exttab3/action.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * DokuWiki Plugin ExtTab3 (Action component)
+ *
+ * Allows extended (MediaWiki-style) tables inside DokuWiki 
+ *
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author     Satoshi Sahara <sahara.sato...@gmail.com>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'action.php');
+
+class action_plugin_exttab3 extends DokuWiki_Action_Plugin {
+
+    /**
+     * register the eventhandlers
+     */
+    public function register(Doku_Event_Handler $controller){
+        $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 
'handle_toolbar', array ());
+    }
+
+    public function handle_toolbar(&$event, $param) {
+        $event->data[] = array (
+            'type' => 'picker',
+            'title' => 'extended table typical patterns',
+            'icon' => DOKU_BASE.'lib/plugins/exttab3/images/table.png',
+            'list' => array(
+                array(
+                    'type'   => 'format',
+                    'title'  => 'Definition table',
+                    'icon'   => DOKU_BASE.'lib/plugins/exttab3/images/d.png',
+                    'sample' => 'term',
+                    'open'   => '\n{|\n|-\n! ',
+                    'close'  => ' || description\n|}\n',
+                    'block'  => true
+                ),
+                array(
+                    'type'   => 'format',
+                    'title'  => 'longer cell content',
+                    'icon'   => 
DOKU_BASE.'lib/plugins/exttab3/images/table.png',
+                    'sample' => 'table caption',
+                    'open'   => '\n{| style=""\n|+ ',
+                    'close'  => '\n!\nA1\n!\nB1\n|-\n|\nA2\n|\nB2\n|}\n',
+                    'block'  => true
+                ),
+            )
+        );
+    }
+}
+
diff --git a/public_html/lib/plugins/exttab3/images/d.png 
b/public_html/lib/plugins/exttab3/images/d.png
new file mode 100644
index 0000000..9b4f168
Binary files /dev/null and b/public_html/lib/plugins/exttab3/images/d.png differ
diff --git a/public_html/lib/plugins/exttab3/images/sample.png 
b/public_html/lib/plugins/exttab3/images/sample.png
new file mode 100644
index 0000000..478681e
Binary files /dev/null and b/public_html/lib/plugins/exttab3/images/sample.png 
differ
diff --git a/public_html/lib/plugins/exttab3/images/table.png 
b/public_html/lib/plugins/exttab3/images/table.png
new file mode 100644
index 0000000..74799e1
Binary files /dev/null and b/public_html/lib/plugins/exttab3/images/table.png 
differ
diff --git a/public_html/lib/plugins/exttab3/plugin.info.txt 
b/public_html/lib/plugins/exttab3/plugin.info.txt
new file mode 100644
index 0000000..d2280ae
--- /dev/null
+++ b/public_html/lib/plugins/exttab3/plugin.info.txt
@@ -0,0 +1,7 @@
+base   exttab3
+author Satoshi Sahara
+email  sahara.sato...@gmail.com
+date   2014-11-20
+name   Extended Table Syntax 3
+desc   Allows extended (MediaWiki-style) tables inside DokuWiki
+url    https://www.dokuwiki.org/plugin:exttab3
diff --git a/public_html/lib/plugins/exttab3/style.css 
b/public_html/lib/plugins/exttab3/style.css
new file mode 100644
index 0000000..5c9e2d2
--- /dev/null
+++ b/public_html/lib/plugins/exttab3/style.css
@@ -0,0 +1,13 @@
+/*
+ * DokuWiki Plugin ExtTab3 style.css
+ */
+div.exttab p {
+    margin-bottom: 0;
+}
+div.exttab ol {
+    padding-left: 0em;
+}
+div.exttab ul {
+    padding-left: 0em;
+}
+
diff --git a/public_html/lib/plugins/exttab3/syntax.php 
b/public_html/lib/plugins/exttab3/syntax.php
new file mode 100644
index 0000000..d1ff7c4
--- /dev/null
+++ b/public_html/lib/plugins/exttab3/syntax.php
@@ -0,0 +1,392 @@
+<?php
+/**
+ * DokuWiki Plugin ExtTab3 (Syntax component)
+ *
+ * Allows extended (MediaWiki-style) tables inside DokuWiki
+ *
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author     Satoshi Sahara <sahara.sato...@gmail.com>
+ * @date       2014-11-20
+ */
+ 
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+ 
+class syntax_plugin_exttab3 extends DokuWiki_Syntax_Plugin {
+
+    protected $stack = array();  // stack of current open tag - used by 
handle() method
+    protected $tableDepth;       // table depth counter
+    protected $tagsmap  = array();
+    protected $attrsmap = array();
+
+    function __construct() {
+        $this->tableDepth = 0;
+
+        // define name, prefix and postfix of tags
+        $this->tagsmap = array(
+                'table'   => array("", "\n" ),        // table start  : {|
+                '/table'  => array("", ""),           // table end    : |}
+                'caption' => array("\t", "\n" ),      // caption      : |+
+                'tr'      => array("\t", "\n" ),      // table row    : |-
+                'th'      => array("\t"."\t", "\n" ), // table header : !
+                'td'      => array("\t"."\t", "\n" ), // table data   : |
+                'div'     => array("", "\n" ),        // wrapper
+        );
+
+        // define allowable attibutes for table tags
+        $this->attrsmap = array(
+            # simple ones (value is a single word)
+            'align', 'border', 'cellpadding', 'cellspacing', 'frame', 
+            'rules', 'width', 'class', 'dir', 'id', 'lang', 'xml:lang',
+            # more complex ones (value is a string or style)
+            'bgcolor', 'summary', 'title', 'style',
+            # additional tr, thead, tbody, tfoot attributes
+            'char', 'charoff', 'valign',
+            # additional td attributes
+            'abbr', 'colspan', 'axis', 'headers', 'rowspan', 'scope',
+            'height', 'width', 'nowrap',
+        );
+    }
+
+    function getType(){  return 'container';}
+    function getPType(){ return 'block';}
+    function getSort(){  return 59; } // = Doku_Parser_Mode_table-1
+    function getAllowedTypes() { 
+        return array('container', 'formatting', 'substition', 'disabled', 
'protected'); 
+    }
+
+    /**
+     * Exttab3 syntax match patterns for parser
+     * modified from original exttab2 code
+     */
+    function connectTo($mode) {
+        $pluginMode = 'plugin_'.$this->getPluginName();
+        $this->Lexer->addEntryPattern('\n\{\|[^\n]*',$mode, $pluginMode); 
+    }
+    function postConnect() {
+        $pluginMode = 'plugin_'.$this->getPluginName();
+        $attrs = '[^\n\{\|\!\[]+'; // match pattern for attributes
+
+        // terminale = Exit Pattren: table end markup + extra brank line
+        $this->Lexer->addExitPattern(' *?\n\|\}(?=\n\n)', $pluginMode);
+
+        // caption:      |+ attrs | caption
+        $this->Lexer->addPattern("\n\|\+ *(?:$attrs\|(?!\|))?", $pluginMode);
+        // table row:    |- attrs
+        $this->Lexer->addPattern(' *?\n\|\-+[^\n]*', $pluginMode);
+        // table start:  {| attrs
+        $this->Lexer->addPattern(' *?\n\{\|[^\n]*', $pluginMode);
+        // table end:    |}
+        $this->Lexer->addPattern(' *?\n\|\}', $pluginMode);
+        // table header: ! attrs |
+        $this->Lexer->addPattern("(?: *?\n|\!)\!(?:$attrs\|(?!\|))?", 
$pluginMode);
+        // table data:   | attrs |
+        $this->Lexer->addPattern("(?: *?\n|\|)\|(?:$attrs\|(?!\|))?", 
$pluginMode);
+    }
+
+
+    /**
+     * helper function to simplify writing plugin calls to the instruction list
+     * first three arguments are passed to function render as $data
+     */
+    protected function _writeCall($tag, $attr, $state, $pos, $match, 
&$handler) {
+        $handler->addPluginCall($this->getPluginName(),
+            array($state, $tag, $attr), $state, $pos, $match);
+    }
+
+    /**
+     * helper function for exttab syntax translation to html
+     *
+     * @param string $match       matched string
+     * @return array              tag name, and attributes
+     */
+    protected function _resolve_markup($match='') {
+        $markup = substr(trim($match), 0, 2);
+        if ($markup       == '{|') { // table_start
+            return array('table', substr($match, 2));
+        } elseif ($markup == '|}') { // table_end
+            return array('/table', '');
+        } elseif ($markup == '|+') { // table_caption
+            return array('caption', trim(substr($match, 2), '|'));
+        } elseif ($markup == '|-') { // table_row
+            return array('tr', trim(substr($match, 2), '-'));
+        }
+        $markup = substr(trim($match), 0, 1);
+        if ($markup       == '!') {  // table_header
+            return array('th', trim($match, '!|'));
+        } elseif ($markup == '|') {  // table_data
+            return array('td', trim($match, '|'));
+        } else {
+            msg($this->getPluginName().' ERROR: unknown syntax: '.hsc($match) 
,-1);
+            return false;
+        }
+    }
+
+
+    /**
+     * Handle the match
+     */
+    function handle($match, $state, $pos, Doku_Handler $handler) {
+
+        // msg('handle: state='.$state.' 
match="'.str_replace("\n","_",$match).'"', 0);
+
+        switch ($state) {
+            case DOKU_LEXER_ENTER:
+                // wrapper open
+                $this->_writeCall('div', 'class="exttab"', DOKU_LEXER_ENTER, 
$pos,$match,$handler);
+                // table start
+                list($tag, $attr) = $this->_resolve_markup($match);
+                array_push($this->stack, $tag);
+                $this->_writeCall($tag, $attr, DOKU_LEXER_ENTER, 
$pos,$match,$handler);
+                $this->tableDepth = $this->tableDepth +1; // increment table 
depth counter
+                break;
+            case DOKU_LEXER_MATCHED:
+                $tag_prev = end($this->stack);
+                list($tag, $attr) = $this->_resolve_markup($match);
+                switch ($tag_prev) {
+                    case 'caption':
+                                $oldtag = array_pop($this->stack);
+                                $this->_writeCall($oldtag,'',DOKU_LEXER_EXIT, 
$pos,$match,$handler);
+                    case 'table':
+                        switch ($tag) {
+                            case 'table':
+                                msg($this->getPluginName().' Syntax ERROR: 
match='.hsc($match) ,-1);
+                                break;
+                            case 'caption':
+                            case 'tr':
+                                array_push($this->stack, $tag);
+                                $this->_writeCall($tag, $attr, 
DOKU_LEXER_ENTER, $pos,$match,$handler);
+                                break;
+                            case 'th':
+                            case 'td':
+                                array_push($this->stack, 'tr');
+                                $this->_writeCall('tr', '', DOKU_LEXER_ENTER, 
$pos,$match,$handler);
+                                array_push($this->stack, $tag);
+                                $this->_writeCall($tag, $attr, 
DOKU_LEXER_ENTER, $pos,$match,$handler);
+                                break;
+                            case '/table':
+                                array_pop($this->stack);
+                                $this->_writeCall('table', '', 
DOKU_LEXER_EXIT, $pos,$match,$handler);
+                                $this->tableDepth = $this->tableDepth -1;
+                                break;
+                        }
+                        break;
+                    case 'tr':
+                        switch ($tag) {
+                            case 'table':
+                            case 'caption':
+                                msg($this->getPluginName().' Syntax ERROR: 
match='.hsc($match) ,-1);
+                                break;
+                            case 'tr':
+                                $oldtag = array_pop($this->stack);
+                                $this->_writeCall($oldtag, '', 
DOKU_LEXER_EXIT, $pos,$match,$handler); 
+                                array_push($this->stack, $tag);
+                                $this->_writeCall($tag, $attr, 
DOKU_LEXER_ENTER, $pos,$match,$handler);
+                                break;
+                            case 'th':
+                            case 'td':
+                                array_push($this->stack, $tag);
+                                $this->_writeCall($tag, $attr, 
DOKU_LEXER_ENTER, $pos,$match,$handler);
+                                break;
+                            case '/table':
+                                do { // rewind table
+                                    $oldtag = array_pop($this->stack);
+                                    
$this->_writeCall($oldtag,'',DOKU_LEXER_EXIT, $pos,$match,$handler);
+                                } while ($oldtag != 'table');
+                                $this->tableDepth = $this->tableDepth -1;
+                                break;
+                        }
+                        break;
+                    case 'th':
+                    case 'td':
+                        switch ($tag) {
+                            case 'table':   // a table within a table
+                                array_push($this->stack, $tag);
+                                $this->_writeCall($tag, $attr, 
DOKU_LEXER_ENTER, $pos,$match,$handler);
+                                $this->tableDepth = $this->tableDepth +1;
+                                break;
+                            case 'caption':
+                                msg($this->getPluginName().' Syntax ERROR: 
match='.hsc($match) ,-1);
+                                break;
+                            case 'tr':
+                                do { // rewind old row prior to start new row
+                                    $oldtag = array_pop($this->stack);
+                                    
$this->_writeCall($oldtag,'',DOKU_LEXER_EXIT, $pos,$match,$handler);
+                                } while ($oldtag != 'tr');
+                                array_push($this->stack, $tag);
+                                $this->_writeCall($tag, $attr, 
DOKU_LEXER_ENTER, $pos,$match,$handler);
+                                break;
+                            case 'th':
+                            case 'td':
+                                $oldtag = array_pop($this->stack);
+                                $this->_writeCall($oldtag,'',DOKU_LEXER_EXIT, 
$pos,$match,$handler); 
+                                array_push($this->stack, $tag);
+                                $this->_writeCall($tag, $attr, 
DOKU_LEXER_ENTER, $pos,$match,$handler);
+                                break;
+                            case '/table':
+                                do { // rewind table
+                                    $oldtag = array_pop($this->stack);
+                                    
$this->_writeCall($oldtag,'',DOKU_LEXER_EXIT, $pos,$match,$handler);
+                                } while ($oldtag != 'table');
+                                $this->tableDepth = $this->tableDepth -1;
+                                break;
+                        }
+                        break;
+                }
+                break;
+            case DOKU_LEXER_EXIT:
+                if ($this->tableDepth > 1) {
+                    msg($this->getPluginName().': missing table end markup 
"|}" '.$this->tableDepth, -1);
+                }
+                while ($tag = array_pop($this->stack)) {
+                    $this->_writeCall($tag,'',DOKU_LEXER_EXIT, 
$pos,$match,$handler);
+                }
+                $this->tableDepth = 0;
+                // wrapper close
+                $this->_writeCall('div', '', DOKU_LEXER_EXIT, 
$pos,$match,$handler);
+                break;
+            case DOKU_LEXER_UNMATCHED:
+                $tag_prev = end($this->stack);
+                switch ($tag_prev) {
+                    case 'caption':
+                                // cdata --- use base() instead of 
$this->_writeCall()
+                                $handler->base($match, $state, $pos);
+                                break;
+                    case 'table':
+                                array_push($this->stack, 'tr');
+                                $this->_writeCall('tr','',DOKU_LEXER_ENTER, 
$pos,$match,$handler);
+                    case 'tr':
+                                array_push($this->stack, 'td');
+                                $this->_writeCall('td','',DOKU_LEXER_ENTER, 
$pos,$match,$handler);
+                    case 'th':
+                    case 'td':
+                                // cdata --- use base() instead of 
$this->_writeCall()
+                                $handler->base($match, $state, $pos);
+                                break;
+                }
+                break;
+        }
+    }
+
+
+   /**
+    * Create output
+    */
+    function render($format, Doku_Renderer $renderer, $data) {
+        if (empty($data)) return false;
+
+        switch ($format) {
+            case 'xhtml' : return $this->render_xhtml($renderer, $data);
+            default:
+                return true;
+        }
+        return false;
+    }
+
+    protected function render_xhtml(&$renderer, $data) {
+        //list($tag, $state, $match) = $data;
+        list($state, $tag, $attr) = $data;
+
+        switch ( $state ) {
+            case DOKU_LEXER_ENTER:    // open tag
+                $renderer->doc.= $this->_open($tag, $attr);
+                break;
+            case DOKU_LEXER_MATCHED:  // defensive, shouldn't occur
+            case DOKU_LEXER_UNMATCHED:
+                $renderer->cdata($tag);
+                break;
+            case DOKU_LEXER_EXIT:     // close tag
+                $renderer->doc.= $this->_close($tag);
+                break;
+        }
+    }
+
+    /**
+     * open a exttab tag, used by render_xhtml()
+     *
+     * @param  string $tag        'table','caption','tr','th' or 'td'
+     * @param  string $attr       attibutes of tag element
+     * @return string             html used to open the tag
+     */
+    protected function _open($tag, $attr=NULL) {
+        $before = $this->tagsmap[$tag][0];
+        $after  = $this->tagsmap[$tag][1];
+        $attr = $this->_cleanAttrString($attr, $this->attrsmap);
+        return $before.'<'.$tag.$attr.'>'.$after;
+    }
+
+    /**
+     * close a exttab tag, used by render_xhtml()
+     *
+     * @param  string $tag        'table','caption','tr','th' or 'td'
+     * @return string             html used to close the tag
+     */
+    protected function _close($tag) {
+        $before = $this->tagsmap[$tag][0];
+        $after  = $this->tagsmap[$tag][1];
+        return $before.'</'.$tag.'>'.$after;
+    }
+
+
+
+    /**
+     * Make the attribute string safe to avoid XSS attacks.
+     *
+     * @author Ashish Myles <marci...@gmail.com>
+     *
+     * @param  string $attr           attibutes to be checked
+     * @param  array  $allowed_keys   allowed attribute name map
+     *                                ex: array('border','bgcolor');
+     * @return string                 cleaned attibutes
+     *
+     * WATCH OUT FOR
+     * - event handlers (e.g. onclick="javascript:...", etc)
+     * - CSS (e.g. background: url(javascript:...))
+     * - closing the tag and opening a new one
+     * WHAT IS DONE
+     * - turn all whitespace into ' ' (to protect from removal)
+     * - remove all non-printable characters and < and >
+     * - parse and filter attributes using a whitelist
+     * - styles with 'url' in them are altogether removed
+     * (I know this is brutally aggressive and doesn't allow
+     * some safe stuff, but better safe than sorry.)
+     * NOTE: Attribute values MUST be in quotes now.
+     */
+    function _cleanAttrString($attr='', $allowed_keys) {
+        if (is_null($attr)) return NULL;
+        # Keep spaces simple
+        $attr = trim(preg_replace('/\s+/', ' ', $attr));
+        # Remove non-printable characters and angle brackets
+        $attr = preg_replace('/[<>[:^print:]]+/', '', $attr);
+        # This regular expression parses the value of an attribute and
+        # the quotation marks surrounding it.
+        # It assumes that all quotes within the value itself must be escaped, 
+        # which is not technically true.
+        # To keep the parsing simple (no look-ahead), the value must be in 
+        # quotes.
+        $val = "([\"'`])(?:[^\\\\\"'`]|\\\\.)*\g{-1}";
+
+        $nattr = preg_match_all("/(\w+)\s*=\s*($val)/", $attr, $matches, 
PREG_SET_ORDER);
+        if (!$nattr) return NULL;
+
+        $clean_attr = '';
+        for ($i = 0; $i < $nattr; ++$i) {
+            $m = $matches[$i];
+            $attrname = strtolower($m[1]);
+            $attrval  = $m[2];
+            # allow only recognized attributes
+            if (in_array($attrname, $allowed_keys, true)) {
+                # make sure that style attributes do not have a url in them
+                if ($attrname != 'style' ||
+                      (stristr($attrval, 'url') === FALSE &&
+                      stristr($attrval, 'import') === FALSE)) {
+                    $clean_attr.= " $attrname=$attrval";
+                }
+            }
+        }
+        return $clean_attr;
+    }
+
+}
diff --git a/public_html/lib/plugins/itemtable/syntax.php 
b/public_html/lib/plugins/itemtable/syntax.php
new file mode 100644
index 0000000..c78febd
--- /dev/null
+++ b/public_html/lib/plugins/itemtable/syntax.php
@@ -0,0 +1,227 @@
+<?php
+/**
+ * Plugin itemtable: Renders tables in DokuWiki format by using itemlists 
instead of the Wiki syntax (very helpful for big tables with a lot of text)
+ *
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author     Olaf Trieschmann <trieschm...@otri.de>
+ *
+ * Thanks to Stephen C's plugin "dbtables", which was used as a starting point!
+ */
+
+// must be run within DokuWiki
+if(!defined('DOKU_INC')) die();
+
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once DOKU_PLUGIN.'syntax.php';
+require_once DOKU_INC.'inc/parser/parser.php';
+require_once DOKU_INC . 'inc/parser/xhtml.php';
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class syntax_plugin_itemtable extends DokuWiki_Syntax_Plugin {
+
+    // $options is used for rendering options    
+    public $options=array();
+    
+    function getInfo() {
+        return array('author' => 'Olaf Trieschmann',
+                     'email'  => 'deve...@otri.de',
+                     'date'   => '2010-11-06',
+                     'name'   => 'Item Table',
+                     'desc'   => 'Renders tables in DokuWiki format by using 
itemlists instead of the Wiki syntax',
+                     'url'    => 
'https://github.com/otriesch/itemtable/raw/master/itemtable.zip');
+    }
+    function getType() { return 'substition'; }
+    function getSort() { return 32; }
+
+    function connectTo($mode) {
+        $this->Lexer->addEntryPattern('<itemtable 
*[^>]*>',$mode,'plugin_itemtable');
+    }
+ 
+    function postConnect() {
+        $this->Lexer->addExitPattern('</itemtable>','plugin_itemtable');
+    }
+
+    /**
+     * Handle the match
+     */
+    function handle($match, $state, $pos, &$handler){
+        switch ($state) {
+            case DOKU_LEXER_ENTER : 
+              return array($state, substr($match, 10, -1) );
+              break;
+            case DOKU_LEXER_MATCHED :
+              return array($state,$match);
+              break;
+            case DOKU_LEXER_UNMATCHED :
+              return array($state, $match);
+              break;
+            case DOKU_LEXER_EXIT :
+              return array($state, '');
+              break;
+        }
+        return array();
+    }
+     
+    function render_tables($match,$mode,$data) {
+      // $match is the full text we're to consider
+      $raw=explode("\n",$match);
+    
+//    $TableData.=$this->options["test"];  
+//    foreach($this->options as $option) {
+//      $TableData.=$option." ";
+//    }
+//    $TableData.="\n\n\n";
+               
+      // Yes, so draw the heading
+      if (trim($this->options["header"])!=""){
+       // Draw the Dokuwiki table heading
+       
$TableData.="^".$this->options["header"].substr("^^^^^^^^^^",0,$this->options["cols"]+1)."\n";
+      } else {
+                       $TableData.="";
+      }
+
+      // Draw the descriptors of each field
+      $TableData.="^ ";
+      for($ColPos=0;$ColPos<$this->options["cols"];$ColPos++)
+              $TableData.="^".$this->options["__col"][$ColPos]." ";
+      $TableData.="^\n";
+      
+      for($ColPos=0;$ColPos<$this->options["cols"];$ColPos++) {
+            $RowElements["__col"][$ColPos]=" ";
+      }
+               $RowCount=0;
+               $CellActive=0;
+                     
+      // Run through each line and decide how to render the text      
+      foreach($raw as $rawline) {
+        //In case we have to read a multiline input for one cell
+        if ($CellActive) {
+                        if (strstr($rawline,$this->options["cell_off"])) {
+                               $RowElements["__col"][$CellActive-1].=" 
".substr($rawline,0,strpos($rawline,$this->options["cell_off"]));
+                               $CellActive=0;
+          } else {
+            $RowElements["__col"][$CellActive-1].=" ".$rawline;
+          }
+        } else {
+               $CurrentLine=trim($rawline);
+               if ($CurrentLine!=""){
+                 // Is this row the name of a row?
+                 if (substr($rawline,0,1)==$this->options["thead"]) {
+                   if ($RowCount!=0) {
+                                    // Go through each entity and output it
+                                    
for($ColPos=0;$ColPos<$this->options["cols"];$ColPos++) {
+                                           
$TableData.="|".$RowElements["__col"][$ColPos]."  ";
+                                    }
+                     // SHIP IT!
+                     $TableData.="|\n";
+                   }
+                   // Remember the current row name
+                       $TableData.="|".substr($rawline,1)."  ";
+                       for($ColPos=0;$ColPos<$this->options["cols"];$ColPos++) 
{
+                                 $RowElements["__col"][$ColPos]=" ";
+                               }
+                                       $RowCount++;
+                 } else {
+                   // Split the fields up.
+                   $RowInfo=explode($this->options["fdelim"],$rawline);
+                   if (count($RowInfo)>=2) {
+                         
for($ColPos=0;$ColPos<$this->options["cols"];$ColPos++) {
+                                if 
($RowInfo[0]==$this->options["__col"][$ColPos]) {
+                                                       
$r=substr($rawline,strlen($RowInfo[0])+1);
+                                                       if 
(strstr($r,$this->options["cell_on"])) {
+                                                         
$r=substr(strstr($r,$this->options["cell_on"]),strlen($this->options["cell_on"]));
+                                                         if 
(strstr($r,$this->options["cell_off"])) {
+                                                           
$r=substr($r,0,strpos($r,$this->options["cell_off"]));
+                                                         } else {
+                                                           
$CellActive=$ColPos+1;
+                                                         }
+                                                       } 
+                                  $RowElements["__col"][$ColPos]=$r;
+                                } 
+                                         }
+                   }
+                 }
+               }
+            }
+          }
+      // Go through each entity and output it
+       for($ColPos=0;$ColPos<$this->options["cols"];$ColPos++) {
+                 $TableData.="|".$RowElements["__col"][$ColPos]."  ";
+      }
+      // SHIP IT!
+      $TableData.="|\n";
+      // Start the HTML table rendering
+      $res="</p><table";
+      if ($this->options["twidth"]!="")
+        $res.=" width='".$this->options["twidth"]."'>";
+      else
+        $res.=">";
+        
+      // Prepare the table information
+      // The option to not render from Dokuwiki to HTML is available
+      if ($this->options["norender"]=="")
+        $td="<td 
class='dbtables-td_0'>".p_render($mode,p_get_instructions($TableData),$data)."</td>";
+      else
+        $td="<td><pre>".$TableData."</pre></td>";
+     
+      // Draw the table row
+      $res.="\n<tr class='dbtables-tr_0' valign='top'>\n";
+      // Write out the table data
+      $res.=$td."\n";
+      $CurTablePos=$CurTablePos+1;
+      // Close off the HTML-Table
+      $res.="</tr></table><p>";
+      return $res;
+    }
+    
+    function render($mode, &$renderer, $data) {
+      // This will only render in xhtml
+      if($mode == 'xhtml'){
+         list($state, $match) = $data;
+          switch ($state) {
+              // This happens when we first find the <itemtable>
+              case DOKU_LEXER_ENTER :
+                $parmsexp=explode(';',$match);
+                // Set the relevant default values
+                $this->options["fdelim"]="="; // The character used to delimit 
what goes between fields
+                $this->options["header"]=""; // 
+                $this->options["__col"]=array();
+                $this->options["cell_on"]="<tablecell>";
+                $this->options["cell_off"]="</tablecell>";
+                $this->options["thead"]="_";  // The character used to 
indicate the table name
+                // $this->options["twidth"]  // Default HTML table width in 
HTML specifications (IE: 95% - 960px)
+                // $this->options["norender"] -> Assign a value to NOT render 
from Dokuwiki to HTML
+                
+                // Prepare each option
+//          $this->options["test"]=""; 
+                $this->options["cols"]=0; 
+                foreach($parmsexp as $pexp) {
+                  $p=explode("=",$pexp);
+                  $p[0]=trim($p[0]);
+                  if (substr($p[0],0,1)=="c") {
+                    $pp=explode(",",$p[1]);
+//                     $this->options["test"].=" p[0]=".$p[0]." p[1]=".$p[1]." 
pp[0]=".$pp[0]." pp[1]=".$pp[1]."\\ \n";
+                                                 
$this->options["__col"]=array_merge ($this->options["__col"],$pp);
+                    foreach($pp as $ppexp) {
+                      $this->options["cols"]++;
+                                                 }                    
+                  } else {
+                    $this->options[$p[0]]=$p[1];
+                  }  
+                }
+                break;
+              // This happens each line between <dbtables> and </dbtables>
+              case DOKU_LEXER_UNMATCHED :
+                // Send to the rendering function
+                $renderer->doc.=$this->render_tables($match,$mode,$data);
+                //$renderer->doc .= $renderer->_xmlEntities($match);
+                break;
+          }
+          return true;
+      }
+      return false;
+    }
+}
\ No newline at end of file
diff --git a/public_html/lib/plugins/yalist/LICENSE 
b/public_html/lib/plugins/yalist/LICENSE
new file mode 100644
index 0000000..22fbe5d
--- /dev/null
+++ b/public_html/lib/plugins/yalist/LICENSE
@@ -0,0 +1,339 @@
+GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    {description}
+    Copyright (C) {year}  {fullname}
+
+    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 2 of the License, or
+    (at your option) any later version.
+
+    This program 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.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  {signature of Ty Coon}, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
\ No newline at end of file
diff --git a/public_html/lib/plugins/yalist/README.md 
b/public_html/lib/plugins/yalist/README.md
new file mode 100644
index 0000000..9deb2ce
--- /dev/null
+++ b/public_html/lib/plugins/yalist/README.md
@@ -0,0 +1,19 @@
+dokuwiki-yalist-plugin
+======================
+
+This plugin extends DokuWiki's list markup syntax to allow definition lists
+and list items with multiple paragraphs. The complete syntax is as follows:
+
+```
+  - ordered list item            [<ol><li>]  <!-- as standard syntax -->
+  * unordered list item          [<ul><li>]  <!-- as standard syntax -->
+  ? definition list term         [<dl><dt>]
+  : definition list definition   [<dl><dd>]
+
+  -- ordered list item w/ multiple paragraphs
+  ** unordered list item w/ multiple paragraphs
+  :: definition list definition w/multiple paragraphs
+  .. new paragraph in --, **, or ::
+```
+
+Lists can be nested within lists, just as in the standard DokuWiki syntax.
diff --git a/public_html/lib/plugins/yalist/plugin.info.txt 
b/public_html/lib/plugins/yalist/plugin.info.txt
new file mode 100644
index 0000000..f6edfd4
--- /dev/null
+++ b/public_html/lib/plugins/yalist/plugin.info.txt
@@ -0,0 +1,7 @@
+base    yalist
+author  Mark C. Prins, previously Ben Slusky
+email   mpr...@users.sf.net
+date    2014-05-16
+name    Simple universal list plugin
+desc    Extend DokuWiki list syntax to allow definition list and multiple 
paragraphs in a list entry
+url     https://www.dokuwiki.org/plugin:yalist
\ No newline at end of file
diff --git a/public_html/lib/plugins/yalist/print.css 
b/public_html/lib/plugins/yalist/print.css
new file mode 100644
index 0000000..3f47bf3
--- /dev/null
+++ b/public_html/lib/plugins/yalist/print.css
@@ -0,0 +1,37 @@
+div.dokuwiki dl {
+    margin-bottom: 0.5em;
+    padding: 0;
+}
+
+div.dokuwiki dt {
+    clear: left;
+}
+
+div.dokuwiki .dt {
+    margin-right: 1em;
+    font-weight: bold;
+    max-width: 30%;
+    float: left;
+}
+
+div.dokuwiki .dt,
+div.dokuwiki .dd,
+div.dokuwiki .li {
+    margin-bottom: 0.33em;
+}
+
+div.dokuwiki dd {
+    margin-left: 3em;
+}
+
+div.dokuwiki dl:after,
+div.dokuwiki dl dl:before,
+div.dokuwiki dl ol:before,
+div.dokuwiki dl ul:before {
+    content: '.';
+    display: block;
+    clear: left;
+    width: 0;
+    height: 0;
+    visibility: hidden;
+}
diff --git a/public_html/lib/plugins/yalist/style.css 
b/public_html/lib/plugins/yalist/style.css
new file mode 100644
index 0000000..b4655ee
--- /dev/null
+++ b/public_html/lib/plugins/yalist/style.css
@@ -0,0 +1,37 @@
+div.dokuwiki dl {
+    margin-bottom: 0.5em;
+}
+
+div.dokuwiki dt {
+    clear: left;
+}
+
+div.dokuwiki .dt {
+    margin-right: 1em;
+    color: __text_alt__;
+    font-weight: bold;
+    max-width: 30%;
+    float: left;
+}
+
+div.dokuwiki .dt,
+div.dokuwiki .dd,
+div.dokuwiki .li {
+    margin-bottom: 0.33em;
+}
+
+div.dokuwiki dd {
+    margin-left: 3em;
+}
+
+div.dokuwiki dl:after,
+div.dokuwiki dl dl:before,
+div.dokuwiki dl ol:before,
+div.dokuwiki dl ul:before {
+    content: '.';
+    display: block;
+    clear: left;
+    width: 0;
+    height: 0;
+    visibility: hidden;
+}
diff --git a/public_html/lib/plugins/yalist/syntax.php 
b/public_html/lib/plugins/yalist/syntax.php
new file mode 100644
index 0000000..bc28714
--- /dev/null
+++ b/public_html/lib/plugins/yalist/syntax.php
@@ -0,0 +1,334 @@
+<?php
+/*
+ * This plugin extends DokuWiki's list markup syntax to allow definition lists
+ * and list items with multiple paragraphs. The complete syntax is as follows:
+ *
+ *
+ *   - ordered list item            [<ol><li>]  <!-- as standard syntax -->
+ *   * unordered list item          [<ul><li>]  <!-- as standard syntax -->
+ *   ? definition list term         [<dl><dt>]
+ *   : definition list definition   [<dl><dd>]
+ *
+ *   -- ordered list item w/ multiple paragraphs
+ *   ** unordered list item w/ multiple paragraphs
+ *   :: definition list definition w/multiple paragraphs
+ *   .. new paragraph in --, **, or ::
+ *
+ *
+ * Lists can be nested within lists, just as in the standard DokuWiki syntax.
+ *
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author     Ben Slusky <slus...@paranoiacs.org>
+ *
+ */
+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');
+class syntax_plugin_yalist extends DokuWiki_Syntax_Plugin {
+    var $stack = array();
+    function getType() {
+        return 'container';
+    }
+    function getSort() {
+        // just before listblock (10)
+        return 9;
+    }
+    function getPType() {
+        return 'block';
+    }
+    function getAllowedTypes() {
+        return array('substition', 'protected', 'disabled', 'formatting');
+    }
+    function connectTo($mode) {
+       $this->Lexer->addEntryPattern('\n {2,}(?:--?|\*\*?|\?|::?)', $mode, 
'plugin_yalist');
+       $this->Lexer->addEntryPattern('\n\t{1,}(?:--?|\*\*?|\?|::?)', $mode, 
'plugin_yalist');
+       $this->Lexer->addPattern('\n {2,}(?:--?|\*\*?|\?|::?|\.\.)', 
'plugin_yalist');
+       $this->Lexer->addPattern('\n\t{1,}(?:--?|\*\*?|\?|::?|\.\.)', 
'plugin_yalist');
+    }
+    function postConnect() {
+        $this->Lexer->addExitPattern('\n', 'plugin_yalist');
+    }
+    function handle($match, $state, $pos, &$handler) {
+        $output = array();
+        $level = 0;
+        switch ($state) {
+        case DOKU_LEXER_ENTER:
+            $frame = $this->_interpret_match($match);
+            $level = $frame['level'] = 1;
+            array_push($output,
+                       "${frame['list']}_open",
+                       "${frame['item']}_open",
+                       "${frame['item']}_content_open");
+            if ($frame['paras'])
+                array_push($output, 'p_open');
+            array_push($this->stack, $frame);
+            break;
+        case DOKU_LEXER_EXIT:
+            $close_content = true;
+            while ($frame = array_pop($this->stack)) {
+                // for the first frame we pop off the stack, we'll need to
+                // close the content tag; for the rest it will have been
+                // closed already
+                if ($close_content) {
+                    if ($frame['paras'])
+                        array_push($output, 'p_close');
+                    array_push($output, "${frame['item']}_content_close");
+                    $close_content = false;
+                }
+                array_push($output,
+                           "${frame['item']}_close",
+                           "${frame['list']}_close");
+            }
+            break;
+        case DOKU_LEXER_MATCHED:
+            $last_frame = end($this->stack);
+            if (substr($match, -2) == '..') {
+                // new paragraphs cannot be deeper than the current depth,
+                // but they may be shallower
+                $para_depth = count(explode('  ', str_replace("\t", '  ', 
$match)));
+                $close_content = true;
+                while ($para_depth < $last_frame['depth'] && 
count($this->stack) > 1) {
+                    if ($close_content) {
+                        if ($last_frame['paras'])
+                            array_push($output, 'p_close');
+                        array_push($output, 
"${last_frame['item']}_content_close");
+                        $close_content = false;
+                    }
+                    array_push($output,
+                               "${last_frame['item']}_close",
+                               "${last_frame['list']}_close");
+                    array_pop($this->stack);
+                    $last_frame = end($this->stack);
+                }
+                if ($last_frame['paras']) {
+                    if ($close_content)
+                        // depth did not change
+                        array_push($output, 'p_close', 'p_open');
+                    else
+                        array_push($output,
+                                   "${last_frame['item']}_content_open",
+                                   'p_open');
+                } else {
+                    // let's just pretend we didn't match...
+                    $state = DOKU_LEXER_UNMATCHED;
+                    $output = $match;
+                }
+                break;
+            }
+            $curr_frame = $this->_interpret_match($match);
+            if ($curr_frame['depth'] > $last_frame['depth']) {
+                // going one level deeper
+                $level = $last_frame['level'] + 1;
+                if ($last_frame['paras'])
+                    array_push($output, 'p_close');
+                array_push($output,
+                           "${last_frame['item']}_content_close",
+                           "${curr_frame['list']}_open");
+            } else {
+                // same depth, or getting shallower
+                $close_content = true;
+                // keep popping frames off the stack until we find a frame
+                // that's at least as deep as this one, or until only the
+                // bottom frame (i.e. the initial list markup) remains
+                while ($curr_frame['depth'] < $last_frame['depth'] &&
+                       count($this->stack) > 1)
+                {
+                    // again, we need to close the content tag only for
+                    // the first frame popped off the stack
+                    if ($close_content) {
+                        if ($last_frame['paras'])
+                            array_push($output, 'p_close');
+                        array_push($output, 
"${last_frame['item']}_content_close");
+                        $close_content = false;
+                    }
+                    array_push($output,
+                               "${last_frame['item']}_close",
+                               "${last_frame['list']}_close");
+                    array_pop($this->stack);
+                    $last_frame = end($this->stack);
+                }
+                // pull the last frame off the stack;
+                // it will be replaced by the current frame
+                array_pop($this->stack);
+                $level = $last_frame['level'];
+                if ($close_content) {
+                    if ($last_frame['paras'])
+                        array_push($output, 'p_close');
+                    array_push($output, "${last_frame['item']}_content_close");
+                    $close_content = false;
+                }
+                array_push($output, "${last_frame['item']}_close");
+                if ($curr_frame['list'] != $last_frame['list']) {
+                    // change list types
+                    array_push($output,
+                               "${last_frame['list']}_close",
+                               "${curr_frame['list']}_open");
+                }
+            }
+            // and finally, open tags for the new list item
+            array_push($output,
+                       "${curr_frame['item']}_open",
+                       "${curr_frame['item']}_content_open");
+            if ($curr_frame['paras'])
+                array_push($output, 'p_open');
+            $curr_frame['level'] = $level;
+            array_push($this->stack, $curr_frame);
+            break;
+        case DOKU_LEXER_UNMATCHED:
+            $output = $match;
+            break;
+        }
+        return array('state' => $state, 'output' => $output, 'level' => 
$level);
+    }
+    function _interpret_match($match) {
+        $tag_table = array(
+            '*' => 'u_li',
+            '-' => 'o_li',
+            '?' => 'dt',
+            ':' => 'dd',
+        );
+        $tag = $tag_table[substr($match, -1)];
+        return array(
+            'depth' => count(explode('  ', str_replace("\t", '  ', $match))),
+            'list' => substr($tag, 0, 1) . 'l',
+            'item' => substr($tag, -2),
+            'paras' => (substr($match, -1) == substr($match, -2, 1)),
+        );
+    }
+    function render($mode, &$renderer, $data) {
+        if ($mode != 'xhtml' && $mode != 'latex')
+            return false;
+        if ($data['state'] == DOKU_LEXER_UNMATCHED) {
+            $renderer->doc .= $renderer->_xmlEntities($data['output']);
+            return true;
+        }
+        foreach ($data['output'] as $i) {
+            $markup = '';
+            if ($mode == 'xhtml') {
+                switch ($i) {
+                case 'ol_open':
+                    $markup = "<ol>\n";
+                    break;
+                case 'ol_close':
+                    $markup = "</ol>\n";
+                    break;
+                case 'ul_open':
+                    $markup = "<ul>\n";
+                    break;
+                case 'ul_close':
+                    $markup = "</ul>\n";
+                    break;
+                case 'dl_open':
+                    $markup = "<dl>\n";
+                    break;
+                case 'dl_close':
+                    $markup = "</dl>\n";
+                    break;
+                case 'li_open':
+                    $markup = "<li class=\"level${data['level']}\">";
+                    break;
+                case 'li_content_open':
+                    $markup = "<div class=\"li\">\n";
+                    break;
+                case 'li_content_close':
+                    $markup = "\n</div>";
+                    break;
+                case 'li_close':
+                    $markup = "</li>\n";
+                    break;
+                case 'dt_open':
+                    $markup = "<dt class=\"level${data['level']}\">";
+                    break;
+                case 'dt_content_open':
+                    $markup = "<span class=\"dt\">";
+                    break;
+                case 'dt_content_close':
+                    $markup = "</span>";
+                    break;
+                case 'dt_close':
+                    $markup = "</dt>\n";
+                    break;
+                case 'dd_open':
+                    $markup = "<dd class=\"level${data['level']}\">";
+                    break;
+                case 'dd_content_open':
+                    $markup = "<div class=\"dd\">\n";
+                    break;
+                case 'dd_content_close':
+                    $markup = "\n</div>";
+                    break;
+                case 'dd_close':
+                    $markup = "</dd>\n";
+                    break;
+                case 'p_open':
+                    $markup = "<p>\n";
+                    break;
+                case 'p_close':
+                    $markup = "\n</p>";
+                    break;
+                }
+            } else {
+                // $mode == 'latex'
+                switch ($i) {
+                case 'ol_open':
+                    $markup = "\\begin{enumerate}\n";
+                    break;
+                case 'ol_close':
+                    $markup = "\\end{enumerate}\n";
+                    break;
+                case 'ul_open':
+                    $markup = "\\begin{itemize}\n";
+                    break;
+                case 'ul_close':
+                    $markup = "\\end{itemize}\n";
+                    break;
+                case 'dl_open':
+                    $markup = "\\begin{description}\n";
+                    break;
+                case 'dl_close':
+                    $markup = "\\end{description}\n";
+                    break;
+                case 'li_open':
+                    $markup = "\item ";
+                    break;
+                case 'li_content_open':
+                    break;
+                case 'li_content_close':
+                    break;
+                case 'li_close':
+                    $markup = "\n";
+                    break;
+                case 'dt_open':
+                    $markup = "\item[";
+                    break;
+                case 'dt_content_open':
+                    break;
+                case 'dt_content_close':
+                    break;
+                case 'dt_close':
+                    $markup = "] ";
+                    break;
+                case 'dd_open':
+                    break;
+                case 'dd_content_open':
+                    break;
+                case 'dd_content_close':
+                    break;
+                case 'dd_close':
+                    $markup = "\n";
+                    break;
+                case 'p_open':
+                    $markup = "\n";
+                    break;
+                case 'p_close':
+                    $markup = "\n";
+                    break;
+                }
+            }
+            $renderer->doc .= $markup;
+        }
+        if ($data['state'] == DOKU_LEXER_EXIT)
+            $renderer->doc .= "\n";
+        return true;
+    }
+}
\ No newline at end of file

-- 


Reply via email to