DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:yalist

yalist plugin

Compatible with DokuWiki

  • 2013-12-08 "Binky" unknown
  • 2013-05-10 "Weatherwax" yes
  • 2012-10-13 "Adora Belle" yes
  • 2012-01-25 "Angua" yes

plugin Simple universal list plugin

Last updated on
2008-07-08
Provides
Syntax
Conflicts with
fckg, fckglite, indexmenu2, navi

Overview

There are many list syntax plugins (see the list of similar plugins above), but this one is mine. I created it because I am not happy with any of the others:

  • Only lists and deflist allow paragraph breaks within list items, but their syntax is radically different from the standard DokuWiki syntax for lists. Worse, the syntax that each plugin introduces for list item terminators differs from the other.1)
  • definitions and definitionlist do not allow nested definition lists.
  • deflist and dl allow nested definition lists, and un/ordered lists nested in definition lists,2) but neither one properly uses the “class=levelN” style to mark the depth of a list item, as the standard DokuWiki list handler does.
  • deflist and dl automatically create a “bookmark” for each definition list term, which introduces a new requirement that definition list terms be unique within a document. This is IMO not a good idea.

My goal in creating yalist was to integrate definition lists into the existing nestable list handler, and to allow list items to contain multiple paragraphs, while maintaining syntax- and output-level compatibility with the existing list handler. yalist achieves this by preempting DokuWiki's list handler, replacing it with a new handler and renderer that render the standard list syntax exactly as DokuWiki would.

Syntax

  - 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 by indenting them further, just as in the standard DokuWiki syntax.

Example

The following DokuWiki source:

  - Ordered list item 1
  - Ordered list item 2
  -- Ordered list item 3...
  .. ... in multiple paragraphs
  - Ordered list item 4

  * Unordered list item
  ** Unordered list item...
  .. ... in multiple paragraphs

  - Ordered list, first level
    - Second level
      - Third level
        - Fourth level
    -- Back to second level
      - //Second?! What happened to third?//
    .. //Quiet, you.//
  - Back to first level
  - Still at first level

  ? Definition list
  : Definition lists vary only slightly from other types of lists in that list items consist of two parts: a term and a description. The term is given by the DT element and is restricted to inline content. The description is given with a DD element that contains block-level content. [Source: W3C]
  ? Definition list w/ multiple paragraphs
  :: The style sheet provided with this plugin will render these paragraphs...
  .. ... to the left of the term being defined.
    ? Definition list w/ multiple "paragraphs"
    : Another way to separate blocks of text in a definition...
    : ... is to simply have multiple definitions for a term (or group of terms).

  : This definition list has DD tags without any preceding DT tags.
  : Hey, it's legal XHTML.
  ? Just like DT tags without following DD tags.
  ?? But DT tags can't contain paragraphs. That would __not__ be legal XHTML.
  .. If you try, the result will be rendered oddly.

… is rendered in XHTML as follows:

<ol>
<li class="level1"><div class="li">
 Ordered list item 1
</div></li>
<li class="level1"><div class="li">
 Ordered list item 2
</div></li>
<li class="level1"><div class="li">
<p>
 Ordered list item 3&hellip;
</p><p>
 &hellip; in multiple paragraphs
</p>
</div></li>
<li class="level1"><div class="li">
 Ordered list item 4
</div></li>
</ol>
 
<ul>
<li class="level1"><div class="li">
 Unordered list item
</div></li>
<li class="level1"><div class="li">
<p>
 Unordered list item&hellip;
</p><p>
 &hellip; in multiple paragraphs
</p>
</div></li>
</ul>
 
<ol>
<li class="level1"><div class="li">
 Ordered list, first level
</div><ol>
<li class="level2"><div class="li">
 Second level
</div><ol>
<li class="level3"><div class="li">
 Third level
</div><ol>
<li class="level4"><div class="li">
 Fourth level
</div></li>
</ol>
</li>
</ol>
</li>
<li class="level2"><div class="li">
<p>
 Back to second level
</p>
</div><ol>
<li class="level3"><div class="li">
 <em>Second?! What happened to third?</em>
</div></li>
</ol>
<div class="li">
<p>
 <em>Quiet, you.</em>
</p>
</div></li>
</ol>
</li>
<li class="level1"><div class="li">
 Back to first level
</div></li>
<li class="level1"><div class="li">
 Still at first level
</div></li>
</ol>
 
<dl>
<dt class="level1"><span class="dt"> Definition list</span></dt>
<dd class="level1"> Definition lists vary only slightly from other types of lists in that list items consist of two parts: a term and a description. The term is given by the DT element and is restricted to inline content. The description is given with a DD element that contains block-level content. [Source: <acronym title="World Wide Web Consortium">W3C</acronym>]</dd>
<dt class="level1"><span class="dt"> Definition list w/ multiple paragraphs</span></dt>
<dd class="level1"><p>
 The style sheet provided with this plugin will render these paragraphs&hellip;
</p><p>
 &hellip; to the left of the term being defined.
</p><dl>
<dt class="level2"><span class="dt"> Definition list w/ multiple “paragraphs”</span></dt>
<dd class="level2"> Another way to separate blocks of text in a definition&hellip;</dd>
<dd class="level2"> &hellip; is to simply have multiple definitions for a term (or group of terms).</dd>
</dl>
</dd>
</dl>
 
<dl>
<dd class="level1"> This definition list has DD tags without any preceding DT tags.</dd>
<dd class="level1"> Hey, it&#039;s legal <acronym title="Extensible HyperText Markup Language">XHTML</acronym>.</dd>
<dt class="level1"><span class="dt"> Just like DT tags without following DD tags.</span></dt>
<dt class="level1"><span class="dt">? But DT tags can&#039;t contain paragraphs. That would <em class="u">not</em> be legal <acronym title="Extensible HyperText Markup Language">XHTML</acronym>.
  .. If you try, the result will be rendered oddly.</span></dt>
</dl>

Installation

Usual procedure. Download the plugin from http://www.paranoiacs.org/~sluskyb/hacks/dokuwiki/yalist/ in .ZIP or .tar.gz format; unpack it manually or use the plugin manager; or copy and paste the source files below.

Source Code

syntax.php

syntax.php
<?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 <sluskyb@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 getInfo() {
        return array(
            'author' => 'Ben Slusky',
            'email'  => 'sluskyb@paranoiacs.org',
            'date'   => '2007-11-02',
            'name'   => 'Simple universal list plugin',
            'desc'   => 'Extend DokuWiki list syntax to allow definition list and multiple paragraphs in a list entry',
            'url'    => 'http://www.dokuwiki.org/plugin:yalist',
        );
    }
 
    function getType() {
        return 'container';
    }
 
    function getSort() {
        return 9;  // just before listblock (10)
    }
 
    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;
    }
}

style.css

style.css
/* plugin: yalist */
 
div.dokuwiki ul,
div.dokuwiki ol {
    //line-height: 1em;
}
 
div.dokuwiki dl {
    //line-height: 1em;
    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;
}
 
/* end plugin: yalist */

Discussion

Updated with bugfixes and enhancements. In the unlikely event that anyone downloaded this plugin already, try it again now. — Ben Slusky 2007-11-10 02:30

FIXME Great idea but seems to be buggy. Once I installed the plugin all bullets are treated as new lists. Basically if I have

  * Item 1
  * Item 2
  * Item 3

The plugin will interpret them as if I wrote

  * Item 1
    * Item 2
      * Item 3

Worse than that, it seems to break all \[\[ \]\] interwiki links

Bulleted lists and interwiki links both work for me… do you have a public site I can look at? — Ben Slusky 2007-11-24 23:39

FIXME Ben, this seems to be almost exactly the right solution, but there's one thing it doesn't do correctly. I want to write

  * First level
  ** First level
    * Second level
    * Second level
  .. continuing the last first level point

but this doesn't work: the .. isn't interpreted, and just becomes part of the last second-level bullet. It seems that the continuation context of the first level is lost in the transition to the second level. I can continue a second level bullet, but to go back to the first level I have to start a new bullet.

Any chance of this being corrected any time soon? Thanks, Andrew.

Maybe the ClearFloat Outdent plugin can do some good for this thingy you describe… It's just an idea LOL so please don't hang me on it. HTH
Mischa The Evil 2008/06/11 18:38
Fixed in the latest version. — Ben Slusky 2008-07-08 02:02
Works—thanks! Andrew

FIXME I also wanted to be able to use markup provided by DokuWiki Core (DWC) and some DokuWiki Plugins (DWP's) of the mode type container3) but that wasn't possible due to the fact that yalist doesn't allow markup provided by DWC and DWP's which are of the mode type container.

This can be changed easily by adding the container-mode type as a new (additional) argument of the method getAllowedTypes(), which itself returns an array of mode types that may be nested within yalist's own markup.
This change can be applied by modifying line 56 from

        return array('substition', 'protected', 'disabled', 'formatting');

to

        return array('container', 'substition', 'protected', 'disabled', 'formatting');

I haven't noticed any unwanted behaviour afterwards, but YMMV ;-)

Mischa The Evil 2008/06/11 22:54

Hm… I think this would result in invalid XHTML, so it's not going in. Sorry. — Ben Slusky 2008-07-08 02:14

Updated on 8 July 2008 to add support for LaTeX output (thanks to Michael Strey) and fix a formatting error when ”..” is shallower than the preceding list markup. — Ben Slusky 2008-07-28 02:25


Where would I modify the code to allow the plugin to interpret ”#” as an ordered list (ideally in addition to ”-”, but instead of will do too)? — Ashtagon 2011-Aug-8.


First, thanks for this great plugin. I've just added ODT support and created a diff using WinMerge. So now let's put this plugin on the ODT Initiative / ODT Render Support page. :-)Tobias KandziaTobias Kandzia
kandzia

2013/06/28 09:05

You need the following formatting styles in your template:

  • “Nummerierung 1 X” for ordered list item (<ol><li>)
  • “Aufzählung 1 X” for unordered list item (<ul><li>)
  • “Aufzählung 2 X” for key or definition list term (<dl><dt>)
  • “Aufzählung 3 X” for value or definition list definition (<dl><dd>)

(style names using a german OpenOffice, X = “Anfang”, “Fortsetzung”, “Ende”)
Btw: I have almost no experience using definition lists in OpenOffice. If there is a recommended way to do them, let me know. I used two styles for the definition list to control alternative indenting and e.g. bold font for the term.

254c254
<         if ($mode != 'xhtml' && $mode != 'latex')
---
>         if ($mode != 'xhtml' && $mode != 'latex' && $mode != 'odt')
262c262,265
<         foreach ($data['output'] as $i) {
---
>         $startOfList = $data['state'] == DOKU_LEXER_ENTER;
>         $endOfList = $data['state'] == DOKU_LEXER_EXIT;
>         $output = $data['output'];
>         foreach ($output as $i) {
316c319
<             } else {  // $mode == 'latex'
---
>             } else if ($mode == 'latex') {
353a357,432
>                 }
>             } else if ($mode == 'odt') {
>                 switch ($i) {
>                 case 'ol_open':
>                     $this->style = "Numbering_20_1";
>                     $markup = '<text:list text:style-name="'.$this->style.'">';
>                     break;
>                 case 'ul_open':
>                     $this->style = "List_20_1";
>                     $markup = '<text:list text:style-name="'.$this->style.'">';
>                     break;
>                 case 'dl_open':
>                     $this->style = "List_20_2";
>                     $markup = '<text:list text:style-name="'.$this->style.'">';
>                     break;
>                 case 'ol_close':
>                 case 'ul_close':
>                 case 'dl_close':
>                     $markup = '</text:list>';
>                     if ($endOfList) {
>                         $cut = strripos($renderer->doc,'<text:p text:style-name=');
>                         $lastItem = substr($renderer->doc,$cut);
>                         $renderer->doc = substr($renderer->doc,0,$cut);
>                         $renderer->doc .= preg_replace('/(.*?text:style-name="'.$this->style.')(.*?)(">.*?)/','\1_20_End\3',$lastItem);
>                     }
>                     $this->listHeader = false;
>                     break;
> 
>                 case 'li_open':             
>                     $markup = '<text:list-item>';
>                     break;
>                 case 'li_content_open':
>                     if (array_search($i,$output) < count($output)-1) break;
>                     $style = $this->style . ($startOfList ? '_20_Start' : '_20_Cont.');
>                     $markup = '<text:p text:style-name="'.$style.'">';
>                     break;
>                 case 'li_content_close':    
>                     if (array_search($i,$output) > 0) break;
>                     $markup = '</text:p>'; break;
>                 case 'li_close':
>                     $markup = '</text:list-item>';
>                     break;
> 
>                 case 'dt_open': // unconditional: DT tags can't contain paragraphs. That would not be legal XHTML.
>                     $markup = '<text:list-item>';
>                     break;
>                 case 'dd_open':
>                     if (in_array("dt_close",$output) || in_array("dd_close",$output)) break; // continue with paragraphs
>                     $this->listHeader = $startOfList;
>                     $markup = $this->listHeader ? '<text:list-header>' : '<text:list-item>';
>                     break;
>                 case 'dt_content_open':
>                     $this->style = "List_20_2";
>                     if (array_search($i,$output) < count($output)-1) break;
>                     $style = $this->style . ($startOfList ? '_20_Start' : '_20_Cont.');
>                     $markup = '<text:p text:style-name="'.$style.'">';
>                     break;
>                 case 'dd_content_open':
>                     $this->style = "List_20_3";
>                     if (array_search($i,$output) < count($output)-1) break;
>                     $style = $this->style . ($startOfList ? '_20_Start' : '_20_Cont.');
>                     $markup = '<text:p text:style-name="'.$style.'">';
>                     break;
>                 case 'dt_content_close':
>                 case 'dd_content_close':
>                     if (array_search($i,$output) > 0) break;
>                     $markup = '</text:p>'; break;
>                 case 'dt_close':
>                 case 'dd_close':
>                     if (in_array("dd_open",$output)) break; // continue with paragraphs
>                     $markup = $this->listHeader ? '</text:list-header>' : '</text:list-item>';
>                     $this->listHeader = false;
>                     break;
> 
>                 case 'p_open':              $markup = '<text:p text:style-name="'.$this->style.'_20_Cont.">'; break;
>                 case 'p_close':             $markup = '</text:p>'; break;

Tobias KandziaTobias Kandzia
kandzia

2013/06/28 09:05

1) Which is especially strange, since they were written by the same author.
2) lists and deflist in combination allow arbitrary nesting of lists.
plugin/yalist.txt · Last modified: 2013/10/22 09:25 by 213.244.167.136