1<?php 2 3 4use ComboStrap\PluginUtility; 5use ComboStrap\TagAttributes; 6use ComboStrap\XmlTagProcessing; 7 8 9/** 10 * Class syntax_plugin_combo_list 11 * Implementation of a list 12 * 13 * This component is not not public 14 * 15 */ 16class syntax_plugin_combo_contentlistitem extends DokuWiki_Syntax_Plugin 17{ 18 19 const DOKU_TAG = "contentlistitem"; 20 const MARKI_TAG = "content-list-item"; 21 const ALL_TAGS = array(self::MARKI_TAG, "list-item", "li"); 22 const LIST_GROUP_ITEM_CLASS = "list-group-item"; 23 24 25 /** 26 * Syntax Type. 27 * 28 * Needs to return one of the mode types defined in $PARSER_MODES in parser.php 29 * @see https://www.dokuwiki.org/devel:syntax_plugins#syntax_types 30 * @see DokuWiki_Syntax_Plugin::getType() 31 */ 32 function getType() 33 { 34 return 'container'; 35 } 36 37 /** 38 * How Dokuwiki will add P element 39 * 40 * * 'normal' - Inline 41 * * 'block' - Block (p are not created inside) 42 * * 'stack' - Block (p can be created inside) 43 * 44 * @see DokuWiki_Syntax_Plugin::getPType() 45 * @see https://www.dokuwiki.org/devel:syntax_plugins#ptype 46 */ 47 function getPType() 48 { 49 /** 50 * No paragraph inside, this is a layout 51 */ 52 return 'block'; 53 } 54 55 public function accepts($mode) 56 { 57 return syntax_plugin_combo_preformatted::disablePreformatted($mode); 58 } 59 60 61 /** 62 * @return array 63 * Allow which kind of plugin inside 64 * 65 * No one of array('baseonly','container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs') 66 * because we manage self the content and we call self the parser 67 * 68 * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php 69 */ 70 function getAllowedTypes() 71 { 72 return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); 73 } 74 75 /** 76 * @see Doku_Parser_Mode::getSort() 77 * the mode with the lowest sort number will win out 78 * Higher than {@link syntax_plugin_combo_contentlist} 79 * but less than {@link syntax_plugin_combo_preformatted} 80 */ 81 function getSort() 82 { 83 return 18; 84 } 85 86 87 function connectTo($mode) 88 { 89 90 /** 91 * This is now know as `row` 92 * This is the old tags 93 */ 94 foreach (self::ALL_TAGS as $tag) { 95 $pattern = XmlTagProcessing::getContainerTagPattern($tag); 96 $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 97 } 98 99 100 } 101 102 public function postConnect() 103 { 104 foreach (self::ALL_TAGS as $tag) { 105 $this->Lexer->addExitPattern('</' . $tag . '>', PluginUtility::getModeFromTag($this->getPluginComponent())); 106 } 107 108 } 109 110 111 /** 112 * 113 * The handle function goal is to parse the matched syntax through the pattern function 114 * and to return the result for use in the renderer 115 * This result is always cached until the page is modified. 116 * @param string $match 117 * @param int $state 118 * @param int $pos - byte position in the original source file 119 * @param Doku_Handler $handler 120 * @return array|bool 121 * @see DokuWiki_Syntax_Plugin::handle() 122 * 123 */ 124 function handle($match, $state, $pos, Doku_Handler $handler) 125 { 126 127 switch ($state) { 128 129 case DOKU_LEXER_ENTER : 130 131 $attributes = TagAttributes::createFromTagMatch($match); 132 $tag = PluginUtility::getMarkupTag($match); 133 return array( 134 PluginUtility::STATE => $state, 135 PluginUtility::ATTRIBUTES => $attributes->toCallStackArray(), 136 PluginUtility::PAYLOAD=>$tag 137 ); 138 139 case DOKU_LEXER_UNMATCHED : 140 return PluginUtility::handleAndReturnUnmatchedData(self::DOKU_TAG, $match, $handler); 141 142 case DOKU_LEXER_EXIT : 143 144 return array( 145 PluginUtility::STATE => $state 146 ); 147 148 149 } 150 return array(); 151 152 } 153 154 /** 155 * Render the output 156 * @param string $format 157 * @param Doku_Renderer $renderer 158 * @param array $data - what the function handle() return'ed 159 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 160 * @see DokuWiki_Syntax_Plugin::render() 161 * 162 * 163 */ 164 function render($format, Doku_Renderer $renderer, $data) 165 { 166 167 /** 168 * The normal flow is that the `row` in a content 169 * list are transformed to `content-list-item` in the {@link DOKU_LEXER_EXIT} state 170 * of {@link syntax_plugin_combo_contentlist::handle()} 171 * 172 */ 173 if ($format == 'xhtml') { 174 175 /** @var Doku_Renderer_xhtml $renderer */ 176 $state = $data[PluginUtility::STATE]; 177 switch ($state) { 178 case DOKU_LEXER_ENTER : 179 $tagAttributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES], self::MARKI_TAG); 180 $tagAttributes->addClassName(self::LIST_GROUP_ITEM_CLASS); 181 $renderer->doc .= $tagAttributes->toHtmlEnterTag("li"); 182 break; 183 case DOKU_LEXER_EXIT : 184 $renderer->doc .= "</li>" . DOKU_LF; 185 break; 186 case DOKU_LEXER_UNMATCHED : 187 $render = PluginUtility::renderUnmatched($data); 188 if (!empty($render)) { 189 $renderer->doc .= "<span>" . $render . '</span>'; 190 } 191 break; 192 } 193 return true; 194 } 195 196 // unsupported $mode 197 return false; 198 } 199 200 201} 202 203