xref: /plugin/combo/syntax/label.php (revision 5f891b7e09648e05e78f5882f3fdde1e9df9b0f1)
1<?php
2
3// implementation of
4// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite
5
6// must be run within Dokuwiki
7use ComboStrap\HeaderUtility;
8use ComboStrap\LogUtility;
9use ComboStrap\TitleUtility;
10use ComboStrap\PluginUtility;
11use ComboStrap\StringUtility;
12use ComboStrap\Tag;
13
14require_once(__DIR__ . '/../class/HeaderUtility.php');
15
16if (!defined('DOKU_INC')) die();
17
18
19class syntax_plugin_combo_label extends DokuWiki_Syntax_Plugin
20{
21
22
23    const TAG = "label";
24
25    /**
26     * The id of the heading element for a accordion label
27     */
28    const HEADING_ID = "headingId";
29    /**
30     * The id of the collapsable target
31     */
32    const TARGET_ID = "targetId";
33
34    /**
35     * An indicator attribute that tells if the accordion is collpased or not
36     */
37    const COLLAPSED = "collapsed";
38
39    function getType()
40    {
41        return 'formatting';
42    }
43
44    /**
45     * How Dokuwiki will add P element
46     *
47     *  * 'normal' - The plugin can be used inside paragraphs (inline)
48     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
49     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
50     *
51     * @see DokuWiki_Syntax_Plugin::getPType()
52     */
53    function getPType()
54    {
55        return 'normal';
56    }
57
58    function getAllowedTypes()
59    {
60        return array('substition', 'formatting', 'disabled');
61    }
62
63    function getSort()
64    {
65        return 201;
66    }
67
68
69    function connectTo($mode)
70    {
71
72        $this->Lexer->addEntryPattern(PluginUtility::getContainerTagPattern(self::TAG), $mode, PluginUtility::getModeForComponent($this->getPluginComponent()));
73    }
74
75    public function postConnect()
76    {
77        $this->Lexer->addExitPattern('</' . self::TAG . '>', PluginUtility::getModeForComponent($this->getPluginComponent()));
78    }
79
80    function handle($match, $state, $pos, Doku_Handler $handler)
81    {
82
83        switch ($state) {
84
85            case DOKU_LEXER_ENTER:
86                $tagAttributes = PluginUtility::getTagAttributes($match);
87
88                $tag = new Tag(self::TAG, $tagAttributes, $state, $handler);
89                $parentTag = $tag->getParent();
90                $context = null;
91                if ($parentTag != null) {
92                    $grandfather = $parentTag->getParent();
93                    if ($grandfather != null) {
94                        $grandFatherName = $grandfather->getName();
95                        switch ($grandFatherName) {
96                            case syntax_plugin_combo_accordion::TAG:
97                                $id = $parentTag->getAttribute("id");
98                                $tagAttributes["id"] = $id;
99                                $tagAttributes[self::HEADING_ID] = "heading" . ucfirst($id);
100                                $tagAttributes[self::TARGET_ID] = "collapse" . ucfirst($id);
101                                $parentAttribute = $parentTag->getAttributes();
102                                if (!key_exists(self::COLLAPSED, $parentAttribute)) {
103                                    // Accordion are collapsed by default
104                                    $tagAttributes[self::COLLAPSED] = "true";
105                                } else {
106                                    $tagAttributes[self::COLLAPSED] = $parentAttribute[self::COLLAPSED];
107                                }
108                                $context = syntax_plugin_combo_accordion::TAG;
109                                break;
110                            case  syntax_plugin_combo_tabs::TAG:
111                                $context = syntax_plugin_combo_tabs::TAG;
112                                $tagAttributes = $parentTag->getAttributes();
113                                break;
114                            default:
115                                LogUtility::log2FrontEnd("The label is included in the $grandFatherName component and this is unexpected", LogUtility::LVL_MSG_WARNING, self::TAG);
116                        }
117                    }
118                }
119
120                return array(
121                    PluginUtility::STATE => $state,
122                    PluginUtility::ATTRIBUTES => $tagAttributes,
123                    PluginUtility::CONTEXT => $context
124                );
125
126            case DOKU_LEXER_UNMATCHED :
127                return array(
128                    PluginUtility::STATE => $state,
129                    PluginUtility::PAYLOAD => $match
130                );
131
132            case DOKU_LEXER_EXIT :
133                $tag = new Tag(self::TAG, array(), $state, $handler);
134                $openingTag = $tag->getOpeningTag();
135                $context = $openingTag->getContext();
136                return array(
137                    PluginUtility::STATE => $state,
138                    PluginUtility::CONTEXT => $context,
139                    PluginUtility::ATTRIBUTES => $openingTag->getAttributes()
140                );
141
142
143        }
144        return array();
145
146    }
147
148    /**
149     * Render the output
150     * @param string $format
151     * @param Doku_Renderer $renderer
152     * @param array $data - what the function handle() return'ed
153     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
154     * @see DokuWiki_Syntax_Plugin::render()
155     *
156     *
157     */
158    function render($format, Doku_Renderer $renderer, $data)
159    {
160
161        if ($format == 'xhtml') {
162
163            /** @var Doku_Renderer_xhtml $renderer */
164            $state = $data[PluginUtility::STATE];
165            switch ($state) {
166
167                case DOKU_LEXER_ENTER:
168
169                    $context = $data[PluginUtility::CONTEXT];
170                    switch ($context) {
171                        case syntax_plugin_combo_accordion::TAG:
172                            $attribute = $data[PluginUtility::ATTRIBUTES];
173                            $headingId = $attribute[self::HEADING_ID];
174                            $collapseId = $attribute[self::TARGET_ID];
175                            $collapsed = $attribute[self::COLLAPSED];
176                            if ($collapsed == "false") {
177                                $collapsedClass = "collapsed";
178                            } else {
179                                $collapsedClass = "";
180                            }
181                            $renderer->doc .= "<div class=\"card-header\" id=\"$headingId\">" . DOKU_LF;
182                            $renderer->doc .= "<h2 class=\"mb-0\">";
183                            $renderer->doc .= "<button class=\"btn btn-link btn-block text-left $collapsedClass\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$collapseId\" aria-expanded=\"true\" aria-controls=\"$collapseId\">";
184                            break;
185                        case  syntax_plugin_combo_tabs::TAG:
186                            $attributes = $data[PluginUtility::ATTRIBUTES];
187                            $renderer->doc .= syntax_plugin_combo_tabs::openNavigationalTabElement($attributes);
188                            break;
189                        default:
190                            LogUtility::log2FrontEnd("The context ($context) of the label is unknown in exit", LogUtility::LVL_MSG_WARNING, self::TAG);
191                    }
192                    break;
193
194                case DOKU_LEXER_UNMATCHED :
195                    $renderer->doc .= PluginUtility::escape($data[PluginUtility::PAYLOAD]);
196                    break;
197
198                case DOKU_LEXER_EXIT:
199                    $context = $data[PluginUtility::CONTEXT];
200                    switch ($context) {
201                        case syntax_plugin_combo_accordion::TAG:
202                            $attribute = $data[PluginUtility::ATTRIBUTES];
203                            $collapseId = $attribute[self::TARGET_ID];
204                            $headingId = $attribute[self::HEADING_ID];
205                            $collapsed = $attribute[self::COLLAPSED];
206                            if ($collapsed == "false") {
207                                $showClass = "show";
208                            } else {
209                                $showClass = "";
210                            }
211                            $renderer->doc .= "</button></h2></div>";
212                            $renderer->doc .= "<div id=\"$collapseId\" class=\"collapse $showClass\" aria-labelledby=\"$headingId\" data-parent=\"#$headingId\">";
213                            $renderer->doc .= "<div class=\"card-body\">" . DOKU_LF;
214                            break;
215                        case  syntax_plugin_combo_tabs::TAG:
216                            $renderer->doc .= syntax_plugin_combo_tabs::closeNavigationalTabElement();
217                            break;
218                        default:
219                            LogUtility::log2FrontEnd("The context ($context) of the label is unknown in exit", LogUtility::LVL_MSG_WARNING, self::TAG);
220
221                    }
222                    break;
223
224
225            }
226        }
227        // unsupported $mode
228        return false;
229    }
230
231
232}
233
234