1<?php
2/**
3 * DokuWiki Syntax Plugin Combostrap.
4 *
5 */
6
7use ComboStrap\Bootstrap;
8use ComboStrap\NavBarUtility;
9use ComboStrap\PluginUtility;
10use ComboStrap\XmlTagProcessing;
11
12
13require_once(__DIR__ . '/../vendor/autoload.php');
14
15
16/**
17 * All DokuWiki plugins to extend the parser/rendering mechanism
18 * need to inherit from this class
19 *
20 * The name of the class must follow a pattern (don't change it)
21 * ie:
22 *    syntax_plugin_PluginName_ComponentName
23 *
24 * A navbar group is a navbar nav
25 */
26class syntax_plugin_combo_navbargroup extends DokuWiki_Syntax_Plugin
27{
28
29    const TAG = "group";
30    const COMPONENT = "navbargroup";
31
32    /**
33     * Syntax Type.
34     *
35     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
36     * @see DokuWiki_Syntax_Plugin::getType()
37     */
38    function getType()
39    {
40        return 'container';
41    }
42
43    /**
44     * @return array
45     * Allow which kind of plugin inside
46     * All
47     */
48    public function getAllowedTypes(): array
49    {
50        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
51    }
52
53    /**
54     * How Dokuwiki will add P element
55     *
56     *  * 'normal' - The plugin can be used inside paragraphs
57     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
58     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
59     *
60     * @see DokuWiki_Syntax_Plugin::getPType()
61     */
62    function getPType(): string
63    {
64        return 'normal';
65    }
66
67    public function accepts($mode): bool
68    {
69        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
70    }
71
72    /**
73     * @see Doku_Parser_Mode::getSort()
74     *
75     * the mode with the lowest sort number will win out
76     * the container (parent) must then have a lower number than the child
77     */
78    function getSort()
79    {
80        return 100;
81    }
82
83    /**
84     * Create a pattern that will called this plugin
85     *
86     * @param string $mode
87     * @see Doku_Parser_Mode::connectTo()
88     */
89    function connectTo($mode)
90    {
91        /**
92         * Only inside a navbar or collapse element
93         */
94        $authorizedMode = [
95            PluginUtility::getModeFromTag(syntax_plugin_combo_navbarcollapse::COMPONENT),
96            PluginUtility::getModeFromTag(syntax_plugin_combo_menubar::TAG)
97        ];
98
99
100        if (in_array($mode, $authorizedMode)) {
101
102            $pattern = XmlTagProcessing::getContainerTagPattern(self::TAG);
103            $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
104
105        }
106
107    }
108
109
110    public function postConnect()
111    {
112        $this->Lexer->addExitPattern('</' . self::TAG . '>', 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
113
114    }
115
116    /**
117     *
118     * The handle function goal is to parse the matched syntax through the pattern function
119     * and to return the result for use in the renderer
120     * This result is always cached until the page is modified.
121     * @param string $match
122     * @param int $state
123     * @param int $pos
124     * @param Doku_Handler $handler
125     * @return array|bool
126     * @see DokuWiki_Syntax_Plugin::handle()
127     *
128     */
129    function handle($match, $state, $pos, Doku_Handler $handler)
130    {
131
132        switch ($state) {
133
134            case DOKU_LEXER_ENTER:
135
136                // Suppress the component name
137                $tagAttributes = PluginUtility::getTagAttributes($match);
138                return array(
139                    PluginUtility::STATE => $state,
140                    PluginUtility::ATTRIBUTES=> $tagAttributes
141                );
142
143            case DOKU_LEXER_UNMATCHED:
144                return PluginUtility::handleAndReturnUnmatchedData(self::TAG,$match,$handler);
145
146
147            case DOKU_LEXER_EXIT :
148
149                return array(PluginUtility::STATE => $state);
150
151
152        }
153
154        return array();
155
156    }
157
158    /**
159     * Render the output
160     * @param string $format
161     * @param Doku_Renderer $renderer
162     * @param array $data - what the function handle() return'ed
163     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
164     * @see DokuWiki_Syntax_Plugin::render()
165     *
166     *
167     */
168    function render($format, Doku_Renderer $renderer, $data)
169    {
170
171        $state = $data[PluginUtility::STATE];
172        if ($format == 'xhtml') {
173
174            /** @var Doku_Renderer_xhtml $renderer */
175
176            switch ($state) {
177
178                case DOKU_LEXER_ENTER :
179                    // https://getbootstrap.com/docs/4.0/components/navbar/#toggler splits the navbar-nav to another element
180                    // navbar-nav implementation
181                    $attributes = $data[PluginUtility::ATTRIBUTES];
182                    $classValue = "navbar-nav";
183                    if (array_key_exists("class", $attributes)) {
184                        $attributes["class"] .= " {$classValue}";
185                    } else {
186                        $attributes["class"] = $classValue;
187                    }
188
189                    if (array_key_exists("expand", $attributes)) {
190                        if ($attributes["expand"]=="true") {
191                            $bootstrapVersion = Bootstrap::getBootStrapMajorVersion();
192                            if($bootstrapVersion== Bootstrap::BootStrapFiveMajorVersion){
193                                $attributes["class"] .= " me-auto";
194                            } else {
195                                $attributes["class"] .= " mr-auto";
196                            }
197                        }
198                        unset($attributes["expand"]);
199                    }
200
201                    $inlineAttributes = PluginUtility::array2HTMLAttributesAsString($attributes);
202                    $renderer->doc .= "<ul {$inlineAttributes}>" . DOKU_LF;
203                    break;
204                case DOKU_LEXER_UNMATCHED :
205                    $renderer->doc .= NavBarUtility::text(PluginUtility::renderUnmatched($data));
206                    break;
207
208                case DOKU_LEXER_EXIT :
209                    $renderer->doc .= '</ul>' . DOKU_LF;
210                    break;
211            }
212            return true;
213        }
214        return false;
215    }
216
217
218}
219