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