1<?php
2
3
4use ComboStrap\PluginUtility;
5use ComboStrap\TagAttributes;
6use ComboStrap\XmlTagProcessing;
7
8
9/**
10 * Class syntax_plugin_combo_list
11 * Implementation of a list
12 *
13 * This component is not not public
14 *
15 */
16class syntax_plugin_combo_contentlistitem extends DokuWiki_Syntax_Plugin
17{
18
19    const DOKU_TAG = "contentlistitem";
20    const MARKI_TAG = "content-list-item";
21    const ALL_TAGS = array(self::MARKI_TAG, "list-item", "li");
22    const LIST_GROUP_ITEM_CLASS = "list-group-item";
23
24
25    /**
26     * Syntax Type.
27     *
28     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
29     * @see https://www.dokuwiki.org/devel:syntax_plugins#syntax_types
30     * @see DokuWiki_Syntax_Plugin::getType()
31     */
32    function getType()
33    {
34        return 'container';
35    }
36
37    /**
38     * How Dokuwiki will add P element
39     *
40     * * 'normal' - Inline
41     *  * 'block' - Block (p are not created inside)
42     *  * 'stack' - Block (p can be created inside)
43     *
44     * @see DokuWiki_Syntax_Plugin::getPType()
45     * @see https://www.dokuwiki.org/devel:syntax_plugins#ptype
46     */
47    function getPType()
48    {
49        /**
50         * No paragraph inside, this is a layout
51         */
52        return 'block';
53    }
54
55    public function accepts($mode)
56    {
57        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
58    }
59
60
61    /**
62     * @return array
63     * Allow which kind of plugin inside
64     *
65     * No one of array('baseonly','container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
66     * because we manage self the content and we call self the parser
67     *
68     * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php
69     */
70    function getAllowedTypes()
71    {
72        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
73    }
74
75    /**
76     * @see Doku_Parser_Mode::getSort()
77     * the mode with the lowest sort number will win out
78     * Higher than {@link syntax_plugin_combo_contentlist}
79     * but less than {@link syntax_plugin_combo_preformatted}
80     */
81    function getSort()
82    {
83        return 18;
84    }
85
86
87    function connectTo($mode)
88    {
89
90        /**
91         * This is now know as `row`
92         * This is the old tags
93         */
94        foreach (self::ALL_TAGS as $tag) {
95            $pattern = XmlTagProcessing::getContainerTagPattern($tag);
96            $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
97        }
98
99
100    }
101
102    public function postConnect()
103    {
104        foreach (self::ALL_TAGS as $tag) {
105            $this->Lexer->addExitPattern('</' . $tag . '>', PluginUtility::getModeFromTag($this->getPluginComponent()));
106        }
107
108    }
109
110
111    /**
112     *
113     * The handle function goal is to parse the matched syntax through the pattern function
114     * and to return the result for use in the renderer
115     * This result is always cached until the page is modified.
116     * @param string $match
117     * @param int $state
118     * @param int $pos - byte position in the original source file
119     * @param Doku_Handler $handler
120     * @return array|bool
121     * @see DokuWiki_Syntax_Plugin::handle()
122     *
123     */
124    function handle($match, $state, $pos, Doku_Handler $handler)
125    {
126
127        switch ($state) {
128
129            case DOKU_LEXER_ENTER :
130
131                $attributes = TagAttributes::createFromTagMatch($match);
132                $tag = PluginUtility::getMarkupTag($match);
133                return array(
134                    PluginUtility::STATE => $state,
135                    PluginUtility::ATTRIBUTES => $attributes->toCallStackArray(),
136                    PluginUtility::PAYLOAD=>$tag
137                );
138
139            case DOKU_LEXER_UNMATCHED :
140                return PluginUtility::handleAndReturnUnmatchedData(self::DOKU_TAG, $match, $handler);
141
142            case DOKU_LEXER_EXIT :
143
144                return array(
145                    PluginUtility::STATE => $state
146                );
147
148
149        }
150        return array();
151
152    }
153
154    /**
155     * Render the output
156     * @param string $format
157     * @param Doku_Renderer $renderer
158     * @param array $data - what the function handle() return'ed
159     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
160     * @see DokuWiki_Syntax_Plugin::render()
161     *
162     *
163     */
164    function render($format, Doku_Renderer $renderer, $data)
165    {
166
167        /**
168         * The normal flow is that the `row` in a content
169         * list are transformed to `content-list-item` in the {@link DOKU_LEXER_EXIT} state
170         * of {@link syntax_plugin_combo_contentlist::handle()}
171         *
172         */
173        if ($format == 'xhtml') {
174
175            /** @var Doku_Renderer_xhtml $renderer */
176            $state = $data[PluginUtility::STATE];
177            switch ($state) {
178                case DOKU_LEXER_ENTER :
179                    $tagAttributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES], self::MARKI_TAG);
180                    $tagAttributes->addClassName(self::LIST_GROUP_ITEM_CLASS);
181                    $renderer->doc .= $tagAttributes->toHtmlEnterTag("li");
182                    break;
183                case DOKU_LEXER_EXIT :
184                    $renderer->doc .= "</li>" . DOKU_LF;
185                    break;
186                case DOKU_LEXER_UNMATCHED :
187                    $render = PluginUtility::renderUnmatched($data);
188                    if (!empty($render)) {
189                        $renderer->doc .= "<span>" . $render . '</span>';
190                    }
191                    break;
192            }
193            return true;
194        }
195
196        // unsupported $mode
197        return false;
198    }
199
200
201}
202
203