1<?php 2 3namespace ComboStrap; 4 5 6use ComboStrap\Tag\AdTag; 7use ComboStrap\Tag\BackgroundTag; 8use ComboStrap\Tag\BarTag; 9use ComboStrap\Tag\BoxTag; 10use ComboStrap\Tag\FollowTag; 11use ComboStrap\Tag\MermaidTag; 12use ComboStrap\Tag\RelatedTag; 13use ComboStrap\Tag\ShareTag; 14use ComboStrap\Tag\SubscribeTag; 15use ComboStrap\Tag\TableTag; 16use ComboStrap\Tag\WebCodeTag; 17use ComboStrap\TagAttribute\Hero; 18use Doku_Handler; 19use Doku_Renderer; 20use Doku_Renderer_metadata; 21use Doku_Renderer_xhtml; 22use DokuWiki_Syntax_Plugin; 23use Mpdf\Tag\Sub; 24use renderer_plugin_combo_analytics; 25use renderer_plugin_combo_xml; 26use syntax_plugin_combo_code; 27 28 29class XmlTagProcessing 30{ 31 32 33 /** 34 * The start tag pattern does not allow > or / 35 * in the data to not compete with the empty tag pattern (ie <empty/> 36 */ 37 public const START_TAG_PATTERN = '<[\w-]+[^/>]*>'; 38 39 40 public static function renderStaticExitXhtml(TagAttributes $tagAttributes, Doku_Renderer_xhtml $renderer, array $data, DokuWiki_Syntax_Plugin $plugin): bool 41 { 42 $logicalTag = $tagAttributes->getLogicalTag(); 43 switch ($logicalTag) { 44 case BlockquoteTag::TAG: 45 BlockquoteTag::renderExitXhtml($tagAttributes, $renderer, $data); 46 return true; 47 case BoxTag::TAG: 48 $renderer->doc .= BoxTag::renderExitXhtml($tagAttributes); 49 return true; 50 case ButtonTag::LOGICAL_TAG: 51 $renderer->doc .= ButtonTag::renderExitXhtml($data); 52 return true; 53 case CardTag::LOGICAL_TAG: 54 CardTag::handleExitXhtml($data, $renderer); 55 return true; 56 case BarTag::LOGICAL_TAG: 57 $renderer->doc .= BarTag::renderExitXhtml($data); 58 return true; 59 case CarrouselTag::TAG: 60 $renderer->doc .= CarrouselTag::renderExitXhtml(); 61 return true; 62 case PrismTags::CONSOLE_TAG: 63 case PrismTags::FILE_TAG: 64 PrismTags::processExitXhtml($tagAttributes, $renderer); 65 return true; 66 case ContainerTag::TAG: 67 $renderer->doc .= ContainerTag::renderExitXhtml(); 68 return true; 69 case GridTag::LOGICAL_TAG: 70 $renderer->doc .= GridTag::renderExitXhtml($tagAttributes); 71 return true; 72 case PipelineTag::TAG: 73 case DateTag::TAG: 74 case PageExplorerTag::LOGICAL_TAG: 75 case PermalinkTag::TAG: 76 case IconTag::TAG: 77 case MermaidTag::LOGICAL_TAG: 78 return true; 79 case DropDownTag::TAG: 80 $renderer->doc .= DropDownTag::renderExitXhtml(); 81 return true; 82 case HeadingTag::LOGICAL_TAG: 83 $context = $data[PluginUtility::CONTEXT]; 84 $renderer->doc .= HeadingTag::renderClosingTag($tagAttributes, $context); 85 return true; 86 case NoteTag::TAG_INOTE: 87 $renderer->doc .= NoteTag::renderClosingInlineNote(); 88 return true; 89 case JumbotronTag::TAG: 90 $renderer->doc .= JumbotronTag::renderExitHtml(); 91 return true; 92 case MasonryTag::LOGICAL_TAG: 93 $renderer->doc .= MasonryTag::renderExitHtml(); 94 return true; 95 case SectionTag::TAG: 96 $renderer->doc .= SectionTag::renderExitXhtml(); 97 return true; 98 case TabsTag::TAG: 99 $renderer->doc .= TabsTag::renderExitXhtml($tagAttributes, $data); 100 return true; 101 case PanelTag::PANEL_LOGICAL_MARKUP: 102 $renderer->doc .= PanelTag::renderExitXhtml($data); 103 return true; 104 case BackgroundTag::LOGICAL_TAG: 105 $renderer->doc .= BackgroundTag::renderExitSpecialHtml($data); 106 return true; 107 case WebCodeTag::TAG: 108 $renderer->doc .= WebCodeTag::renderExit($tagAttributes, $data); 109 return true; 110 case ShareTag::MARKUP: 111 $renderer->doc .= ShareTag::renderExit(); 112 return true; 113 case FollowTag::MARKUP: 114 $renderer->doc .= FollowTag::renderExit(); 115 return true; 116 default: 117 LogUtility::warning("The exit tag (" . $logicalTag . ") was not processed."); 118 return false; 119 } 120 121 } 122 123 /** 124 * Static because it handle inline and block tag 125 * @param string $match 126 * @param int $state 127 * @param int $pos 128 * @param Doku_Handler $handler 129 * @param DokuWiki_Syntax_Plugin $plugin 130 * @return array 131 */ 132 public static function handleStatic(string $match, int $state, int $pos, Doku_Handler $handler, DokuWiki_Syntax_Plugin $plugin): array 133 { 134 /** 135 * Logical Tag Building 136 */ 137 switch ($state) { 138 139 case DOKU_LEXER_ENTER: 140 141 return self::handleStaticEnter($match, $pos, $handler, $plugin); 142 143 case DOKU_LEXER_UNMATCHED : 144 145 $data = PluginUtility::handleAndReturnUnmatchedData(null, $match, $handler); 146 /** 147 * Attribute of parent are send for context 148 * (example `display = none`) 149 */ 150 $callStack = CallStack::createFromHandler($handler); 151 $parentTag = $callStack->moveToParent(); 152 if ($parentTag !== false) { 153 $tagAttributes = $parentTag->getAttributes(); 154 $data[PluginUtility::ATTRIBUTES] = $tagAttributes; 155 } 156 return $data; 157 158 case DOKU_LEXER_EXIT : 159 160 return self::handleStaticExit($match, $pos, $handler, $plugin); 161 162 163 default: 164 throw new ExceptionRuntimeInternal("Should not happen"); 165 } 166 } 167 168 public static function renderStaticEnterXhtml(TagAttributes $tagAttributes, Doku_Renderer_xhtml $renderer, array $data, DokuWiki_Syntax_Plugin $plugin): bool 169 { 170 171 $context = $data[PluginUtility::CONTEXT]; 172 $pos = $data[PluginUtility::POSITION]; 173 $logicalTag = $tagAttributes->getLogicalTag(); 174 switch ($logicalTag) { 175 case BlockquoteTag::TAG: 176 $renderer->doc .= BlockquoteTag::renderEnterXhtml($tagAttributes, $data, $renderer); 177 return true; 178 case BoxTag::TAG: 179 $renderer->doc .= BoxTag::renderEnterXhtml($tagAttributes); 180 return true; 181 case ButtonTag::LOGICAL_TAG: 182 $renderer->doc .= ButtonTag::renderEnterXhtml($tagAttributes, $plugin, $data); 183 return true; 184 case CardTag::LOGICAL_TAG: 185 $renderer->doc .= CardTag::renderEnterXhtml($tagAttributes, $renderer, $data); 186 return true; 187 case BarTag::LOGICAL_TAG: 188 $renderer->doc .= BarTag::renderEnterXhtml($tagAttributes, $data); 189 return true; 190 case CarrouselTag::TAG: 191 $renderer->doc .= CarrouselTag::renderEnterXhtml($tagAttributes, $data); 192 return true; 193 case PrismTags::CONSOLE_TAG: 194 case PrismTags::FILE_TAG: 195 PrismTags::processEnterXhtml($tagAttributes, $plugin, $renderer); 196 return true; 197 case ContainerTag::TAG: 198 $renderer->doc .= ContainerTag::renderEnterXhtml($tagAttributes); 199 return true; 200 case GridTag::LOGICAL_TAG: 201 $renderer->doc .= GridTag::renderEnterXhtml($tagAttributes); 202 return true; 203 case PipelineTag::TAG: 204 $renderer->doc .= PipelineTag::renderEnterXhtml($tagAttributes); 205 return true; 206 case DateTag::TAG: 207 $renderer->doc .= DateTag::renderHtml($tagAttributes); 208 return true; 209 case DropDownTag::TAG: 210 $renderer->doc .= DropDownTag::renderEnterXhtml($tagAttributes); 211 return true; 212 case HeadingTag::LOGICAL_TAG: 213 HeadingTag::processRenderEnterXhtml($context, $tagAttributes, $renderer, $pos); 214 return true; 215 case NoteTag::TAG_INOTE: 216 $renderer->doc .= NoteTag::renderEnterInlineNote($tagAttributes); 217 return true; 218 case JumbotronTag::TAG: 219 $renderer->doc .= JumbotronTag::renderEnterXhtml($tagAttributes); 220 return true; 221 case MasonryTag::LOGICAL_TAG: 222 $renderer->doc .= MasonryTag::renderEnterTag(); 223 return true; 224 case PageExplorerTag::LOGICAL_TAG: 225 $renderer->doc .= PageExplorerTag::renderEnterTag($tagAttributes, $data); 226 return true; 227 case SectionTag::TAG: 228 $renderer->doc .= SectionTag::renderEnterXhtml($tagAttributes); 229 return true; 230 case TabsTag::TAG: 231 $renderer->doc .= TabsTag::renderEnterXhtml($tagAttributes, $data); 232 return true; 233 case PanelTag::PANEL_LOGICAL_MARKUP: 234 $renderer->doc .= PanelTag::renderEnterXhtml($tagAttributes, $data); 235 return true; 236 case PermalinkTag::TAG: 237 $renderer->doc .= PermalinkTag::renderEnterSpecialXhtml($data); 238 return true; 239 case HrTag::TAG: 240 $renderer->doc .= HrTag::render($tagAttributes); 241 return true; 242 case IconTag::TAG: 243 $renderer->doc .= IconTag::renderEnterTag($tagAttributes); 244 return true; 245 case BackgroundTag::LOGICAL_TAG: 246 $renderer->doc .= BackgroundTag::renderEnterTag(); 247 return true; 248 case MermaidTag::LOGICAL_TAG: 249 $renderer->doc .= MermaidTag::renderEnter($tagAttributes); 250 return true; 251 case WebCodeTag::TAG: 252 return true; 253 case ShareTag::MARKUP: 254 $renderer->doc .= ShareTag::renderSpecialEnter($tagAttributes, DOKU_LEXER_ENTER); 255 return true; 256 case FollowTag::MARKUP: 257 $renderer->doc .= FollowTag::renderSpecialEnterNode($tagAttributes, DOKU_LEXER_ENTER); 258 return true; 259 case TableTag::TAG: 260 TableTag::renderEnterXhtml($tagAttributes, $renderer); 261 return true; 262 case RelatedTag::TAG: 263 LogUtility::warning("The related tag should be closed. You should write <related/> and not <related>."); 264 $renderer->doc .= RelatedTag::render($tagAttributes); 265 return true; 266 default: 267 LogUtility::warning("The enter tag (" . $logicalTag . ") was not processed."); 268 return false; 269 } 270 } 271 272 public static function handleStaticEnter(string $match, int $pos, Doku_Handler $handler, DokuWiki_Syntax_Plugin $plugin): array 273 { 274 // context data 275 $executionContext = ExecutionContext::getActualOrCreateFromEnv(); 276 277 // Normalize Trim and delete eol to start clean 278 $match = trim($match); 279 $match = str_replace("\n"," ",$match); 280 281 // Markup 282 $markupTag = PluginUtility::getMarkupTag($match); 283 $logicalTag = $markupTag; 284 $defaultAttributes = []; 285 $knownTypes = []; 286 $allowAnyFirstBooleanAttributesAsType = false; 287 288 // code block allow a second attribute value as file name 289 $hasTwoBooleanAttribute = false; 290 $secondBooleanAttribute = null; 291 292 switch ($markupTag) { 293 case BlockquoteTag::TAG: 294 // Suppress the component name 295 $defaultAttributes = array("type" => BlockquoteTag::CARD_TYPE); 296 $knownTypes = [BlockquoteTag::TYPO_TYPE, BlockquoteTag::CARD_TYPE];; 297 break; 298 case BoxTag::TAG: 299 $defaultAttributes[BoxTag::HTML_TAG_ATTRIBUTE] = BoxTag::DEFAULT_HTML_TAG; 300 $defaultAttributes[BoxTag::LOGICAL_TAG_ATTRIBUTE] = BoxTag::LOGICAL_TAG_DEFAUT; 301 break; 302 case ButtonTag::MARKUP_SHORT: 303 case ButtonTag::MARKUP_LONG: 304 $logicalTag = ButtonTag::LOGICAL_TAG; 305 $knownTypes = ButtonTag::TYPES; 306 $defaultAttributes = array( 307 Skin::SKIN_ATTRIBUTE => Skin::FILLED_VALUE, 308 TagAttributes::TYPE_KEY => ColorRgb::PRIMARY_VALUE 309 ); 310 break; 311 case CardTag::CARD_TAG: 312 case CardTag::TEASER_TAG: 313 $logicalTag = CardTag::LOGICAL_TAG; 314 break; 315 case BarTag::BAR_TAG: 316 case BarTag::SLIDE_TAG: 317 $logicalTag = BarTag::LOGICAL_TAG; 318 $defaultAttributes[Hero::ATTRIBUTE] = "sm"; 319 break; 320 case PrismTags::CONSOLE_TAG: 321 case PrismTags::FILE_TAG: 322 $hasTwoBooleanAttribute = true; 323 $secondBooleanAttribute = syntax_plugin_combo_code::FILE_PATH_KEY; 324 $allowAnyFirstBooleanAttributesAsType = true; 325 break; 326 case ContainerTag::TAG: 327 $knownTypes = ContainerTag::CONTAINER_VALUES; 328 $defaultAttributes[TagAttributes::TYPE_KEY] = $executionContext->getConfig()->getValue(ContainerTag::DEFAULT_LAYOUT_CONTAINER_CONF, ContainerTag::DEFAULT_LAYOUT_CONTAINER_DEFAULT_VALUE); 329 break; 330 case GridTag::ROW_TAG: 331 case GridTag::GRID_TAG: 332 $logicalTag = GridTag::LOGICAL_TAG; 333 $knownTypes = GridTag::KNOWN_TYPES; 334 break; 335 case HeadingTag::HEADING_TAG: 336 case HeadingTag::TITLE_TAG: 337 $logicalTag = HeadingTag::LOGICAL_TAG; 338 $knownTypes = HeadingTag::getAllTypes(); 339 break; 340 case NoteTag::TAG_INOTE: 341 $defaultConfValue = $plugin->getConf(NoteTag::INOTE_CONF_DEFAULT_ATTRIBUTES_KEY); 342 $defaultAttributes = PluginUtility::parseAttributes($defaultConfValue); 343 if (!isset($defaultAttributes[TagAttributes::TYPE_KEY])) { 344 $defaultAttributes[TagAttributes::TYPE_KEY] = "info"; 345 } 346 $knownTypes = NoteTag::KNOWN_TYPES; 347 break; 348 case JumbotronTag::TAG: 349 $defaultAttributes = JumbotronTag::getDefault(); 350 break; 351 case MasonryTag::CARD_COLUMNS_TAG: 352 case MasonryTag::TEASER_COLUMNS_TAG: 353 case MasonryTag::MASONRY_TAG: 354 $logicalTag = MasonryTag::LOGICAL_TAG; 355 break; 356 case PageExplorerTag::NTOC_MARKUP: 357 case PageExplorerTag::PAGE_EXPLORER_MARKUP: 358 $logicalTag = PageExplorerTag::LOGICAL_TAG; 359 $defaultAttributes = [TagAttributes::TYPE_KEY => PageExplorerTag::LIST_TYPE]; 360 $knownTypes = [PageExplorerTag::TYPE_TREE, PageExplorerTag::LIST_TYPE]; 361 break; 362 case PageExplorerTag::INDEX_HOME_TAG: 363 case PageExplorerTag::INDEX_TAG: 364 $logicalTag = PageExplorerTag::LOGICAL_INDEX_TAG; 365 break; 366 case PageExplorerTag::NAMESPACE_ITEM_TAG: 367 case PageExplorerTag::NAMESPACE_LONG_TAG: 368 case PageExplorerTag::NAMESPACE_SHORT_TAG: 369 $logicalTag = PageExplorerTag::NAMESPACE_LOGICAL_TAG; 370 break; 371 case PageExplorerTag::PAGE_ITEM_TAG: 372 case PageExplorerTag::PAGE_TAG: 373 $logicalTag = PageExplorerTag::PAGE_LOGICAL_TAG; 374 break; 375 case TabsTag::TAG: 376 $knownTypes = [TabsTag::ENCLOSED_PILLS_TYPE, TabsTag::ENCLOSED_TABS_TYPE, TabsTag::PILLS_TYPE, TabsTag::TABS_TYPE]; 377 break; 378 case PanelTag::PANEL_MARKUP: 379 case PanelTag::TAB_PANEL_MARKUP: 380 $logicalTag = PanelTag::PANEL_LOGICAL_MARKUP; 381 break; 382 case PermalinkTag::TAG: 383 $knownTypes = PermalinkTag::getKnownTypes(); 384 $defaultAttributes = [TagAttributes::TYPE_KEY => PermalinkTag::GENERATED_TYPE]; 385 break; 386 case BackgroundTag::MARKUP_LONG: 387 case BackgroundTag::MARKUP_SHORT: 388 $logicalTag = BackgroundTag::LOGICAL_TAG; 389 break; 390 case MermaidTag::MARKUP_MERMAID: 391 case WebCodeTag::TAG: 392 $logicalTag = Tag\WebCodeTag::TAG; 393 $defaultAttributes = WebCodeTag::getDefaultAttributes(); 394 break; 395 case MermaidTag::MARKUP_SEQUENCE_DIAGRAM: 396 case MermaidTag::MARKUP_CLASS_DIAGRAM: 397 case MermaidTag::MARKUP_FLOWCHART: 398 case MermaidTag::MARKUP_GANTT: 399 case MermaidTag::MARKUP_ERD: 400 case MermaidTag::MARKUP_JOURNEY: 401 case MermaidTag::MARKUP_PIECHART: 402 case MermaidTag::MARKUP_STATE_DIAGRAM: 403 $logicalTag = MermaidTag::LOGICAL_TAG; 404 break; 405 case ShareTag::MARKUP: 406 $knownTypes = ShareTag::getKnownTypes(); 407 break; 408 case FollowTag::MARKUP: 409 $knownTypes = FollowTag::getKnownTypes(); 410 break; 411 } 412 413 /** 414 * Build tag Attributes 415 */ 416 if (!$hasTwoBooleanAttribute) { 417 $tagAttributes = TagAttributes::createFromTagMatch($match, $defaultAttributes, $knownTypes, $allowAnyFirstBooleanAttributesAsType); 418 } else { 419 $tagAttributes = TagAttributes::createEmpty(); 420 $attributesArray = PluginUtility::getQualifiedTagAttributes($match, true, $secondBooleanAttribute, $knownTypes, $allowAnyFirstBooleanAttributesAsType); 421 foreach ($attributesArray as $key => $value) { 422 $tagAttributes->addComponentAttributeValue($key, $value); 423 } 424 } 425 $tagAttributes->setLogicalTag($logicalTag); 426 427 /** 428 * Calculate extra returned key in the table 429 */ 430 $returnedArray = []; 431 switch ($logicalTag) { 432 case BlockquoteTag::TAG: 433 $returnedArray = BlockquoteTag::handleEnter($handler); 434 break; 435 case BoxTag::TAG: 436 BoxTag::handleEnter($tagAttributes); 437 break; 438 case ButtonTag::LOGICAL_TAG: 439 $returnedArray = ButtonTag::handleEnter($tagAttributes, $handler); 440 break; 441 case CardTag::CARD_TAG: 442 $returnedArray = CardTag::handleEnter($tagAttributes, $handler); 443 break; 444 case BarTag::LOGICAL_TAG: 445 $returnedArray = BarTag::handleEnter($tagAttributes); 446 break; 447 case CarrouselTag::TAG: 448 $returnedArray = CarrouselTag::handleEnter($handler); 449 break; 450 case GridTag::LOGICAL_TAG: 451 GridTag::processEnter($tagAttributes, $handler, $match); 452 break; 453 case DateTag::TAG: 454 DateTag::handleEnterAndSpecial(); 455 break; 456 case HeadingTag::LOGICAL_TAG: 457 $returnedArray = HeadingTag::handleEnter($handler, $tagAttributes, $markupTag); 458 break; 459 case PanelTag::PANEL_LOGICAL_MARKUP: 460 $returnedArray = PanelTag::handleEnter($tagAttributes, $handler, $markupTag); 461 break; 462 case PermalinkTag::TAG: 463 $returnedArray = PermalinkTag::handleEnterSpecial($tagAttributes, DOKU_LEXER_ENTER, $handler); 464 break; 465 case IconTag::TAG: 466 $returnedArray = IconTag::handleEnter($tagAttributes, $handler); 467 break; 468 case BackgroundTag::LOGICAL_TAG: 469 BackgroundTag::handleEnterAndSpecial($tagAttributes); 470 break; 471 } 472 473 /** 474 * Common default 475 */ 476 $defaultReturnedArray[PluginUtility::STATE] = DOKU_LEXER_ENTER; 477 $defaultReturnedArray[PluginUtility::TAG] = $logicalTag; 478 $defaultReturnedArray[PluginUtility::MARKUP_TAG] = $markupTag; 479 $defaultReturnedArray[PluginUtility::POSITION] = $pos; 480 $defaultReturnedArray[PluginUtility::ATTRIBUTES] = $tagAttributes->toCallStackArray(); 481 482 return array_merge($defaultReturnedArray, $returnedArray); 483 484 } 485 486 public static function renderStatic(string $format, Doku_Renderer $renderer, array $data, DokuWiki_Syntax_Plugin $plugin): bool 487 { 488 $logicalTag = $data[PluginUtility::TAG]; 489 $attributes = $data[PluginUtility::ATTRIBUTES]; 490 $context = $data[PluginUtility::CONTEXT]; 491 $state = $data[PluginUtility::STATE]; 492 $pos = $data[PluginUtility::POSITION]; 493 $tagAttributes = TagAttributes::createFromCallStackArray($attributes)->setLogicalTag($logicalTag); 494 switch ($format) { 495 case "xhtml": 496 /** @var Doku_Renderer_xhtml $renderer */ 497 switch ($state) { 498 case DOKU_LEXER_ENTER: 499 return self::renderStaticEnterXhtml($tagAttributes, $renderer, $data, $plugin); 500 case DOKU_LEXER_UNMATCHED: 501 502 $renderer->doc .= PluginUtility::renderUnmatched($data); 503 return true; 504 505 case DOKU_LEXER_EXIT: 506 507 return XmlTagProcessing::renderStaticExitXhtml($tagAttributes, $renderer, $data, $plugin); 508 } 509 break; 510 case 'metadata': 511 /** @var Doku_Renderer_metadata $renderer */ 512 if (!in_array($state, [DOKU_LEXER_ENTER, DOKU_LEXER_SPECIAL])) { 513 return true; 514 } 515 return XmlTagProcessing::renderStaticEnterSpecialMetadata($tagAttributes, $renderer, $data, $plugin); 516 case 'xml': 517 /** @var renderer_plugin_combo_xml $renderer */ 518 switch ($state) { 519 case DOKU_LEXER_ENTER: 520 switch ($logicalTag) { 521 default: 522 case BarTag::LOGICAL_TAG: 523 $renderer->doc .= "<$logicalTag>"; 524 return true; 525 } 526 case DOKU_LEXER_UNMATCHED : 527 $renderer->doc .= PluginUtility::renderUnmatched($data); 528 break; 529 case DOKU_LEXER_EXIT : 530 switch ($logicalTag) { 531 default: 532 case BarTag::LOGICAL_TAG: 533 $renderer->doc .= "</$logicalTag>"; 534 return true; 535 } 536 } 537 return false; 538 case renderer_plugin_combo_analytics::RENDERER_FORMAT: 539 /** 540 * @var renderer_plugin_combo_analytics $renderer 541 */ 542 switch ($logicalTag) { 543 default: 544 case HeadingTag::LOGICAL_TAG: 545 HeadingTag::processMetadataAnalytics($data, $renderer); 546 return true; 547 } 548 549 } 550 551 // unsupported $mode 552 return false; 553 } 554 555 public static function handleStaticExit(string $match, int $pos, Doku_Handler $handler, DokuWiki_Syntax_Plugin $plugin): array 556 { 557 $markupTag = PluginUtility::getMarkupTag($match); 558 $logicalTag = $markupTag; 559 $returnedArray = []; 560 switch ($markupTag) { 561 case BlockquoteTag::TAG: 562 $returnedArray = BlockquoteTag::handleExit($handler); 563 break; 564 case BoxTag::TAG: 565 $returnedArray = BoxTag::handleExit($handler); 566 break; 567 case ButtonTag::MARKUP_SHORT: 568 case ButtonTag::MARKUP_LONG: 569 $logicalTag = ButtonTag::LOGICAL_TAG; 570 $returnedArray = ButtonTag::handleExit($handler); 571 break; 572 case CardTag::CARD_TAG: 573 case CardTag::TEASER_TAG: 574 $logicalTag = CardTag::LOGICAL_TAG; 575 $returnedArray = CardTag::handleExit($handler, $pos, $match); 576 break; 577 case BarTag::BAR_TAG: 578 case BarTag::SLIDE_TAG: 579 $logicalTag = BarTag::LOGICAL_TAG; 580 $returnedArray = BarTag::handleExit($handler, $pos, $match); 581 break; 582 case CarrouselTag::TAG: 583 $returnedArray = CarrouselTag::handleExit($handler); 584 break; 585 case PrismTags::CONSOLE_TAG: 586 case PrismTags::FILE_TAG: 587 $returnedArray = PrismTags::handleExit($handler); 588 break; 589 case PipelineTag::TAG: 590 PipelineTag::processExit($handler); 591 break; 592 case GridTag::GRID_TAG: 593 case GridTag::ROW_TAG: 594 $logicalTag = GridTag::LOGICAL_TAG; 595 $returnedArray = GridTag::handleExit($handler); 596 break; 597 case DateTag::TAG: 598 DateTag::handleExit($handler); 599 break; 600 case HeadingTag::TITLE_TAG: 601 case HeadingTag::HEADING_TAG: 602 $logicalTag = HeadingTag::LOGICAL_TAG; 603 $returnedArray = HeadingTag::handleExit($handler); 604 break; 605 case MasonryTag::CARD_COLUMNS_TAG: 606 case MasonryTag::TEASER_COLUMNS_TAG: 607 case MasonryTag::MASONRY_TAG: 608 $logicalTag = MasonryTag::LOGICAL_TAG; 609 MasonryTag::handleExit($handler); 610 break; 611 case PageExplorerTag::NTOC_MARKUP: 612 case PageExplorerTag::PAGE_EXPLORER_MARKUP: 613 $logicalTag = PageExplorerTag::LOGICAL_TAG; 614 PageExplorerTag::handleExit($handler); 615 break; 616 case PageExplorerTag::INDEX_HOME_TAG: 617 case PageExplorerTag::INDEX_TAG: 618 $logicalTag = PageExplorerTag::LOGICAL_INDEX_TAG; 619 break; 620 case PageExplorerTag::NAMESPACE_ITEM_TAG: 621 case PageExplorerTag::NAMESPACE_LONG_TAG: 622 case PageExplorerTag::NAMESPACE_SHORT_TAG: 623 $logicalTag = PageExplorerTag::NAMESPACE_LOGICAL_TAG; 624 break; 625 case PageExplorerTag::PAGE_ITEM_TAG: 626 case PageExplorerTag::PAGE_TAG: 627 $logicalTag = PageExplorerTag::PAGE_LOGICAL_TAG; 628 break; 629 case PageExplorerTag::PARENT_TAG: 630 // nothing as the content is captured and deleted by page-explorer 631 break; 632 case TabsTag::TAG: 633 $returnedArray = TabsTag::handleExit($handler); 634 break; 635 case PanelTag::PANEL_MARKUP: 636 case PanelTag::TAB_PANEL_MARKUP: 637 $logicalTag = PanelTag::PANEL_LOGICAL_MARKUP; 638 $returnedArray = PanelTag::handleExit($handler, $pos, $markupTag, $match); 639 break; 640 case PermalinkTag::TAG: 641 PermalinkTag::handeExit($handler); 642 break; 643 case IconTag::TAG: 644 $returnedArray = IconTag::handleExit($handler); 645 break; 646 case BackgroundTag::MARKUP_SHORT: 647 case BackgroundTag::MARKUP_LONG: 648 $logicalTag = BackgroundTag::LOGICAL_TAG; 649 $returnedArray = BackgroundTag::handleExit($handler); 650 break; 651 case MermaidTag::MARKUP_SEQUENCE_DIAGRAM: 652 case MermaidTag::MARKUP_CLASS_DIAGRAM: 653 case MermaidTag::MARKUP_FLOWCHART: 654 case MermaidTag::MARKUP_GANTT: 655 case MermaidTag::MARKUP_ERD: 656 case MermaidTag::MARKUP_JOURNEY: 657 case MermaidTag::MARKUP_PIECHART: 658 case MermaidTag::MARKUP_STATE_DIAGRAM: 659 $logicalTag = MermaidTag::LOGICAL_TAG; 660 MermaidTag::handleExit($handler); 661 break; 662 case MermaidTag::MARKUP_MERMAID: // bug 663 case WebCodeTag::TAG: 664 $logicalTag = WebCodeTag::TAG; 665 $returnedArray = WebCodeTag::handleExit($handler); 666 break; 667 } 668 /** 669 * Common exit attributes 670 */ 671 $defaultReturnedArray[PluginUtility::STATE] = DOKU_LEXER_EXIT; 672 $defaultReturnedArray[PluginUtility::TAG] = $logicalTag; 673 $defaultReturnedArray[PluginUtility::MARKUP_TAG] = $markupTag; 674 return array_merge($defaultReturnedArray, $returnedArray); 675 } 676 677 /** 678 * @param $tag 679 * @return string 680 * 681 * Create a lookahead pattern for a container tag used to enter in a mode 682 */ 683 public static function getContainerTagPattern($tag): string 684 { 685 // this pattern ensure that the tag 686 // `accordion` will not intercept also the tag `accordionitem` 687 // where: 688 // ?: means non capturing group (to not capture the last >) 689 // (\s.*?): is a capturing group that starts with a space 690 $pattern = "(?:\s.*?>|>)"; 691 return '<' . $tag . $pattern . '(?=.*?<\/' . $tag . '>)'; 692 } 693 694 public static function handleStaticEmptyTag(string $match, int $state, int $pos, Doku_Handler $handler, DokuWiki_Syntax_Plugin $plugin): array 695 { 696 /** 697 * Logical Tag Building 698 */ 699 $logicalTag = PluginUtility::getMarkupTag($match); 700 $defaultAttributes = []; 701 $knownTypes = []; 702 $allowAnyFirstBooleanAttributesAsType = false; 703 switch ($logicalTag) { 704 case SearchTag::TAG: 705 $defaultAttributes = array( 706 'ajax' => true, 707 'autocomplete' => false 708 ); 709 break; 710 case PageImageTag::MARKUP: 711 $knownTypes = PageImageTag::TYPES; 712 $defaultAttributes = PageImageTag::getDefaultAttributes(); 713 break; 714 case ShareTag::MARKUP: 715 $knownTypes = ShareTag::getKnownTypes(); 716 break; 717 case FollowTag::MARKUP: 718 $knownTypes = FollowTag::getKnownTypes(); 719 break; 720 case BrandListTag::MARKUP: 721 $knownTypes = BrandButton::TYPE_BUTTONS; 722 $defaultAttributes = [TagAttributes::TYPE_KEY => BrandButton::TYPE_BUTTON_BRAND]; 723 break; 724 case BrandTag::MARKUP: 725 $defaultAttributes = [TagAttributes::TYPE_KEY => Brand::CURRENT_BRAND]; 726 $allowAnyFirstBooleanAttributesAsType = true; 727 break; 728 case PermalinkTag::TAG: 729 $knownTypes = PermalinkTag::getKnownTypes(); 730 $defaultAttributes = [TagAttributes::TYPE_KEY => PermalinkTag::GENERATED_TYPE]; 731 break; 732 case BreadcrumbTag::MARKUP_BLOCK: 733 $logicalTag = BreadcrumbTag::LOGICAL_TAG; 734 $knownTypes = BreadcrumbTag::TYPES; 735 $defaultAttributes = BreadcrumbTag::getDefaultBlockAttributes(); 736 break; 737 } 738 $tagAttributes = TagAttributes::createFromTagMatch($match, $defaultAttributes, $knownTypes, $allowAnyFirstBooleanAttributesAsType) 739 ->setLogicalTag($logicalTag); 740 741 /** 742 * Calculate extra returned key in the table 743 */ 744 $returnedArray = []; 745 switch ($logicalTag) { 746 case IconTag::TAG: 747 $returnedArray = IconTag::handleSpecial($tagAttributes, $handler); 748 break; 749 case PageImageTag::MARKUP: 750 $returnedArray = PageImageTag::handle($tagAttributes, $handler); 751 break; 752 case BrandTag::MARKUP: 753 $returnedArray = BrandTag::handleSpecialEnter($tagAttributes, $handler); 754 break; 755 case CacheTag::MARKUP: 756 $returnedArray = CacheTag::handle($tagAttributes); 757 break; 758 case BackgroundTag::MARKUP_SHORT: 759 case BackgroundTag::MARKUP_LONG: 760 BackgroundTag::handleEnterAndSpecial($tagAttributes); 761 $callStack = CallStack::createFromHandler($handler); 762 $returnedArray = BackgroundTag::setAttributesToParentAndReturnData($callStack, $tagAttributes, $state); 763 break; 764 case DateTag::TAG: 765 DateTag::handleEnterAndSpecial(); 766 break; 767 case PermalinkTag::TAG: 768 $returnedArray = PermalinkTag::handleEnterSpecial($tagAttributes, $state, $handler); 769 break; 770 case BreadcrumbTag::MARKUP_BLOCK: 771 $returnedArray = BreadcrumbTag::handleEnter($tagAttributes); 772 break; 773 case HrTag::TAG: 774 /** 775 * Block tag 776 */ 777 $returnedArray = [PluginUtility::DISPLAY => HrTag::getDisplay()]; 778 break; 779 } 780 781 /** 782 * Common default 783 * {@link PluginUtility::DISPLAY} should be set on handle 784 */ 785 $defaultReturnedArray[PluginUtility::STATE] = $state; 786 $defaultReturnedArray[PluginUtility::TAG] = $logicalTag; 787 $defaultReturnedArray[PluginUtility::ATTRIBUTES] = $tagAttributes->toCallStackArray(); 788 789 return array_merge($defaultReturnedArray, $returnedArray); 790 } 791 792 public static function renderStaticEmptyTag(string $format, Doku_Renderer $renderer, array $data, DokuWiki_Syntax_Plugin $plugin): bool 793 { 794 795 $tag = $data[PluginUtility::TAG]; 796 $attributes = $data[PluginUtility::ATTRIBUTES]; 797 $state = DOKU_LEXER_SPECIAL; 798 $tagAttributes = TagAttributes::createFromCallStackArray($attributes)->setLogicalTag($tag); 799 switch ($format) { 800 case "xhtml": 801 /** @var Doku_Renderer_xhtml $renderer */ 802 switch ($tag) { 803 case HrTag::TAG: 804 $renderer->doc .= HrTag::render($tagAttributes); 805 break; 806 case SearchTag::TAG: 807 $renderer->doc .= SearchTag::render($tagAttributes); 808 break; 809 case IconTag::TAG: 810 $renderer->doc .= IconTag::renderEmptyTag($tagAttributes); 811 break; 812 case BreadcrumbTag::LOGICAL_TAG: 813 $renderer->doc .= BreadcrumbTag::render($tagAttributes); 814 break; 815 case PageImageTag::MARKUP: 816 $renderer->doc .= PageImageTag::render($tagAttributes, $data); 817 break; 818 case ShareTag::MARKUP: 819 $renderer->doc .= ShareTag::renderSpecialEnter($tagAttributes, $state); 820 break; 821 case BrandListTag::MARKUP: 822 $renderer->doc .= BrandListTag::render($tagAttributes); 823 break; 824 case BrandTag::MARKUP: 825 $renderer->doc .= BrandTag::render($tagAttributes, $state, $data); 826 break; 827 case CacheTag::MARKUP: 828 $renderer->doc .= CacheTag::renderXhtml($data); 829 break; 830 case BackgroundTag::MARKUP_LONG: 831 case BackgroundTag::MARKUP_SHORT: 832 $renderer->doc .= BackgroundTag::renderExitSpecialHtml($data); 833 break; 834 case DateTag::TAG: 835 $renderer->doc .= DateTag::renderHtml($tagAttributes); 836 return true; 837 case PermalinkTag::TAG: 838 $renderer->doc .= PermalinkTag::renderEnterSpecialXhtml($data); 839 return true; 840 case QualityTag::MARKUP_TAG: 841 $renderer->doc .= QualityTag::renderXhtml($tagAttributes); 842 return true; 843 case FollowTag::MARKUP: 844 $renderer->doc .= FollowTag::renderSpecialEnterNode($tagAttributes, DOKU_LEXER_SPECIAL); 845 return true; 846 case MediaMarkup::TAG: 847 $renderer->doc .= MediaMarkup::renderSpecial($data, $renderer); 848 return true; 849 case SubscribeTag::LOGICAL_TAG: 850 $renderer->doc .= SubscribeTag::renderEnterXhtml($tagAttributes); 851 return true; 852 case AdTag::MARKUP: 853 $renderer->doc .= AdTag::render($tagAttributes); 854 return true; 855 case RelatedTag::TAG: 856 $renderer->doc .= RelatedTag::render($tagAttributes); 857 return true; 858 default: 859 LogUtility::errorIfDevOrTest("The empty tag (" . $tag . ") was not processed."); 860 } 861 break; 862 case 'metadata': 863 /** @var Doku_Renderer_metadata $renderer */ 864 switch ($tag) { 865 case IconTag::TAG: 866 IconTag::metadata($renderer, $tagAttributes); 867 return true; 868 case CacheTag::MARKUP: 869 CacheTag::metadata($data); 870 return true; 871 case MediaMarkup::TAG: 872 MediaMarkup::metadata($data, $renderer); 873 return true; 874 } 875 break; 876 case renderer_plugin_combo_analytics::RENDERER_FORMAT: 877 878 } 879 // unsupported $mode 880 return false; 881 } 882 883 private static function renderStaticEnterSpecialMetadata(TagAttributes $tagAttributes, Doku_Renderer_metadata $renderer, array $data, DokuWiki_Syntax_Plugin $plugin): bool 884 { 885 $logicalTag = $tagAttributes->getLogicalTag(); 886 switch ($logicalTag) { 887 case HeadingTag::LOGICAL_TAG: 888 HeadingTag::processHeadingEnterMetadata($data, $renderer); 889 return true; 890 case IconTag::TAG: 891 IconTag::metadata($renderer, $tagAttributes); 892 return true; 893 case BackgroundTag::LOGICAL_TAG: 894 BackgroundTag::renderMeta($data, $renderer); 895 return true; 896 } 897 return false; 898 } 899} 900 901