1<?php 2/** 3 * DokuWiki Syntax Plugin Combostrap. 4 * 5 */ 6 7use ComboStrap\ExecutionContext; 8use ComboStrap\PluginUtility; 9use ComboStrap\TagAttributes; 10use ComboStrap\XmlTagProcessing; 11 12require_once(__DIR__ . '/../vendor/autoload.php'); 13 14/** 15 * All DokuWiki plugins to extend the parser/rendering mechanism 16 * need to inherit from this class 17 * 18 * The name of the class must follow a pattern (don't change it) 19 * ie: 20 * syntax_plugin_PluginName_ComponentName 21 * 22 * https://getbootstrap.com/docs/4.6/components/collapse/#accordion-example 23 * 24 * Ter info: 25 * https://jqueryui.com/accordion/ 26 * 27 * See also: https://getbootstrap.com/docs/5.0/content/reboot/#summary 28 * with a pointer 29 * 30 */ 31class syntax_plugin_combo_accordion extends DokuWiki_Syntax_Plugin 32{ 33 34 35 const TAG = 'accordion'; 36 37 38 /** 39 * Syntax Type. 40 * 41 * Needs to return one of the mode types defined in $PARSER_MODES in parser.php 42 * @see DokuWiki_Syntax_Plugin::getType() 43 */ 44 function getType() 45 { 46 return 'container'; 47 } 48 49 /** 50 * @return array 51 * Allow which kind of plugin inside 52 * 53 * One of array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs') 54 * 'baseonly' will run only in the base mode 55 * because we manage self the content and we call self the parser 56 * 57 * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php 58 */ 59 public function getAllowedTypes(): array 60 { 61 return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); 62 } 63 64 public function accepts($mode): bool 65 { 66 /** 67 * header mode is disable to take over 68 * and replace it with {@link syntax_plugin_combo_heading} 69 */ 70 if ($mode == "header") { 71 return false; 72 } 73 /** 74 * 75 */ 76 return syntax_plugin_combo_preformatted::disablePreformatted($mode); 77 78 } 79 80 /** 81 * How Dokuwiki will add P element 82 * 83 * * 'normal' - Inline 84 * * 'block' - Block (p are not created inside) 85 * * 'stack' - Block (p can be created inside) 86 * 87 * @see DokuWiki_Syntax_Plugin::getPType() 88 */ 89 function getPType() 90 { 91 return 'block'; 92 } 93 94 /** 95 * @see Doku_Parser_Mode::getSort() 96 * Higher number than the teaser-columns 97 * because the mode with the lowest sort number will win out 98 */ 99 function getSort() 100 { 101 return 200; 102 } 103 104 /** 105 * Create a pattern that will called this plugin 106 * 107 * @param string $mode 108 * @see Doku_Parser_Mode::connectTo() 109 */ 110 function connectTo($mode) 111 { 112 113 114 $pattern = XmlTagProcessing::getContainerTagPattern(self::TAG); 115 $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 116 117 118 } 119 120 public function postConnect() 121 { 122 123 124 $this->Lexer->addExitPattern('</' . self::TAG . '>', PluginUtility::getModeFromTag($this->getPluginComponent())); 125 126 127 } 128 129 /** 130 * 131 * The handle function goal is to parse the matched syntax through the pattern function 132 * and to return the result for use in the renderer 133 * This result is always cached until the page is modified. 134 * @param string $match 135 * @param int $state 136 * @param int $pos 137 * @param Doku_Handler $handler 138 * @return array|bool 139 * @see DokuWiki_Syntax_Plugin::handle() 140 * 141 */ 142 function handle($match, $state, $pos, Doku_Handler $handler) 143 { 144 145 switch ($state) { 146 147 case DOKU_LEXER_ENTER: 148 149 $attributes = TagAttributes::createFromTagMatch($match) 150 ->setLogicalTag(self::TAG); 151 152 // Attributes has at 153 // https://getbootstrap.com/docs/4.6/components/collapse/#accordion-example 154 $attributes->addClassName("accordion"); 155 156 if (!$attributes->hasComponentAttribute(TagAttributes::ID_KEY)) { 157 $idKey = ExecutionContext::getActualOrCreateFromEnv()->getIdManager()->generateNewHtmlIdForComponent(self::TAG); 158 $attributes->addComponentAttributeValue(TagAttributes::ID_KEY, $idKey); 159 } 160 161 return array( 162 PluginUtility::STATE => $state, 163 PluginUtility::ATTRIBUTES => $attributes->toCallStackArray() 164 ); 165 166 case DOKU_LEXER_UNMATCHED : 167 168 return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler); 169 170 171 case DOKU_LEXER_EXIT : 172 173 return array( 174 PluginUtility::STATE => $state 175 ); 176 177 178 } 179 180 return array(); 181 182 } 183 184 /** 185 * Render the output 186 * @param string $format 187 * @param Doku_Renderer $renderer 188 * @param array $data - what the function handle() return'ed 189 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 190 * @see DokuWiki_Syntax_Plugin::render() 191 * 192 * 193 */ 194 function render($format, Doku_Renderer $renderer, $data): bool 195 { 196 197 if ($format == 'xhtml') { 198 199 /** @var Doku_Renderer_xhtml $renderer */ 200 $state = $data[PluginUtility::STATE]; 201 switch ($state) { 202 case DOKU_LEXER_ENTER: 203 $attributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES]) 204 ->setLogicalTag(self::TAG); 205 $renderer->doc .= $attributes->toHtmlEnterTag("div"); 206 break; 207 case DOKU_LEXER_UNMATCHED: 208 $renderer->doc .= PluginUtility::renderUnmatched($data); 209 break; 210 case DOKU_LEXER_EXIT: 211 $renderer->doc .= '</div>'; 212 break; 213 } 214 215 216 return true; 217 } 218 return false; 219 } 220 221 222} 223