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