1*531e725cSNickeau<?php 2*531e725cSNickeau/** 3*531e725cSNickeau * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4*531e725cSNickeau * 5*531e725cSNickeau * This source code is licensed under the GPL license found in the 6*531e725cSNickeau * COPYING file in the root directory of this source tree. 7*531e725cSNickeau * 8*531e725cSNickeau * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9*531e725cSNickeau * @author ComboStrap <support@combostrap.com> 10*531e725cSNickeau * 11*531e725cSNickeau */ 12*531e725cSNickeau 13*531e725cSNickeauuse ComboStrap\ConditionalValue; 14*531e725cSNickeauuse ComboStrap\PluginUtility; 15*531e725cSNickeauuse ComboStrap\TagAttributes; 16*531e725cSNickeau 17*531e725cSNickeau 18*531e725cSNickeaurequire_once(__DIR__ . '/../class/PluginUtility.php'); 19*531e725cSNickeau 20*531e725cSNickeau/** 21*531e725cSNickeau * The {@link https://combostrap.com/column column} of a {@link https://combostrap.com/grid grid} 22*531e725cSNickeau * 23*531e725cSNickeau * 24*531e725cSNickeau * Note: The name of the class must follow this pattern ie syntax_plugin_PluginName_ComponentName 25*531e725cSNickeau */ 26*531e725cSNickeauclass syntax_plugin_combo_cell extends DokuWiki_Syntax_Plugin 27*531e725cSNickeau{ 28*531e725cSNickeau 29*531e725cSNickeau const TAG = "cell"; 30*531e725cSNickeau 31*531e725cSNickeau const WIDTH_ATTRIBUTE = TagAttributes::WIDTH_KEY; 32*531e725cSNickeau const VERTICAL_ATTRIBUTE = "vertical"; 33*531e725cSNickeau 34*531e725cSNickeau static function getTags() 35*531e725cSNickeau { 36*531e725cSNickeau return [self::TAG, "col", "column"]; 37*531e725cSNickeau } 38*531e725cSNickeau 39*531e725cSNickeau /** 40*531e725cSNickeau * Syntax Type. 41*531e725cSNickeau * 42*531e725cSNickeau * Needs to return one of the mode types defined in $PARSER_MODES in parser.php 43*531e725cSNickeau * @see DokuWiki_Syntax_Plugin::getType() 44*531e725cSNickeau */ 45*531e725cSNickeau function getType() 46*531e725cSNickeau { 47*531e725cSNickeau return 'container'; 48*531e725cSNickeau } 49*531e725cSNickeau 50*531e725cSNickeau /** 51*531e725cSNickeau * @return array 52*531e725cSNickeau * Allow which kind of plugin inside 53*531e725cSNickeau * All 54*531e725cSNickeau */ 55*531e725cSNickeau public function getAllowedTypes() 56*531e725cSNickeau { 57*531e725cSNickeau return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); 58*531e725cSNickeau } 59*531e725cSNickeau 60*531e725cSNickeau public function accepts($mode) 61*531e725cSNickeau { 62*531e725cSNickeau 63*531e725cSNickeau /** 64*531e725cSNickeau * header mode is disable to take over 65*531e725cSNickeau * and replace it with {@link syntax_plugin_combo_heading} 66*531e725cSNickeau */ 67*531e725cSNickeau if ($mode == "header") { 68*531e725cSNickeau return false; 69*531e725cSNickeau } 70*531e725cSNickeau 71*531e725cSNickeau 72*531e725cSNickeau return syntax_plugin_combo_preformatted::disablePreformatted($mode); 73*531e725cSNickeau 74*531e725cSNickeau } 75*531e725cSNickeau 76*531e725cSNickeau /** 77*531e725cSNickeau * How Dokuwiki will add P element 78*531e725cSNickeau * 79*531e725cSNickeau * * 'normal' - The plugin can be used inside paragraphs 80*531e725cSNickeau * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 81*531e725cSNickeau * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 82*531e725cSNickeau * 83*531e725cSNickeau * @see DokuWiki_Syntax_Plugin::getPType() 84*531e725cSNickeau */ 85*531e725cSNickeau function getPType() 86*531e725cSNickeau { 87*531e725cSNickeau return 'stack'; 88*531e725cSNickeau } 89*531e725cSNickeau 90*531e725cSNickeau /** 91*531e725cSNickeau * @see Doku_Parser_Mode::getSort() 92*531e725cSNickeau * 93*531e725cSNickeau * the mode with the lowest sort number will win out 94*531e725cSNickeau * the container (parent) must then have a lower number than the child 95*531e725cSNickeau */ 96*531e725cSNickeau function getSort() 97*531e725cSNickeau { 98*531e725cSNickeau return 100; 99*531e725cSNickeau } 100*531e725cSNickeau 101*531e725cSNickeau /** 102*531e725cSNickeau * Create a pattern that will called this plugin 103*531e725cSNickeau * 104*531e725cSNickeau * @param string $mode 105*531e725cSNickeau * @see Doku_Parser_Mode::connectTo() 106*531e725cSNickeau */ 107*531e725cSNickeau function connectTo($mode) 108*531e725cSNickeau { 109*531e725cSNickeau 110*531e725cSNickeau // A cell can be anywhere 111*531e725cSNickeau foreach (self::getTags() as $tag) { 112*531e725cSNickeau $pattern = PluginUtility::getContainerTagPattern($tag); 113*531e725cSNickeau $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeForComponent($this->getPluginComponent())); 114*531e725cSNickeau } 115*531e725cSNickeau 116*531e725cSNickeau 117*531e725cSNickeau } 118*531e725cSNickeau 119*531e725cSNickeau public function postConnect() 120*531e725cSNickeau { 121*531e725cSNickeau 122*531e725cSNickeau foreach (self::getTags() as $tag) { 123*531e725cSNickeau $this->Lexer->addExitPattern('</' . $tag . '>', PluginUtility::getModeForComponent($this->getPluginComponent())); 124*531e725cSNickeau } 125*531e725cSNickeau 126*531e725cSNickeau } 127*531e725cSNickeau 128*531e725cSNickeau /** 129*531e725cSNickeau * 130*531e725cSNickeau * The handle function goal is to parse the matched syntax through the pattern function 131*531e725cSNickeau * and to return the result for use in the renderer 132*531e725cSNickeau * This result is always cached until the page is modified. 133*531e725cSNickeau * @param string $match 134*531e725cSNickeau * @param int $state 135*531e725cSNickeau * @param int $pos 136*531e725cSNickeau * @param Doku_Handler $handler 137*531e725cSNickeau * @return array|bool 138*531e725cSNickeau * @see DokuWiki_Syntax_Plugin::handle() 139*531e725cSNickeau * 140*531e725cSNickeau */ 141*531e725cSNickeau function handle($match, $state, $pos, Doku_Handler $handler) 142*531e725cSNickeau { 143*531e725cSNickeau 144*531e725cSNickeau switch ($state) { 145*531e725cSNickeau 146*531e725cSNickeau case DOKU_LEXER_ENTER: 147*531e725cSNickeau 148*531e725cSNickeau $attributes = TagAttributes::createFromTagMatch($match)->toCallStackArray(); 149*531e725cSNickeau return array( 150*531e725cSNickeau PluginUtility::STATE => $state, 151*531e725cSNickeau PluginUtility::ATTRIBUTES => $attributes); 152*531e725cSNickeau 153*531e725cSNickeau case DOKU_LEXER_UNMATCHED: 154*531e725cSNickeau return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler); 155*531e725cSNickeau 156*531e725cSNickeau case DOKU_LEXER_EXIT : 157*531e725cSNickeau 158*531e725cSNickeau return array( 159*531e725cSNickeau PluginUtility::STATE => $state 160*531e725cSNickeau ); 161*531e725cSNickeau 162*531e725cSNickeau 163*531e725cSNickeau } 164*531e725cSNickeau 165*531e725cSNickeau return array(); 166*531e725cSNickeau 167*531e725cSNickeau } 168*531e725cSNickeau 169*531e725cSNickeau /** 170*531e725cSNickeau * Render the output 171*531e725cSNickeau * @param string $format 172*531e725cSNickeau * @param Doku_Renderer $renderer 173*531e725cSNickeau * @param array $data - what the function handle() return'ed 174*531e725cSNickeau * @return boolean - rendered correctly? (however, returned value is not used at the moment) 175*531e725cSNickeau * @see DokuWiki_Syntax_Plugin::render() 176*531e725cSNickeau * 177*531e725cSNickeau * 178*531e725cSNickeau */ 179*531e725cSNickeau function render($format, Doku_Renderer $renderer, $data) 180*531e725cSNickeau { 181*531e725cSNickeau 182*531e725cSNickeau if ($format == 'xhtml') { 183*531e725cSNickeau 184*531e725cSNickeau /** @var Doku_Renderer_xhtml $renderer */ 185*531e725cSNickeau $state = $data[PluginUtility::STATE]; 186*531e725cSNickeau switch ($state) { 187*531e725cSNickeau 188*531e725cSNickeau case DOKU_LEXER_ENTER : 189*531e725cSNickeau 190*531e725cSNickeau PluginUtility::getSnippetManager()->attachCssSnippetForBar(self::TAG); 191*531e725cSNickeau $callStackArray = $data[PluginUtility::ATTRIBUTES]; 192*531e725cSNickeau $attributes = TagAttributes::createFromCallStackArray($callStackArray, self::TAG); 193*531e725cSNickeau $attributes->addClassName("col"); 194*531e725cSNickeau if ($attributes->hasComponentAttribute(self::VERTICAL_ATTRIBUTE)) { 195*531e725cSNickeau $value = $attributes->getValue(self::VERTICAL_ATTRIBUTE); 196*531e725cSNickeau if ($value == "center") { 197*531e725cSNickeau //$attributes->addClassName("d-inline-flex"); 198*531e725cSNickeau $attributes->addClassName("align-self-center"); 199*531e725cSNickeau } 200*531e725cSNickeau } 201*531e725cSNickeau if ($attributes->hasComponentAttribute(syntax_plugin_combo_cell::WIDTH_ATTRIBUTE)) { 202*531e725cSNickeau $sizeValues = $attributes->getValuesAndRemove(syntax_plugin_combo_cell::WIDTH_ATTRIBUTE); 203*531e725cSNickeau foreach ($sizeValues as $sizeValue) { 204*531e725cSNickeau $conditionalValue = ConditionalValue::createFrom($sizeValue); 205*531e725cSNickeau if ($conditionalValue->getBreakpoint() == "xs") { 206*531e725cSNickeau $attributes->addClassName("col-" . $conditionalValue->getValue()); 207*531e725cSNickeau } else { 208*531e725cSNickeau if ($conditionalValue->getBreakpoint() != null) { 209*531e725cSNickeau $attributes->addClassName("col-$sizeValue"); 210*531e725cSNickeau } else { 211*531e725cSNickeau /** 212*531e725cSNickeau * No breakpoint given 213*531e725cSNickeau * If this is a number between 1 and 12, 214*531e725cSNickeau * we take the assumption that this is a ratio 215*531e725cSNickeau * otherwise, this a width in CSS length 216*531e725cSNickeau */ 217*531e725cSNickeau if ($sizeValue >= 1 && $sizeValue <= syntax_plugin_combo_row::GRID_TOTAL_COLUMNS) { 218*531e725cSNickeau $attributes->addClassName("col-$sizeValue"); 219*531e725cSNickeau } else { 220*531e725cSNickeau $attributes->addComponentAttributeValue(TagAttributes::WIDTH_KEY, $sizeValue); 221*531e725cSNickeau } 222*531e725cSNickeau } 223*531e725cSNickeau } 224*531e725cSNickeau } 225*531e725cSNickeau } 226*531e725cSNickeau $renderer->doc .= $attributes->toHtmlEnterTag("div") . DOKU_LF; 227*531e725cSNickeau break; 228*531e725cSNickeau 229*531e725cSNickeau case DOKU_LEXER_UNMATCHED : 230*531e725cSNickeau 231*531e725cSNickeau $renderer->doc .= PluginUtility::renderUnmatched($data); 232*531e725cSNickeau break; 233*531e725cSNickeau 234*531e725cSNickeau case DOKU_LEXER_EXIT : 235*531e725cSNickeau 236*531e725cSNickeau $renderer->doc .= '</div>' . DOKU_LF; 237*531e725cSNickeau break; 238*531e725cSNickeau } 239*531e725cSNickeau return true; 240*531e725cSNickeau } 241*531e725cSNickeau return false; 242*531e725cSNickeau } 243*531e725cSNickeau 244*531e725cSNickeau 245*531e725cSNickeau} 246