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>{|</code> | table start | +|<code>{+</code> | table caption | +|<code>{-</code> | table row | +|<code>!</code> | table header | +|<code>|</code> | table data | +|<code>|}</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 --