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