1<?php 2/** 3 * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4 * 5 * This source code is licensed under the GPL license found in the 6 * COPYING file in the root directory of this source tree. 7 * 8 * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9 * @author ComboStrap <support@combostrap.com> 10 * 11 */ 12 13use ComboStrap\Call; 14use ComboStrap\CallStack; 15use ComboStrap\Dimension; 16use ComboStrap\GridTag; 17use ComboStrap\LogUtility; 18use ComboStrap\PluginUtility; 19use ComboStrap\Tag\BoxTag; 20use ComboStrap\TagAttributes; 21use ComboStrap\XmlTagProcessing; 22 23 24require_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 25 26/** 27 * 28 * 29 * 30 * @deprecated - flex item are created now with the {@link \ComboStrap\TagAttribute\Align} attribute 31 * and the col class is set now on the row class. 32 */ 33class syntax_plugin_combo_cell extends DokuWiki_Syntax_Plugin 34{ 35 36 const TAG = "cell"; 37 38 const WIDTH_ATTRIBUTE = Dimension::WIDTH_KEY; 39 const FLEX_CLASS = "d-flex"; 40 41 42 static function getTags(): array 43 { 44 return [self::TAG, "col", "column"]; 45 } 46 47 /** 48 * Syntax Type. 49 * 50 * Needs to return one of the mode types defined in $PARSER_MODES in parser.php 51 * @see DokuWiki_Syntax_Plugin::getType() 52 */ 53 function getType(): string 54 { 55 return 'container'; 56 } 57 58 /** 59 * @return array 60 * Allow which kind of plugin inside 61 * All 62 */ 63 public function getAllowedTypes(): array 64 { 65 return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); 66 } 67 68 public function accepts($mode): bool 69 { 70 71 /** 72 * header mode is disable to take over 73 * and replace it with {@link syntax_plugin_combo_heading} 74 */ 75 if ($mode == "header") { 76 return false; 77 } 78 79 80 return syntax_plugin_combo_preformatted::disablePreformatted($mode); 81 82 } 83 84 /** 85 * How Dokuwiki will add P element 86 * 87 * * 'normal' - The plugin can be used inside paragraphs 88 * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 89 * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 90 * 91 * @see DokuWiki_Syntax_Plugin::getPType() 92 */ 93 function getPType() 94 { 95 return 'stack'; 96 } 97 98 /** 99 * @see Doku_Parser_Mode::getSort() 100 * 101 * the mode with the lowest sort number will win out 102 * the container (parent) must then have a lower number than the child 103 */ 104 function getSort() 105 { 106 return 100; 107 } 108 109 /** 110 * Create a pattern that will called this plugin 111 * 112 * @param string $mode 113 * @see Doku_Parser_Mode::connectTo() 114 */ 115 function connectTo($mode) 116 { 117 118 // A cell can be anywhere 119 foreach (self::getTags() as $tag) { 120 $pattern = XmlTagProcessing::getContainerTagPattern($tag); 121 $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 122 } 123 124 125 } 126 127 public function postConnect() 128 { 129 130 foreach (self::getTags() as $tag) { 131 $this->Lexer->addExitPattern('</' . $tag . '>', PluginUtility::getModeFromTag($this->getPluginComponent())); 132 } 133 134 } 135 136 /** 137 * 138 * The handle function goal is to parse the matched syntax through the pattern function 139 * and to return the result for use in the renderer 140 * This result is always cached until the page is modified. 141 * @param string $match 142 * @param int $state 143 * @param int $pos 144 * @param Doku_Handler $handler 145 * @return array|bool 146 * @see DokuWiki_Syntax_Plugin::handle() 147 * 148 */ 149 function handle($match, $state, $pos, Doku_Handler $handler) 150 { 151 152 switch ($state) { 153 154 case DOKU_LEXER_ENTER: 155 156 $knownTypes = []; 157 $defaultAttributes = []; 158 $attributes = TagAttributes::createFromTagMatch($match, $defaultAttributes, $knownTypes)->toCallStackArray(); 159 160 LogUtility::warning("Cell (Col) has been deprecated for box (You can use now any component in a grid or row).", GridTag::TAG); 161 return array( 162 PluginUtility::STATE => $state, 163 PluginUtility::ATTRIBUTES => $attributes); 164 165 case DOKU_LEXER_UNMATCHED: 166 return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler); 167 168 case DOKU_LEXER_EXIT : 169 170 $callStack = CallStack::createFromHandler($handler); 171 $openingTag = $callStack->moveToPreviousCorrespondingOpeningCall(); 172 $firstChild = $callStack->moveToFirstChildTag(); 173 174 /** 175 * A cell is a flex container that helps place its children 176 * It should contain one or more container 177 * It should have at minimum one 178 */ 179 $addChildContainer = true; 180 if ($firstChild !== false) { 181 if (in_array($firstChild->getTagName(), TagAttributes::CONTAINER_LOGICAL_ELEMENTS)) { 182 $addChildContainer = false; 183 } 184 } 185 if ($addChildContainer === true) { 186 /** 187 * A cell should have one or more container as child 188 * If the container is not in the markup, we add it 189 */ 190 $callStack->moveToCall($openingTag); 191 $callStack->insertAfter( 192 Call::createComboCall( 193 BoxTag::TAG, 194 DOKU_LEXER_ENTER, 195 [], 196 null, 197 null, 198 null, 199 null, 200 \syntax_plugin_combo_xmlblocktag::TAG 201 )); 202 $callStack->moveToEnd(); 203 $callStack->insertBefore( 204 Call::createComboCall( 205 BoxTag::TAG, 206 DOKU_LEXER_EXIT, 207 [], 208 null, 209 null, 210 null, 211 null, 212 \syntax_plugin_combo_xmlblocktag::TAG 213 )); 214 } 215 216 217 return array( 218 PluginUtility::STATE => $state 219 ); 220 221 222 } 223 224 return array(); 225 226 } 227 228 /** 229 * Render the output 230 * @param string $format 231 * @param Doku_Renderer $renderer 232 * @param array $data - what the function handle() return'ed 233 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 234 * @see DokuWiki_Syntax_Plugin::render() 235 * 236 * 237 */ 238 function render($format, Doku_Renderer $renderer, $data): bool 239 { 240 241 if ($format == 'xhtml') { 242 243 /** @var Doku_Renderer_xhtml $renderer */ 244 $state = $data[PluginUtility::STATE]; 245 switch ($state) { 246 247 case DOKU_LEXER_ENTER : 248 249 PluginUtility::getSnippetManager()->attachCssInternalStyleSheet(self::TAG); 250 $callStackArray = $data[PluginUtility::ATTRIBUTES]; 251 $attributes = TagAttributes::createFromCallStackArray($callStackArray, self::TAG); 252 /** 253 * A flex to be able to align the children (horizontal/vertical) 254 * if they are constraint in width 255 */ 256 $attributes->addClassName(self::FLEX_CLASS); 257 /** 258 * Horizontal (center) 259 */ 260 $attributes->addClassName("justify-content-center"); 261 262 $renderer->doc .= $attributes->toHtmlEnterTag("div"); 263 break; 264 265 case DOKU_LEXER_UNMATCHED : 266 267 $renderer->doc .= PluginUtility::renderUnmatched($data); 268 break; 269 270 case DOKU_LEXER_EXIT : 271 272 $renderer->doc .= '</div>'; 273 break; 274 } 275 return true; 276 } 277 return false; 278 } 279 280 281} 282