1<?php
2
3
4// must be run within Dokuwiki
5use ComboStrap\CallStack;
6use ComboStrap\ColorRgb;
7use ComboStrap\Dimension;
8use ComboStrap\PluginUtility;
9use ComboStrap\TagAttribute\BackgroundAttribute;
10use ComboStrap\TagAttributes;
11use ComboStrap\XmlTagProcessing;
12
13
14/**
15 * Class syntax_plugin_combo_note
16 * Implementation of a note
17 * called an alert in <a href="https://getbootstrap.com/docs/4.0/components/alerts/">bootstrap</a>
18 */
19class syntax_plugin_combo_note extends DokuWiki_Syntax_Plugin
20{
21
22    const TAG = "note";
23    const COMPONENT = "combo_note";
24    const INFO_TYPE = "info";
25    const IMPORTANT_TYPE = "important";
26    const WARNING_TYPE = "warning";
27    const TIP_TYPE = "tip";
28
29    /**
30     * Syntax Type.
31     *
32     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
33     * @see DokuWiki_Syntax_Plugin::getType()
34     */
35    function getType(): string
36    {
37        return 'container';
38    }
39
40    /**
41     * How Dokuwiki will add P element
42     *
43     * * 'normal' - The plugin can be used inside paragraphs
44     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
45     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
46     *
47     * @see DokuWiki_Syntax_Plugin::getPType()
48     */
49    function getPType()
50    {
51        return 'stack';
52    }
53
54    /**
55     * @return array
56     * Allow which kind of plugin inside
57     *
58     * ************************
59     * This function has no effect because {@link SyntaxPlugin::accepts()} is used
60     * ************************
61     */
62    function getAllowedTypes()
63    {
64        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
65    }
66
67
68    function getSort()
69    {
70        return 201;
71    }
72
73    public function accepts($mode): bool
74    {
75        /**
76         * header mode is disable to take over
77         * and replace it with {@link syntax_plugin_combo_heading}
78         */
79        if ($mode == "header") {
80            return false;
81        }
82        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
83
84    }
85
86
87    function connectTo($mode)
88    {
89
90        $pattern = XmlTagProcessing::getContainerTagPattern(self::TAG);
91        $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
92    }
93
94
95    function postConnect()
96    {
97
98        $this->Lexer->addExitPattern('</' . self::TAG . '>', PluginUtility::getModeFromTag($this->getPluginComponent()));
99
100    }
101
102    function handle($match, $state, $pos, Doku_Handler $handler)
103    {
104
105        switch ($state) {
106
107            case DOKU_LEXER_ENTER :
108                $defaultAttributes = array(TagAttributes::TYPE_KEY => self::INFO_TYPE);
109                $knwonTypes = [self::INFO_TYPE, self::TIP_TYPE, self::IMPORTANT_TYPE, self::WARNING_TYPE];
110                $attributes = TagAttributes::createFromTagMatch($match, $defaultAttributes, $knwonTypes);
111                return array(
112                    PluginUtility::STATE => $state,
113                    PluginUtility::ATTRIBUTES => $attributes->toCallStackArray()
114                );
115
116            case DOKU_LEXER_UNMATCHED :
117                return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler);
118
119            case DOKU_LEXER_EXIT :
120
121                $callStack = CallStack::createFromHandler($handler);
122                Dimension::addScrollToggleOnClickIfNoControl($callStack);
123
124
125                // Important otherwise we don't get an exit in the render
126                return array(
127                    PluginUtility::STATE => $state
128                );
129
130
131        }
132        return array();
133
134    }
135
136    /**
137     * Render the output
138     * @param string $format
139     * @param Doku_Renderer $renderer
140     * @param array $data - what the function handle() return'ed
141     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
142     * @see DokuWiki_Syntax_Plugin::render()
143     *
144     *
145     */
146    function render($format, Doku_Renderer $renderer, $data)
147    {
148        if ($format == 'xhtml') {
149
150            /** @var Doku_Renderer_xhtml $renderer */
151            $state = $data[PluginUtility::STATE];
152            switch ($state) {
153                case DOKU_LEXER_ENTER :
154                    PluginUtility::getSnippetManager()->attachCssInternalStyleSheet(self::TAG);
155                    $attributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES], self::TAG);
156                    $attributes->addClassName("alert");
157                    $type = $attributes->getValue(TagAttributes::TYPE_KEY);
158                    // Switch for the color
159                    switch ($type) {
160                        case self::IMPORTANT_TYPE:
161                            $type = "warning";
162                            break;
163                        case self::WARNING_TYPE:
164                            $type = "danger";
165                            break;
166                    }
167
168                    if ($type != self::TIP_TYPE) {
169                        $attributes->addClassName("alert-" . $type);
170                    } else {
171                        // There is no alert-tip color
172                        // base color was background color and we have modified the luminance
173                        if (!$attributes->hasComponentAttribute(ColorRgb::COLOR)) {
174                            $attributes->addComponentAttributeValue(ColorRgb::COLOR, "#6c6400"); // lum - 51
175                        }
176                        if (!$attributes->hasComponentAttribute("border-color")) {
177                            $attributes->addComponentAttributeValue("border-color", "#FFF78c"); // lum - 186
178                        }
179                        if (!$attributes->hasComponentAttribute(BackgroundAttribute::BACKGROUND_COLOR)) {
180                            $attributes->addComponentAttributeValue(BackgroundAttribute::BACKGROUND_COLOR, "#fff79f"); // lum - 195
181                        }
182                    }
183
184                    $attributes->addOutputAttributeValue("role", "note");
185                    $renderer->doc .= $attributes->toHtmlEnterTag('div');
186                    break;
187
188                case DOKU_LEXER_UNMATCHED :
189                    $renderer->doc .= PluginUtility::renderUnmatched($data);
190                    break;
191
192                case DOKU_LEXER_EXIT :
193                    $renderer->doc .= '</div>';
194                    break;
195            }
196            return true;
197        }
198
199        // unsupported $mode
200        return false;
201    }
202
203
204}
205
206