1531e725cSNickeau<?php 2531e725cSNickeau/** 3531e725cSNickeau * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4531e725cSNickeau * 5531e725cSNickeau * This source code is licensed under the GPL license found in the 6531e725cSNickeau * COPYING file in the root directory of this source tree. 7531e725cSNickeau * 8531e725cSNickeau * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9531e725cSNickeau * @author ComboStrap <support@combostrap.com> 10531e725cSNickeau * 11531e725cSNickeau */ 12531e725cSNickeau 13*04fd306cSNickeauuse ComboStrap\Call; 14*04fd306cSNickeauuse ComboStrap\CallStack; 15a6bf47aaSNickeauuse ComboStrap\Dimension; 16*04fd306cSNickeauuse ComboStrap\GridTag; 17*04fd306cSNickeauuse ComboStrap\LogUtility; 18531e725cSNickeauuse ComboStrap\PluginUtility; 19*04fd306cSNickeauuse ComboStrap\Tag\BoxTag; 20531e725cSNickeauuse ComboStrap\TagAttributes; 21*04fd306cSNickeauuse ComboStrap\XmlTagProcessing; 22531e725cSNickeau 23531e725cSNickeau 2437748cd8SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 25531e725cSNickeau 26531e725cSNickeau/** 27531e725cSNickeau * 28531e725cSNickeau * 29*04fd306cSNickeau * 30*04fd306cSNickeau * @deprecated - flex item are created now with the {@link \ComboStrap\TagAttribute\Align} attribute 31*04fd306cSNickeau * and the col class is set now on the row class. 32531e725cSNickeau */ 33531e725cSNickeauclass syntax_plugin_combo_cell extends DokuWiki_Syntax_Plugin 34531e725cSNickeau{ 35531e725cSNickeau 36531e725cSNickeau const TAG = "cell"; 37531e725cSNickeau 38a6bf47aaSNickeau const WIDTH_ATTRIBUTE = Dimension::WIDTH_KEY; 39*04fd306cSNickeau const FLEX_CLASS = "d-flex"; 40531e725cSNickeau 41*04fd306cSNickeau 42*04fd306cSNickeau static function getTags(): array 43531e725cSNickeau { 44531e725cSNickeau return [self::TAG, "col", "column"]; 45531e725cSNickeau } 46531e725cSNickeau 47531e725cSNickeau /** 48531e725cSNickeau * Syntax Type. 49531e725cSNickeau * 50531e725cSNickeau * Needs to return one of the mode types defined in $PARSER_MODES in parser.php 51531e725cSNickeau * @see DokuWiki_Syntax_Plugin::getType() 52531e725cSNickeau */ 53*04fd306cSNickeau function getType(): string 54531e725cSNickeau { 55531e725cSNickeau return 'container'; 56531e725cSNickeau } 57531e725cSNickeau 58531e725cSNickeau /** 59531e725cSNickeau * @return array 60531e725cSNickeau * Allow which kind of plugin inside 61531e725cSNickeau * All 62531e725cSNickeau */ 63*04fd306cSNickeau public function getAllowedTypes(): array 64531e725cSNickeau { 65531e725cSNickeau return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); 66531e725cSNickeau } 67531e725cSNickeau 68*04fd306cSNickeau public function accepts($mode): bool 69531e725cSNickeau { 70531e725cSNickeau 71531e725cSNickeau /** 72531e725cSNickeau * header mode is disable to take over 73531e725cSNickeau * and replace it with {@link syntax_plugin_combo_heading} 74531e725cSNickeau */ 75531e725cSNickeau if ($mode == "header") { 76531e725cSNickeau return false; 77531e725cSNickeau } 78531e725cSNickeau 79531e725cSNickeau 80531e725cSNickeau return syntax_plugin_combo_preformatted::disablePreformatted($mode); 81531e725cSNickeau 82531e725cSNickeau } 83531e725cSNickeau 84531e725cSNickeau /** 85531e725cSNickeau * How Dokuwiki will add P element 86531e725cSNickeau * 87531e725cSNickeau * * 'normal' - The plugin can be used inside paragraphs 88531e725cSNickeau * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 89531e725cSNickeau * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 90531e725cSNickeau * 91531e725cSNickeau * @see DokuWiki_Syntax_Plugin::getPType() 92531e725cSNickeau */ 93531e725cSNickeau function getPType() 94531e725cSNickeau { 95531e725cSNickeau return 'stack'; 96531e725cSNickeau } 97531e725cSNickeau 98531e725cSNickeau /** 99531e725cSNickeau * @see Doku_Parser_Mode::getSort() 100531e725cSNickeau * 101531e725cSNickeau * the mode with the lowest sort number will win out 102531e725cSNickeau * the container (parent) must then have a lower number than the child 103531e725cSNickeau */ 104531e725cSNickeau function getSort() 105531e725cSNickeau { 106531e725cSNickeau return 100; 107531e725cSNickeau } 108531e725cSNickeau 109531e725cSNickeau /** 110531e725cSNickeau * Create a pattern that will called this plugin 111531e725cSNickeau * 112531e725cSNickeau * @param string $mode 113531e725cSNickeau * @see Doku_Parser_Mode::connectTo() 114531e725cSNickeau */ 115531e725cSNickeau function connectTo($mode) 116531e725cSNickeau { 117531e725cSNickeau 118531e725cSNickeau // A cell can be anywhere 119531e725cSNickeau foreach (self::getTags() as $tag) { 120*04fd306cSNickeau $pattern = XmlTagProcessing::getContainerTagPattern($tag); 1219337a630SNickeau $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 122531e725cSNickeau } 123531e725cSNickeau 124531e725cSNickeau 125531e725cSNickeau } 126531e725cSNickeau 127531e725cSNickeau public function postConnect() 128531e725cSNickeau { 129531e725cSNickeau 130531e725cSNickeau foreach (self::getTags() as $tag) { 1319337a630SNickeau $this->Lexer->addExitPattern('</' . $tag . '>', PluginUtility::getModeFromTag($this->getPluginComponent())); 132531e725cSNickeau } 133531e725cSNickeau 134531e725cSNickeau } 135531e725cSNickeau 136531e725cSNickeau /** 137531e725cSNickeau * 138531e725cSNickeau * The handle function goal is to parse the matched syntax through the pattern function 139531e725cSNickeau * and to return the result for use in the renderer 140531e725cSNickeau * This result is always cached until the page is modified. 141531e725cSNickeau * @param string $match 142531e725cSNickeau * @param int $state 143531e725cSNickeau * @param int $pos 144531e725cSNickeau * @param Doku_Handler $handler 145531e725cSNickeau * @return array|bool 146531e725cSNickeau * @see DokuWiki_Syntax_Plugin::handle() 147531e725cSNickeau * 148531e725cSNickeau */ 149531e725cSNickeau function handle($match, $state, $pos, Doku_Handler $handler) 150531e725cSNickeau { 151531e725cSNickeau 152531e725cSNickeau switch ($state) { 153531e725cSNickeau 154531e725cSNickeau case DOKU_LEXER_ENTER: 155531e725cSNickeau 156*04fd306cSNickeau $knownTypes = []; 157*04fd306cSNickeau $defaultAttributes = []; 158*04fd306cSNickeau $attributes = TagAttributes::createFromTagMatch($match, $defaultAttributes, $knownTypes)->toCallStackArray(); 159*04fd306cSNickeau 160*04fd306cSNickeau LogUtility::warning("Cell (Col) has been deprecated for box (You can use now any component in a grid or row).", GridTag::TAG); 161531e725cSNickeau return array( 162531e725cSNickeau PluginUtility::STATE => $state, 163531e725cSNickeau PluginUtility::ATTRIBUTES => $attributes); 164531e725cSNickeau 165531e725cSNickeau case DOKU_LEXER_UNMATCHED: 166531e725cSNickeau return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler); 167531e725cSNickeau 168531e725cSNickeau case DOKU_LEXER_EXIT : 169531e725cSNickeau 170*04fd306cSNickeau $callStack = CallStack::createFromHandler($handler); 171*04fd306cSNickeau $openingTag = $callStack->moveToPreviousCorrespondingOpeningCall(); 172*04fd306cSNickeau $firstChild = $callStack->moveToFirstChildTag(); 173*04fd306cSNickeau 174*04fd306cSNickeau /** 175*04fd306cSNickeau * A cell is a flex container that helps place its children 176*04fd306cSNickeau * It should contain one or more container 177*04fd306cSNickeau * It should have at minimum one 178*04fd306cSNickeau */ 179*04fd306cSNickeau $addChildContainer = true; 180*04fd306cSNickeau if ($firstChild !== false) { 181*04fd306cSNickeau if (in_array($firstChild->getTagName(), TagAttributes::CONTAINER_LOGICAL_ELEMENTS)) { 182*04fd306cSNickeau $addChildContainer = false; 183*04fd306cSNickeau } 184*04fd306cSNickeau } 185*04fd306cSNickeau if ($addChildContainer === true) { 186*04fd306cSNickeau /** 187*04fd306cSNickeau * A cell should have one or more container as child 188*04fd306cSNickeau * If the container is not in the markup, we add it 189*04fd306cSNickeau */ 190*04fd306cSNickeau $callStack->moveToCall($openingTag); 191*04fd306cSNickeau $callStack->insertAfter( 192*04fd306cSNickeau Call::createComboCall( 193*04fd306cSNickeau BoxTag::TAG, 194*04fd306cSNickeau DOKU_LEXER_ENTER, 195*04fd306cSNickeau [], 196*04fd306cSNickeau null, 197*04fd306cSNickeau null, 198*04fd306cSNickeau null, 199*04fd306cSNickeau null, 200*04fd306cSNickeau \syntax_plugin_combo_xmlblocktag::TAG 201*04fd306cSNickeau )); 202*04fd306cSNickeau $callStack->moveToEnd(); 203*04fd306cSNickeau $callStack->insertBefore( 204*04fd306cSNickeau Call::createComboCall( 205*04fd306cSNickeau BoxTag::TAG, 206*04fd306cSNickeau DOKU_LEXER_EXIT, 207*04fd306cSNickeau [], 208*04fd306cSNickeau null, 209*04fd306cSNickeau null, 210*04fd306cSNickeau null, 211*04fd306cSNickeau null, 212*04fd306cSNickeau \syntax_plugin_combo_xmlblocktag::TAG 213*04fd306cSNickeau )); 214*04fd306cSNickeau } 215*04fd306cSNickeau 216*04fd306cSNickeau 217531e725cSNickeau return array( 218531e725cSNickeau PluginUtility::STATE => $state 219531e725cSNickeau ); 220531e725cSNickeau 221531e725cSNickeau 222531e725cSNickeau } 223531e725cSNickeau 224531e725cSNickeau return array(); 225531e725cSNickeau 226531e725cSNickeau } 227531e725cSNickeau 228531e725cSNickeau /** 229531e725cSNickeau * Render the output 230531e725cSNickeau * @param string $format 231531e725cSNickeau * @param Doku_Renderer $renderer 232531e725cSNickeau * @param array $data - what the function handle() return'ed 233531e725cSNickeau * @return boolean - rendered correctly? (however, returned value is not used at the moment) 234531e725cSNickeau * @see DokuWiki_Syntax_Plugin::render() 235531e725cSNickeau * 236531e725cSNickeau * 237531e725cSNickeau */ 238*04fd306cSNickeau function render($format, Doku_Renderer $renderer, $data): bool 239531e725cSNickeau { 240531e725cSNickeau 241531e725cSNickeau if ($format == 'xhtml') { 242531e725cSNickeau 243531e725cSNickeau /** @var Doku_Renderer_xhtml $renderer */ 244531e725cSNickeau $state = $data[PluginUtility::STATE]; 245531e725cSNickeau switch ($state) { 246531e725cSNickeau 247531e725cSNickeau case DOKU_LEXER_ENTER : 248531e725cSNickeau 249*04fd306cSNickeau PluginUtility::getSnippetManager()->attachCssInternalStyleSheet(self::TAG); 250531e725cSNickeau $callStackArray = $data[PluginUtility::ATTRIBUTES]; 251531e725cSNickeau $attributes = TagAttributes::createFromCallStackArray($callStackArray, self::TAG); 252531e725cSNickeau /** 253*04fd306cSNickeau * A flex to be able to align the children (horizontal/vertical) 254*04fd306cSNickeau * if they are constraint in width 255531e725cSNickeau */ 256*04fd306cSNickeau $attributes->addClassName(self::FLEX_CLASS); 257*04fd306cSNickeau /** 258*04fd306cSNickeau * Horizontal (center) 259*04fd306cSNickeau */ 260*04fd306cSNickeau $attributes->addClassName("justify-content-center"); 261*04fd306cSNickeau 262*04fd306cSNickeau $renderer->doc .= $attributes->toHtmlEnterTag("div"); 263531e725cSNickeau break; 264531e725cSNickeau 265531e725cSNickeau case DOKU_LEXER_UNMATCHED : 266531e725cSNickeau 267531e725cSNickeau $renderer->doc .= PluginUtility::renderUnmatched($data); 268531e725cSNickeau break; 269531e725cSNickeau 270531e725cSNickeau case DOKU_LEXER_EXIT : 271531e725cSNickeau 272*04fd306cSNickeau $renderer->doc .= '</div>'; 273531e725cSNickeau break; 274531e725cSNickeau } 275531e725cSNickeau return true; 276531e725cSNickeau } 277531e725cSNickeau return false; 278531e725cSNickeau } 279531e725cSNickeau 280531e725cSNickeau 281531e725cSNickeau} 282