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