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($tagAttributes); 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 case ShareTag::MARKUP: 668 $returnedArray = ShareTag::handleExit($handler); 669 670 break; 671 672 } 673 /** 674 * Common exit attributes 675 */ 676 $defaultReturnedArray[PluginUtility::STATE] = DOKU_LEXER_EXIT; 677 $defaultReturnedArray[PluginUtility::TAG] = $logicalTag; 678 $defaultReturnedArray[PluginUtility::MARKUP_TAG] = $markupTag; 679 return array_merge($defaultReturnedArray, $returnedArray); 680 } 681 682 /** 683 * @param $tag 684 * @return string 685 * 686 * Create a lookahead pattern for a container tag used to enter in a mode 687 */ 688 public static function getContainerTagPattern($tag): string 689 { 690 // this pattern ensure that the tag 691 // `accordion` will not intercept also the tag `accordionitem` 692 // where: 693 // ?: means non capturing group (to not capture the last >) 694 // (\s.*?): is a capturing group that starts with a space 695 $pattern = "(?:\s.*?>|>)"; 696 return '<' . $tag . $pattern . '(?=.*?<\/' . $tag . '>)'; 697 } 698 699 public static function handleStaticEmptyTag(string $match, int $state, int $pos, Doku_Handler $handler, DokuWiki_Syntax_Plugin $plugin): array 700 { 701 /** 702 * Logical Tag Building 703 */ 704 $logicalTag = PluginUtility::getMarkupTag($match); 705 $defaultAttributes = []; 706 $knownTypes = []; 707 $allowAnyFirstBooleanAttributesAsType = false; 708 switch ($logicalTag) { 709 case SearchTag::TAG: 710 $defaultAttributes = array( 711 'ajax' => true, 712 'autocomplete' => false 713 ); 714 break; 715 case PageImageTag::MARKUP: 716 $knownTypes = PageImageTag::TYPES; 717 $defaultAttributes = PageImageTag::getDefaultAttributes(); 718 break; 719 case ShareTag::MARKUP: 720 $knownTypes = ShareTag::getKnownTypes(); 721 break; 722 case FollowTag::MARKUP: 723 $knownTypes = FollowTag::getKnownTypes(); 724 break; 725 case BrandListTag::MARKUP: 726 $knownTypes = BrandButton::TYPE_BUTTONS; 727 $defaultAttributes = [TagAttributes::TYPE_KEY => BrandButton::TYPE_BUTTON_BRAND]; 728 break; 729 case BrandTag::MARKUP: 730 $defaultAttributes = [TagAttributes::TYPE_KEY => Brand::CURRENT_BRAND]; 731 $allowAnyFirstBooleanAttributesAsType = true; 732 break; 733 case PermalinkTag::TAG: 734 $knownTypes = PermalinkTag::getKnownTypes(); 735 $defaultAttributes = [TagAttributes::TYPE_KEY => PermalinkTag::GENERATED_TYPE]; 736 break; 737 case BreadcrumbTag::MARKUP_BLOCK: 738 $logicalTag = BreadcrumbTag::LOGICAL_TAG; 739 $knownTypes = BreadcrumbTag::TYPES; 740 $defaultAttributes = BreadcrumbTag::getDefaultBlockAttributes(); 741 break; 742 } 743 $tagAttributes = TagAttributes::createFromTagMatch($match, $defaultAttributes, $knownTypes, $allowAnyFirstBooleanAttributesAsType) 744 ->setLogicalTag($logicalTag); 745 746 /** 747 * Calculate extra returned key in the table 748 */ 749 $returnedArray = []; 750 switch ($logicalTag) { 751 case IconTag::TAG: 752 $returnedArray = IconTag::handleSpecial($tagAttributes, $handler); 753 break; 754 case PageImageTag::MARKUP: 755 $returnedArray = PageImageTag::handle($tagAttributes, $handler); 756 break; 757 case BrandTag::MARKUP: 758 $returnedArray = BrandTag::handleSpecialEnter($tagAttributes, $handler); 759 break; 760 case CacheTag::MARKUP: 761 $returnedArray = CacheTag::handle($tagAttributes); 762 break; 763 case BackgroundTag::MARKUP_SHORT: 764 case BackgroundTag::MARKUP_LONG: 765 BackgroundTag::handleEnterAndSpecial($tagAttributes); 766 $callStack = CallStack::createFromHandler($handler); 767 $returnedArray = BackgroundTag::setAttributesToParentAndReturnData($callStack, $tagAttributes, $state); 768 break; 769 case DateTag::TAG: 770 DateTag::handleEnterAndSpecial(); 771 break; 772 case PermalinkTag::TAG: 773 $returnedArray = PermalinkTag::handleEnterSpecial($tagAttributes, $state, $handler); 774 break; 775 case BreadcrumbTag::MARKUP_BLOCK: 776 $returnedArray = BreadcrumbTag::handleEnter($tagAttributes); 777 break; 778 case HrTag::TAG: 779 /** 780 * Block tag 781 */ 782 $returnedArray = [PluginUtility::DISPLAY => HrTag::getDisplay()]; 783 break; 784 } 785 786 /** 787 * Common default 788 * {@link PluginUtility::DISPLAY} should be set on handle 789 */ 790 $defaultReturnedArray[PluginUtility::STATE] = $state; 791 $defaultReturnedArray[PluginUtility::TAG] = $logicalTag; 792 $defaultReturnedArray[PluginUtility::ATTRIBUTES] = $tagAttributes->toCallStackArray(); 793 794 return array_merge($defaultReturnedArray, $returnedArray); 795 } 796 797 public static function renderStaticEmptyTag(string $format, Doku_Renderer $renderer, array $data, DokuWiki_Syntax_Plugin $plugin): bool 798 { 799 800 $tag = $data[PluginUtility::TAG]; 801 $attributes = $data[PluginUtility::ATTRIBUTES]; 802 $state = DOKU_LEXER_SPECIAL; 803 $tagAttributes = TagAttributes::createFromCallStackArray($attributes)->setLogicalTag($tag); 804 switch ($format) { 805 case "xhtml": 806 /** @var Doku_Renderer_xhtml $renderer */ 807 switch ($tag) { 808 case HrTag::TAG: 809 $renderer->doc .= HrTag::render($tagAttributes); 810 break; 811 case SearchTag::TAG: 812 $renderer->doc .= SearchTag::render($tagAttributes); 813 break; 814 case IconTag::TAG: 815 $renderer->doc .= IconTag::renderEmptyTag($tagAttributes); 816 break; 817 case BreadcrumbTag::LOGICAL_TAG: 818 $renderer->doc .= BreadcrumbTag::render($tagAttributes); 819 break; 820 case PageImageTag::MARKUP: 821 $renderer->doc .= PageImageTag::render($tagAttributes, $data); 822 break; 823 case ShareTag::MARKUP: 824 $renderer->doc .= ShareTag::renderSpecialEnter($tagAttributes, $state); 825 break; 826 case BrandListTag::MARKUP: 827 $renderer->doc .= BrandListTag::render($tagAttributes); 828 break; 829 case BrandTag::MARKUP: 830 $renderer->doc .= BrandTag::render($tagAttributes, $state, $data); 831 break; 832 case CacheTag::MARKUP: 833 $renderer->doc .= CacheTag::renderXhtml($data); 834 break; 835 case BackgroundTag::MARKUP_LONG: 836 case BackgroundTag::MARKUP_SHORT: 837 $renderer->doc .= BackgroundTag::renderExitSpecialHtml($data); 838 break; 839 case DateTag::TAG: 840 $renderer->doc .= DateTag::renderHtml($tagAttributes); 841 return true; 842 case PermalinkTag::TAG: 843 $renderer->doc .= PermalinkTag::renderEnterSpecialXhtml($data); 844 return true; 845 case QualityTag::MARKUP_TAG: 846 $renderer->doc .= QualityTag::renderXhtml($tagAttributes); 847 return true; 848 case FollowTag::MARKUP: 849 $renderer->doc .= FollowTag::renderSpecialEnterNode($tagAttributes, DOKU_LEXER_SPECIAL); 850 return true; 851 case MediaMarkup::TAG: 852 $renderer->doc .= MediaMarkup::renderSpecial($data, $renderer); 853 return true; 854 case SubscribeTag::LOGICAL_TAG: 855 $renderer->doc .= SubscribeTag::renderEnterXhtml($tagAttributes); 856 return true; 857 case AdTag::MARKUP: 858 $renderer->doc .= AdTag::render($tagAttributes); 859 return true; 860 case RelatedTag::TAG: 861 $renderer->doc .= RelatedTag::render($tagAttributes); 862 return true; 863 default: 864 LogUtility::errorIfDevOrTest("The empty tag (" . $tag . ") was not processed."); 865 } 866 break; 867 case 'metadata': 868 /** @var Doku_Renderer_metadata $renderer */ 869 switch ($tag) { 870 case IconTag::TAG: 871 IconTag::metadata($renderer, $tagAttributes); 872 return true; 873 case CacheTag::MARKUP: 874 CacheTag::metadata($data); 875 return true; 876 case MediaMarkup::TAG: 877 MediaMarkup::metadata($data, $renderer); 878 return true; 879 } 880 break; 881 case renderer_plugin_combo_analytics::RENDERER_FORMAT: 882 883 } 884 // unsupported $mode 885 return false; 886 } 887 888 private static function renderStaticEnterSpecialMetadata(TagAttributes $tagAttributes, Doku_Renderer_metadata $renderer, array $data, DokuWiki_Syntax_Plugin $plugin): bool 889 { 890 $logicalTag = $tagAttributes->getLogicalTag(); 891 switch ($logicalTag) { 892 case HeadingTag::LOGICAL_TAG: 893 HeadingTag::processHeadingEnterMetadata($data, $renderer); 894 return true; 895 case IconTag::TAG: 896 IconTag::metadata($renderer, $tagAttributes); 897 return true; 898 case BackgroundTag::LOGICAL_TAG: 899 BackgroundTag::renderMeta($data, $renderer); 900 return true; 901 } 902 return false; 903 } 904} 905 906