xref: /plugin/combo/syntax/brand.php (revision 4cadd4f8c541149bdda95f080e38a6d4e3a640ca)
1007225e5Sgerardnico<?php
2007225e5Sgerardnico
3007225e5Sgerardnico
4007225e5Sgerardnico// must be run within Dokuwiki
5*4cadd4f8SNickeauuse ComboStrap\Brand;
6*4cadd4f8SNickeauuse ComboStrap\BrandButton;
7*4cadd4f8SNickeauuse ComboStrap\CacheDependencies;
8*4cadd4f8SNickeauuse ComboStrap\CacheManager;
9*4cadd4f8SNickeauuse ComboStrap\Call;
10*4cadd4f8SNickeauuse ComboStrap\CallStack;
11*4cadd4f8SNickeauuse ComboStrap\ColorRgb;
12*4cadd4f8SNickeauuse ComboStrap\Dimension;
13*4cadd4f8SNickeauuse ComboStrap\ExceptionCombo;
14*4cadd4f8SNickeauuse ComboStrap\Icon;
15*4cadd4f8SNickeauuse ComboStrap\LogUtility;
16*4cadd4f8SNickeauuse ComboStrap\Page;
17007225e5Sgerardnicouse ComboStrap\PluginUtility;
18531e725cSNickeauuse ComboStrap\TagAttributes;
19*4cadd4f8SNickeauuse ComboStrap\Template;
20*4cadd4f8SNickeauuse ComboStrap\TemplateUtility;
21007225e5Sgerardnico
22007225e5Sgerardnicoif (!defined('DOKU_INC')) die();
23007225e5Sgerardnico
24007225e5Sgerardnico
2532b85071SNickeauclass syntax_plugin_combo_brand extends DokuWiki_Syntax_Plugin
2632b85071SNickeau{
2732b85071SNickeau
2832b85071SNickeau    const TAG = "brand";
29*4cadd4f8SNickeau    const CANONICAL = self::TAG;
30*4cadd4f8SNickeau
31*4cadd4f8SNickeau
32*4cadd4f8SNickeau    public const ICON_ATTRIBUTE = "icon";
33*4cadd4f8SNickeau
34*4cadd4f8SNickeau    public const URL_ATTRIBUTE = "url";
35*4cadd4f8SNickeau
36*4cadd4f8SNickeau    /**
37*4cadd4f8SNickeau     * Class needed
38*4cadd4f8SNickeau     * https://getbootstrap.com/docs/5.1/components/navbar/#image-and-text
39*4cadd4f8SNickeau     */
40*4cadd4f8SNickeau    const BOOTSTRAP_NAV_BAR_IMAGE_AND_TEXT_CLASS = "d-inline-block align-text-top";
41*4cadd4f8SNickeau
42*4cadd4f8SNickeau    const WIDGET_ATTRIBUTE = "widget";
43*4cadd4f8SNickeau
44*4cadd4f8SNickeau    const BRAND_IMAGE_FOUND_INDICATOR = "brand_image_found";
45*4cadd4f8SNickeau    const BRAND_TEXT_FOUND_INDICATOR = "brand_text_found";
46*4cadd4f8SNickeau
47*4cadd4f8SNickeau
48*4cadd4f8SNickeau    public static function addOpenLinkTagInCallStack(CallStack $callStack, TagAttributes $tagAttributes)
49*4cadd4f8SNickeau    {
50*4cadd4f8SNickeau        $linkArrayAttributes = $tagAttributes->toCallStackArray();
51*4cadd4f8SNickeau        $linkArrayAttributes[TagAttributes::TYPE_KEY] = $tagAttributes->getLogicalTag();
52*4cadd4f8SNickeau        $linkAttributes = TagAttributes::createFromCallStackArray($linkArrayAttributes);
53*4cadd4f8SNickeau        syntax_plugin_combo_link::addOpenLinkTagInCallStack($callStack, $linkAttributes);
54*4cadd4f8SNickeau    }
55*4cadd4f8SNickeau
56*4cadd4f8SNickeau    /**
57*4cadd4f8SNickeau     * @throws ExceptionCombo
58*4cadd4f8SNickeau     */
59*4cadd4f8SNickeau    public static function mixBrandButtonToTagAttributes(TagAttributes $tagAttributes, BrandButton $brandButton)
60*4cadd4f8SNickeau    {
61*4cadd4f8SNickeau        $brandLinkAttributes = $brandButton->getLinkAttributes();
62*4cadd4f8SNickeau        $urlAttribute = syntax_plugin_combo_brand::URL_ATTRIBUTE;
63*4cadd4f8SNickeau        $url = $tagAttributes->getValueAndRemoveIfPresent($urlAttribute);
64*4cadd4f8SNickeau        if ($url !== null) {
65*4cadd4f8SNickeau            $urlTemplate = Template::create($url);
66*4cadd4f8SNickeau            $variableDetected = $urlTemplate->getVariablesDetected();
67*4cadd4f8SNickeau            if (sizeof($variableDetected) === 1 && $variableDetected[0] === "path") {
68*4cadd4f8SNickeau                CacheManager::getOrCreate()->addDependencyForCurrentSlot(CacheDependencies::REQUESTED_PAGE_DEPENDENCY);
69*4cadd4f8SNickeau                $page = Page::createPageFromRequestedPage();
70*4cadd4f8SNickeau                $relativePath = str_replace(":", "/", $page->getDokuwikiId());
71*4cadd4f8SNickeau                $url = $urlTemplate
72*4cadd4f8SNickeau                    ->set("path", $relativePath)
73*4cadd4f8SNickeau                    ->render();
74*4cadd4f8SNickeau            }
75*4cadd4f8SNickeau            $tagAttributes->addOutputAttributeValue("href", $url);
76*4cadd4f8SNickeau        }
77*4cadd4f8SNickeau        $tagAttributes->mergeWithCallStackArray($brandLinkAttributes->toCallStackArray());
78*4cadd4f8SNickeau    }
79*4cadd4f8SNickeau
80*4cadd4f8SNickeau
81*4cadd4f8SNickeau    /**
82*4cadd4f8SNickeau     * An utility constructor to be sure that we build the brand button
83*4cadd4f8SNickeau     * with the same data in the handle and render function
84*4cadd4f8SNickeau     * @throws ExceptionCombo
85*4cadd4f8SNickeau     */
86*4cadd4f8SNickeau    public static function createButtonFromAttributes(TagAttributes $brandAttributes, $type = BrandButton::TYPE_BUTTON_BRAND): BrandButton
87*4cadd4f8SNickeau    {
88*4cadd4f8SNickeau        $brandName = $brandAttributes->getValue(TagAttributes::TYPE_KEY, Brand::CURRENT_BRAND);
89*4cadd4f8SNickeau        $widget = $brandAttributes->getValue(self::WIDGET_ATTRIBUTE, BrandButton::WIDGET_BUTTON_VALUE);
90*4cadd4f8SNickeau        $icon = $brandAttributes->getValue(self::ICON_ATTRIBUTE, BrandButton::ICON_SOLID_VALUE);
91*4cadd4f8SNickeau
92*4cadd4f8SNickeau        $brandButton = (new BrandButton($brandName, $type))
93*4cadd4f8SNickeau            ->setWidget($widget)
94*4cadd4f8SNickeau            ->setIconType($icon);
95*4cadd4f8SNickeau
96*4cadd4f8SNickeau        $width = $brandAttributes->getValueAsInteger(Dimension::WIDTH_KEY);
97*4cadd4f8SNickeau        if ($width !== null) {
98*4cadd4f8SNickeau            $brandButton->setWidth($width);
99*4cadd4f8SNickeau        }
100*4cadd4f8SNickeau        $title = $brandAttributes->getValue(syntax_plugin_combo_link::TITLE_ATTRIBUTE);
101*4cadd4f8SNickeau        if ($title !== null) {
102*4cadd4f8SNickeau            $brandButton->setLinkTitle($title);
103*4cadd4f8SNickeau        }
104*4cadd4f8SNickeau        $color = $brandAttributes->getValue(ColorRgb::PRIMARY_VALUE);
105*4cadd4f8SNickeau        if ($color !== null) {
106*4cadd4f8SNickeau            $brandButton->setPrimaryColor($color);
107*4cadd4f8SNickeau        }
108*4cadd4f8SNickeau        $secondaryColor = $brandAttributes->getValue(ColorRgb::SECONDARY_VALUE);
109*4cadd4f8SNickeau        if ($secondaryColor !== null) {
110*4cadd4f8SNickeau            $brandButton->setSecondaryColor($secondaryColor);
111*4cadd4f8SNickeau        }
112*4cadd4f8SNickeau        $handle = $brandAttributes->getValue(syntax_plugin_combo_follow::HANDLE_ATTRIBUTE);
113*4cadd4f8SNickeau        if ($handle !== null) {
114*4cadd4f8SNickeau            $brandButton->setHandle($handle);
115*4cadd4f8SNickeau        }
116*4cadd4f8SNickeau        return $brandButton;
117*4cadd4f8SNickeau    }
118007225e5Sgerardnico
119007225e5Sgerardnico    /**
120007225e5Sgerardnico     * Syntax Type.
121007225e5Sgerardnico     *
122007225e5Sgerardnico     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
123007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::getType()
124007225e5Sgerardnico     */
125*4cadd4f8SNickeau    function getType(): string
12632b85071SNickeau    {
127*4cadd4f8SNickeau        return 'substition';
128007225e5Sgerardnico    }
129007225e5Sgerardnico
130007225e5Sgerardnico    /**
131007225e5Sgerardnico     * How Dokuwiki will add P element
132007225e5Sgerardnico     *
133007225e5Sgerardnico     *  * 'normal' - The plugin can be used inside paragraphs
134007225e5Sgerardnico     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
135007225e5Sgerardnico     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
136007225e5Sgerardnico     *
137007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::getPType()
138007225e5Sgerardnico     */
139*4cadd4f8SNickeau    function getPType(): string
14032b85071SNickeau    {
141007225e5Sgerardnico        return 'normal';
142007225e5Sgerardnico    }
143007225e5Sgerardnico
144007225e5Sgerardnico    /**
145007225e5Sgerardnico     * @return array
146007225e5Sgerardnico     * Allow which kind of plugin inside
147007225e5Sgerardnico     *
148007225e5Sgerardnico     * array('container', 'baseonly', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
149007225e5Sgerardnico     *
150007225e5Sgerardnico     */
151*4cadd4f8SNickeau    function getAllowedTypes(): array
15232b85071SNickeau    {
153*4cadd4f8SNickeau        return array('baseonly', 'formatting', 'substition', 'protected', 'disabled');
154007225e5Sgerardnico    }
155007225e5Sgerardnico
156*4cadd4f8SNickeau    function getSort(): int
15732b85071SNickeau    {
158007225e5Sgerardnico        return 201;
159007225e5Sgerardnico    }
160007225e5Sgerardnico
161*4cadd4f8SNickeau    public
162*4cadd4f8SNickeau    function accepts($mode): bool
163531e725cSNickeau    {
164531e725cSNickeau        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
165531e725cSNickeau    }
166531e725cSNickeau
167007225e5Sgerardnico
168007225e5Sgerardnico    /**
169007225e5Sgerardnico     * Create a pattern that will called this plugin
170007225e5Sgerardnico     *
171007225e5Sgerardnico     * @param string $mode
17232b85071SNickeau     * @see Doku_Parser_Mode::connectTo()
173007225e5Sgerardnico     */
17432b85071SNickeau    function connectTo($mode)
17532b85071SNickeau    {
176007225e5Sgerardnico
177007225e5Sgerardnico        $pattern = PluginUtility::getContainerTagPattern(self::getTag());
178007225e5Sgerardnico        $this->Lexer->addEntryPattern($pattern, $mode, 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
179007225e5Sgerardnico
180*4cadd4f8SNickeau        /**
181*4cadd4f8SNickeau         * The empty tag pattern should be after the container pattern
182*4cadd4f8SNickeau         */
183*4cadd4f8SNickeau        $this->Lexer->addSpecialPattern(PluginUtility::getEmptyTagPattern(self::TAG), $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
184*4cadd4f8SNickeau
185007225e5Sgerardnico    }
186007225e5Sgerardnico
18732b85071SNickeau    function postConnect()
18832b85071SNickeau    {
189007225e5Sgerardnico
190007225e5Sgerardnico        $this->Lexer->addExitPattern('</' . self::getTag() . '>', 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
191007225e5Sgerardnico
192007225e5Sgerardnico    }
193007225e5Sgerardnico
19432b85071SNickeau    function handle($match, $state, $pos, Doku_Handler $handler)
19532b85071SNickeau    {
196007225e5Sgerardnico
197*4cadd4f8SNickeau
198007225e5Sgerardnico        switch ($state) {
199007225e5Sgerardnico
200*4cadd4f8SNickeau            case DOKU_LEXER_SPECIAL :
201007225e5Sgerardnico            case DOKU_LEXER_ENTER :
202*4cadd4f8SNickeau
203*4cadd4f8SNickeau                /**
204*4cadd4f8SNickeau                 * Context
205*4cadd4f8SNickeau                 */
206*4cadd4f8SNickeau                $callStack = CallStack::createFromHandler($handler);
207*4cadd4f8SNickeau                $parent = $callStack->moveToParent();
208*4cadd4f8SNickeau                $context = null;
209*4cadd4f8SNickeau                if ($parent !== false) {
210*4cadd4f8SNickeau                    $context = $parent->getTagName();
211531e725cSNickeau                }
212*4cadd4f8SNickeau
213*4cadd4f8SNickeau                /**
214*4cadd4f8SNickeau                 * Default parameters, type definition and parsing
215*4cadd4f8SNickeau                 */
216*4cadd4f8SNickeau                if ($context === syntax_plugin_combo_menubar::TAG) {
217*4cadd4f8SNickeau                    $defaultWidget = BrandButton::WIDGET_LINK_VALUE;
218*4cadd4f8SNickeau                } else {
219*4cadd4f8SNickeau                    $defaultWidget = BrandButton::WIDGET_BUTTON_VALUE;
220*4cadd4f8SNickeau                }
221*4cadd4f8SNickeau                $defaultParameters[TagAttributes::TYPE_KEY] = Brand::CURRENT_BRAND;
222*4cadd4f8SNickeau                $defaultParameters[self::WIDGET_ATTRIBUTE] = $defaultWidget;
223*4cadd4f8SNickeau                $knownTypes = null;
224*4cadd4f8SNickeau                $tagAttributes = TagAttributes::createFromTagMatch($match, $defaultParameters, $knownTypes)
225*4cadd4f8SNickeau                    ->setLogicalTag(self::TAG);
226*4cadd4f8SNickeau
227*4cadd4f8SNickeau
22832b85071SNickeau                return array(
22932b85071SNickeau                    PluginUtility::STATE => $state,
230*4cadd4f8SNickeau                    PluginUtility::ATTRIBUTES => $tagAttributes->toCallStackArray(),
231*4cadd4f8SNickeau                    PluginUtility::CONTEXT => $context
23232b85071SNickeau                );
233007225e5Sgerardnico
234007225e5Sgerardnico            case DOKU_LEXER_UNMATCHED :
23532b85071SNickeau                return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler);
236007225e5Sgerardnico
237007225e5Sgerardnico            case DOKU_LEXER_EXIT :
238007225e5Sgerardnico
239*4cadd4f8SNickeau                $callStack = CallStack::createFromHandler($handler);
240*4cadd4f8SNickeau                $openTag = $callStack->moveToPreviousCorrespondingOpeningCall();
241*4cadd4f8SNickeau                $openTagAttributes = TagAttributes::createFromCallStackArray($openTag->getAttributes());
242*4cadd4f8SNickeau                $openTagContext = $openTag->getContext();
243*4cadd4f8SNickeau                /**
244*4cadd4f8SNickeau                 * Old syntax
245*4cadd4f8SNickeau                 * An icon/image could be already inside
246*4cadd4f8SNickeau                 * We go from end to start to
247*4cadd4f8SNickeau                 * see if there is also a text, if this is the case,
248*4cadd4f8SNickeau                 * there is a class added on the media
249*4cadd4f8SNickeau                 */
250*4cadd4f8SNickeau                $markupIconImageFound = false;
251*4cadd4f8SNickeau                $textFound = false;
252*4cadd4f8SNickeau                $callStack->moveToEnd();
253*4cadd4f8SNickeau                while ($actualCall = $callStack->previous()) {
254*4cadd4f8SNickeau                    $tagName = $actualCall->getTagName();
255*4cadd4f8SNickeau                    if (in_array($tagName, [syntax_plugin_combo_icon::TAG, syntax_plugin_combo_media::TAG])) {
256*4cadd4f8SNickeau
257*4cadd4f8SNickeau
258*4cadd4f8SNickeau                        if ($textFound && $openTagContext === syntax_plugin_combo_menubar::TAG) {
259*4cadd4f8SNickeau                            // if text and icon
260*4cadd4f8SNickeau                            // We add it here because, if they are present, we don't add them later
261*4cadd4f8SNickeau                            // for all on raster image
262*4cadd4f8SNickeau                            $actualCall->addClassName(self::BOOTSTRAP_NAV_BAR_IMAGE_AND_TEXT_CLASS);
263*4cadd4f8SNickeau                        }
264*4cadd4f8SNickeau
265*4cadd4f8SNickeau                        // is it a added call / no content
266*4cadd4f8SNickeau                        // or is it an icon from the markup
267*4cadd4f8SNickeau                        if ($actualCall->getCapturedContent() === null) {
268*4cadd4f8SNickeau
269*4cadd4f8SNickeau                            // It's an added call
270*4cadd4f8SNickeau                            // No user icon, image can be found anymore
271*4cadd4f8SNickeau                            // exiting
272*4cadd4f8SNickeau                            break;
273*4cadd4f8SNickeau                        }
274*4cadd4f8SNickeau
275*4cadd4f8SNickeau                        $primary = $openTagAttributes->getValue(ColorRgb::PRIMARY_VALUE);
276*4cadd4f8SNickeau                        if ($primary !== null && $tagName === syntax_plugin_combo_icon::TAG) {
277*4cadd4f8SNickeau                            try {
278*4cadd4f8SNickeau                                $brandButton = self::createButtonFromAttributes($openTagAttributes);
279*4cadd4f8SNickeau                                $actualCall->addAttribute(ColorRgb::COLOR, $brandButton->getTextColor());
280*4cadd4f8SNickeau                            } catch (ExceptionCombo $e) {
281*4cadd4f8SNickeau                                LogUtility::msg("Error while trying to set the icon color on exit. Error: {$e->getMessage()}");
282*4cadd4f8SNickeau                            }
283*4cadd4f8SNickeau                        }
284*4cadd4f8SNickeau
285*4cadd4f8SNickeau                        $markupIconImageFound = true;
286*4cadd4f8SNickeau                    }
287*4cadd4f8SNickeau                    if ($actualCall->getState() === DOKU_LEXER_UNMATCHED) {
288*4cadd4f8SNickeau                        $textFound = true;
289*4cadd4f8SNickeau                    }
290*4cadd4f8SNickeau                }
291*4cadd4f8SNickeau                $openTag->setPluginData(self::BRAND_IMAGE_FOUND_INDICATOR, $markupIconImageFound);
292*4cadd4f8SNickeau                $openTag->setPluginData(self::BRAND_TEXT_FOUND_INDICATOR, $textFound);
293*4cadd4f8SNickeau
29432b85071SNickeau                return array(
29532b85071SNickeau                    PluginUtility::STATE => $state
29632b85071SNickeau                );
297007225e5Sgerardnico
298007225e5Sgerardnico
299007225e5Sgerardnico        }
300007225e5Sgerardnico        return array();
301007225e5Sgerardnico
302007225e5Sgerardnico    }
303007225e5Sgerardnico
304007225e5Sgerardnico    /**
305007225e5Sgerardnico     * Render the output
306007225e5Sgerardnico     * @param string $format
307007225e5Sgerardnico     * @param Doku_Renderer $renderer
308*4cadd4f8SNickeau     * @param array $data - what the function handle() return
309007225e5Sgerardnico     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
310007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::render()
311007225e5Sgerardnico     *
312007225e5Sgerardnico     *
313007225e5Sgerardnico     */
314*4cadd4f8SNickeau    function render($format, Doku_Renderer $renderer, $data): bool
31532b85071SNickeau    {
316007225e5Sgerardnico
317*4cadd4f8SNickeau        if ($format === "xhtml") {
31832b85071SNickeau            $state = $data[PluginUtility::STATE];
319007225e5Sgerardnico            switch ($state) {
320*4cadd4f8SNickeau                case DOKU_LEXER_SPECIAL:
321007225e5Sgerardnico                case DOKU_LEXER_ENTER:
322*4cadd4f8SNickeau
323*4cadd4f8SNickeau                    $tagAttributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES]);
324*4cadd4f8SNickeau                    /**
325*4cadd4f8SNickeau                     * Brand Object creation
326*4cadd4f8SNickeau                     */
327*4cadd4f8SNickeau                    $brandName = $tagAttributes->getType();
328*4cadd4f8SNickeau                    try {
329*4cadd4f8SNickeau                        $brandButton = self::createButtonFromAttributes($tagAttributes);
330*4cadd4f8SNickeau                    } catch (ExceptionCombo $e) {
331*4cadd4f8SNickeau                        $renderer->doc .= LogUtility::wrapInRedForHtml("Error while reading the brand data for the brand ($brandName). Error: {$e->getMessage()}");
332*4cadd4f8SNickeau                        return false;
333*4cadd4f8SNickeau                    }
334*4cadd4f8SNickeau                    /**
335*4cadd4f8SNickeau                     * Link
336*4cadd4f8SNickeau                     */
337*4cadd4f8SNickeau                    try {
338*4cadd4f8SNickeau                        self::mixBrandButtonToTagAttributes($tagAttributes, $brandButton);
339*4cadd4f8SNickeau                    } catch (ExceptionCombo $e) {
340*4cadd4f8SNickeau                        $renderer->doc .= LogUtility::wrapInRedForHtml("Error while getting the link data for the the brand ($brandName). Error: {$e->getMessage()}");
341*4cadd4f8SNickeau                        return false;
342*4cadd4f8SNickeau                    }
343*4cadd4f8SNickeau                    $context = $data[PluginUtility::CONTEXT];
344*4cadd4f8SNickeau                    if ($context === syntax_plugin_combo_menubar::TAG) {
345*4cadd4f8SNickeau                        $tagAttributes->addOutputAttributeValue("accesskey", "h");
346531e725cSNickeau                        $tagAttributes->addClassName("navbar-brand");
347*4cadd4f8SNickeau                    }
348*4cadd4f8SNickeau                    // Width does not apply to link (otherwise the link got a max-width of 30)
349*4cadd4f8SNickeau                    $tagAttributes->removeComponentAttributeIfPresent(Dimension::WIDTH_KEY);
350*4cadd4f8SNickeau                    // Widget also
351*4cadd4f8SNickeau                    $tagAttributes->removeComponentAttributeIfPresent(self::WIDGET_ATTRIBUTE);
352*4cadd4f8SNickeau                    $renderer->doc .= $tagAttributes
353*4cadd4f8SNickeau                        ->setType(self::CANONICAL)
354*4cadd4f8SNickeau                        ->setLogicalTag(syntax_plugin_combo_link::TAG)
355*4cadd4f8SNickeau                        ->toHtmlEnterTag("a");
356007225e5Sgerardnico
357*4cadd4f8SNickeau
358*4cadd4f8SNickeau                    /**
359*4cadd4f8SNickeau                     * Logo
360*4cadd4f8SNickeau                     */
361*4cadd4f8SNickeau                    $brandImageFound = $data[self::BRAND_IMAGE_FOUND_INDICATOR];
362*4cadd4f8SNickeau                    if (!$brandImageFound && $brandButton->hasIcon()) {
363*4cadd4f8SNickeau                        try {
364*4cadd4f8SNickeau                            $iconAttributes = $brandButton->getIconAttributes();
365*4cadd4f8SNickeau                            $textFound = $data[self::BRAND_TEXT_FOUND_INDICATOR];
366*4cadd4f8SNickeau                            $name = $iconAttributes[\syntax_plugin_combo_icon::ICON_NAME_ATTRIBUTE];
367*4cadd4f8SNickeau                            $iconAttributes = TagAttributes::createFromCallStackArray($iconAttributes);
368*4cadd4f8SNickeau                            if ($textFound && $context === syntax_plugin_combo_menubar::TAG) {
369*4cadd4f8SNickeau                                $iconAttributes->addClassName(self::BOOTSTRAP_NAV_BAR_IMAGE_AND_TEXT_CLASS);
370*4cadd4f8SNickeau                            }
371*4cadd4f8SNickeau                            $renderer->doc .= Icon::create($name, $iconAttributes)
372*4cadd4f8SNickeau                                ->render();
373*4cadd4f8SNickeau                        } catch (ExceptionCombo $e) {
374*4cadd4f8SNickeau
375*4cadd4f8SNickeau                            if ($brandButton->getBrand()->getName() === Brand::CURRENT_BRAND) {
376*4cadd4f8SNickeau
377*4cadd4f8SNickeau                                $documentationLink = PluginUtility::getDocumentationHyperLink("logo", "documentation");
378*4cadd4f8SNickeau                                LogUtility::msg("A svg logo icon is not installed on your website. Check the corresponding $documentationLink.", LogUtility::LVL_MSG_INFO);
379*4cadd4f8SNickeau
380*4cadd4f8SNickeau                            } else {
381*4cadd4f8SNickeau
382*4cadd4f8SNickeau                                $renderer->doc .= "The brand icon returns an error. Error: {$e->getMessage()}";
383*4cadd4f8SNickeau                                // we don't return because the link is not closed
384*4cadd4f8SNickeau
385*4cadd4f8SNickeau                            }
386*4cadd4f8SNickeau
387*4cadd4f8SNickeau                        }
388*4cadd4f8SNickeau                    }
389*4cadd4f8SNickeau
390*4cadd4f8SNickeau                    /**
391*4cadd4f8SNickeau                     * End of link
392*4cadd4f8SNickeau                     */
393*4cadd4f8SNickeau                    if ($state === DOKU_LEXER_SPECIAL) {
394*4cadd4f8SNickeau                        $renderer->doc .= "</a>";
395*4cadd4f8SNickeau                    }
396*4cadd4f8SNickeau
397*4cadd4f8SNickeau                    /**
398*4cadd4f8SNickeau                     * Add the Icon / CSS / Javascript snippet
399*4cadd4f8SNickeau                     *
400*4cadd4f8SNickeau                     */
401*4cadd4f8SNickeau                    $tagAttributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES]);
402*4cadd4f8SNickeau                    try {
403*4cadd4f8SNickeau                        $brandButton = self::createButtonFromAttributes($tagAttributes);
404*4cadd4f8SNickeau                    } catch (ExceptionCombo $e) {
405*4cadd4f8SNickeau                        LogUtility::msg("The brand could not be build. Error: {$e->getMessage()}");
406*4cadd4f8SNickeau                        return false;
407*4cadd4f8SNickeau                    }
408*4cadd4f8SNickeau                    try {
409*4cadd4f8SNickeau                        $style = $brandButton->getStyle();
410*4cadd4f8SNickeau                    } catch (ExceptionCombo $e) {
411*4cadd4f8SNickeau                        LogUtility::msg("The style of the {$this->getType()} button ($brandButton) could not be determined. Error: {$e->getMessage()}");
412*4cadd4f8SNickeau                        return false;
413*4cadd4f8SNickeau                    }
414*4cadd4f8SNickeau                    $snippetId = $brandButton->getStyleScriptIdentifier();
415*4cadd4f8SNickeau                    PluginUtility::getSnippetManager()->attachCssInternalStyleSheetForSlot($snippetId, $style);
416007225e5Sgerardnico                    break;
417007225e5Sgerardnico                case DOKU_LEXER_UNMATCHED:
41832b85071SNickeau                    $renderer->doc .= PluginUtility::renderUnmatched($data);
419007225e5Sgerardnico                    break;
420007225e5Sgerardnico                case DOKU_LEXER_EXIT:
421*4cadd4f8SNickeau                    $renderer->doc .= "</a>";
422007225e5Sgerardnico                    break;
423*4cadd4f8SNickeau
424007225e5Sgerardnico            }
425007225e5Sgerardnico            return true;
426007225e5Sgerardnico        }
427007225e5Sgerardnico
428007225e5Sgerardnico        // unsupported $mode
429007225e5Sgerardnico        return false;
430007225e5Sgerardnico    }
431007225e5Sgerardnico
432*4cadd4f8SNickeau    public
433*4cadd4f8SNickeau    static function getTag(): string
434007225e5Sgerardnico    {
435*4cadd4f8SNickeau        return self::TAG;
436*4cadd4f8SNickeau    }
437*4cadd4f8SNickeau
438*4cadd4f8SNickeau    /**
439*4cadd4f8SNickeau     *
440*4cadd4f8SNickeau     * @throws ExceptionCombo
441*4cadd4f8SNickeau     */
442*4cadd4f8SNickeau    public
443*4cadd4f8SNickeau    static function addIconInCallStack(CallStack $callStack, BrandButton $brandButton)
444*4cadd4f8SNickeau    {
445*4cadd4f8SNickeau
446*4cadd4f8SNickeau        if (!$brandButton->hasIcon()) {
447*4cadd4f8SNickeau            return;
448*4cadd4f8SNickeau        }
449*4cadd4f8SNickeau        $iconAttributes = $brandButton->getIconAttributes();
450*4cadd4f8SNickeau
451*4cadd4f8SNickeau        $callStack->appendCallAtTheEnd(
452*4cadd4f8SNickeau            Call::createComboCall(
453*4cadd4f8SNickeau                syntax_plugin_combo_icon::TAG,
454*4cadd4f8SNickeau                DOKU_LEXER_SPECIAL,
455*4cadd4f8SNickeau                $iconAttributes
456*4cadd4f8SNickeau            ));
457007225e5Sgerardnico    }
458007225e5Sgerardnico
459007225e5Sgerardnico}
460007225e5Sgerardnico
461