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