xref: /plugin/combo/syntax/accordion.php (revision 21913ab3235d516e2fa19c7e3929b555b3a2bda1)
1<?php
2/**
3 * DokuWiki Syntax Plugin Combostrap.
4 *
5 */
6
7use ComboStrap\PluginUtility;
8use ComboStrap\Tag;
9use ComboStrap\TagAttributes;
10
11if (!defined('DOKU_INC')) {
12    die();
13}
14
15if (!defined('DOKU_PLUGIN')) {
16    define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
17}
18
19require_once(__DIR__ . '/../class/PluginUtility.php');
20
21/**
22 * All DokuWiki plugins to extend the parser/rendering mechanism
23 * need to inherit from this class
24 *
25 * The name of the class must follow a pattern (don't change it)
26 * ie:
27 *    syntax_plugin_PluginName_ComponentName
28 *
29 * https://getbootstrap.com/docs/4.6/components/collapse/#accordion-example
30 *
31 * Ter info:
32 * https://jqueryui.com/accordion/
33 */
34class syntax_plugin_combo_accordion extends DokuWiki_Syntax_Plugin
35{
36
37
38    const TAG = 'accordion';
39
40    /**
41     * @var int a counter to give an id to the accordion card
42     */
43    private $accordionCounter = 0;
44
45    /**
46     * Syntax Type.
47     *
48     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
49     * @see DokuWiki_Syntax_Plugin::getType()
50     */
51    function getType()
52    {
53        return 'container';
54    }
55
56    /**
57     * @return array
58     * Allow which kind of plugin inside
59     *
60     * One of array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
61     * 'baseonly' will run only in the base mode
62     * because we manage self the content and we call self the parser
63     *
64     * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php
65     */
66    public function getAllowedTypes()
67    {
68        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
69    }
70
71    public function accepts($mode)
72    {
73        /**
74         * header mode is disable to take over
75         * and replace it with {@link syntax_plugin_combo_title}
76         */
77        if ($mode == "header") {
78            return false;
79        }
80        /**
81         *
82         */
83        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
84
85    }
86
87    /**
88     * How Dokuwiki will add P element
89     *
90     * * 'normal' - The plugin can be used inside paragraphs
91     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
92     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
93     *
94     * @see DokuWiki_Syntax_Plugin::getPType()
95     */
96    function getPType()
97    {
98        return 'block';
99    }
100
101    /**
102     * @see Doku_Parser_Mode::getSort()
103     * Higher number than the teaser-columns
104     * because the mode with the lowest sort number will win out
105     */
106    function getSort()
107    {
108        return 200;
109    }
110
111    /**
112     * Create a pattern that will called this plugin
113     *
114     * @param string $mode
115     * @see Doku_Parser_Mode::connectTo()
116     */
117    function connectTo($mode)
118    {
119
120
121        $pattern = PluginUtility::getContainerTagPattern(self::TAG);
122        $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeForComponent($this->getPluginComponent()));
123
124
125    }
126
127    public function postConnect()
128    {
129
130
131        $this->Lexer->addExitPattern('</' . self::TAG . '>', PluginUtility::getModeForComponent($this->getPluginComponent()));
132
133
134    }
135
136    /**
137     *
138     * The handle function goal is to parse the matched syntax through the pattern function
139     * and to return the result for use in the renderer
140     * This result is always cached until the page is modified.
141     * @param string $match
142     * @param int $state
143     * @param int $pos
144     * @param Doku_Handler $handler
145     * @return array|bool
146     * @see DokuWiki_Syntax_Plugin::handle()
147     *
148     */
149    function handle($match, $state, $pos, Doku_Handler $handler)
150    {
151
152        switch ($state) {
153
154            case DOKU_LEXER_ENTER:
155
156                $this->accordionCounter++;
157                $attributes = PluginUtility::getTagAttributes($match);
158
159                // Attributes has at
160                // https://getbootstrap.com/docs/4.6/components/collapse/#accordion-example
161                PluginUtility::addClass2Attributes("accordion", $attributes);
162                if (!in_array("id", $attributes)) {
163                    $attributes["id"] = self::TAG . $this->accordionCounter;
164                }
165
166                return array(
167                    PluginUtility::STATE => $state,
168                    PluginUtility::ATTRIBUTES => $attributes
169                );
170
171            case DOKU_LEXER_UNMATCHED :
172
173                return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler);
174
175
176            case DOKU_LEXER_EXIT :
177
178                return array(
179                    PluginUtility::STATE => $state
180                );
181
182
183        }
184
185        return array();
186
187    }
188
189    /**
190     * Render the output
191     * @param string $format
192     * @param Doku_Renderer $renderer
193     * @param array $data - what the function handle() return'ed
194     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
195     * @see DokuWiki_Syntax_Plugin::render()
196     *
197     *
198     */
199    function render($format, Doku_Renderer $renderer, $data)
200    {
201
202        if ($format == 'xhtml') {
203
204            /** @var Doku_Renderer_xhtml $renderer */
205            $state = $data[PluginUtility::STATE];
206            switch ($state) {
207                case DOKU_LEXER_ENTER:
208                    $attributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES]);
209                    $renderer->doc .= $attributes->toHtmlEnterTag("div") . DOKU_LF;
210                    break;
211                case DOKU_LEXER_UNMATCHED:
212                    $renderer->doc .= PluginUtility::renderUnmatched($data);
213                    break;
214                case DOKU_LEXER_EXIT:
215                    $renderer->doc .= '</div>' . DOKU_LF;
216                    break;
217            }
218
219
220            return true;
221        }
222        return false;
223    }
224
225
226}
227