11f443476SAndreas Gohr<?php 21f443476SAndreas Gohr 31f443476SAndreas Gohrnamespace dokuwiki\Parsing\ParserMode; 41f443476SAndreas Gohr 5*71096e46SAndreas Gohruse dokuwiki\Parsing\Handler; 61f443476SAndreas Gohruse dokuwiki\Parsing\ModeRegistry; 71f443476SAndreas Gohr 81f443476SAndreas Gohr/** 91f443476SAndreas Gohr * Base class for inline formatting modes (bold, italic, underline, etc.) 101f443476SAndreas Gohr * 111f443476SAndreas Gohr * Each concrete subclass defines its entry/exit patterns, mode name, and sort order. 121f443476SAndreas Gohr */ 131f443476SAndreas Gohrabstract class AbstractFormatting extends AbstractMode 141f443476SAndreas Gohr{ 151f443476SAndreas Gohr /** 161f443476SAndreas Gohr * Constructor. Sets up allowed modes for this formatting type. 171f443476SAndreas Gohr * 181f443476SAndreas Gohr * Formatting modes accept other formatting, substitutions, and disabled modes, 191f443476SAndreas Gohr * but exclude themselves to prevent self-nesting (e.g. bold inside bold). 201f443476SAndreas Gohr */ 211f443476SAndreas Gohr public function __construct() 221f443476SAndreas Gohr { 231f443476SAndreas Gohr $self = $this->getModeName(); 241f443476SAndreas Gohr $this->allowedModes = array_filter( 251f443476SAndreas Gohr ModeRegistry::getInstance()->getModesForCategories([ 261f443476SAndreas Gohr ModeRegistry::CATEGORY_FORMATTING, 271f443476SAndreas Gohr ModeRegistry::CATEGORY_SUBSTITION, 281f443476SAndreas Gohr ModeRegistry::CATEGORY_DISABLED, 291f443476SAndreas Gohr ]), 301f443476SAndreas Gohr static fn($mode) => $mode !== $self 311f443476SAndreas Gohr ); 321f443476SAndreas Gohr } 331f443476SAndreas Gohr 341f443476SAndreas Gohr /** @inheritdoc */ 351f443476SAndreas Gohr public function connectTo($mode) 361f443476SAndreas Gohr { 371f443476SAndreas Gohr // Can't nest formatting in itself 381f443476SAndreas Gohr if ($mode === $this->getModeName()) { 391f443476SAndreas Gohr return; 401f443476SAndreas Gohr } 411f443476SAndreas Gohr 421f443476SAndreas Gohr $this->Lexer->addEntryPattern( 431f443476SAndreas Gohr $this->getEntryPattern(), 441f443476SAndreas Gohr $mode, 451f443476SAndreas Gohr $this->getModeName() 461f443476SAndreas Gohr ); 471f443476SAndreas Gohr } 481f443476SAndreas Gohr 49*71096e46SAndreas Gohr /** 50*71096e46SAndreas Gohr * @return string The regex pattern that starts this formatting 51*71096e46SAndreas Gohr */ 52*71096e46SAndreas Gohr abstract protected function getEntryPattern(): string; 53*71096e46SAndreas Gohr 54*71096e46SAndreas Gohr /** 55*71096e46SAndreas Gohr * @return string The regex pattern that ends this formatting 56*71096e46SAndreas Gohr */ 57*71096e46SAndreas Gohr abstract protected function getExitPattern(): string; 58*71096e46SAndreas Gohr 59*71096e46SAndreas Gohr /** 60*71096e46SAndreas Gohr * @return string The mode name used for lexer registration 61*71096e46SAndreas Gohr */ 62*71096e46SAndreas Gohr abstract protected function getModeName(): string; 63*71096e46SAndreas Gohr 641f443476SAndreas Gohr /** @inheritdoc */ 651f443476SAndreas Gohr public function postConnect() 661f443476SAndreas Gohr { 671f443476SAndreas Gohr $this->Lexer->addExitPattern( 681f443476SAndreas Gohr $this->getExitPattern(), 691f443476SAndreas Gohr $this->getModeName() 701f443476SAndreas Gohr ); 711f443476SAndreas Gohr } 72*71096e46SAndreas Gohr 73*71096e46SAndreas Gohr /** @inheritdoc */ 74*71096e46SAndreas Gohr public function handle($match, $state, $pos, Handler $handler) 75*71096e46SAndreas Gohr { 76*71096e46SAndreas Gohr $name = $this->getModeName(); 77*71096e46SAndreas Gohr match ($state) { 78*71096e46SAndreas Gohr DOKU_LEXER_ENTER => $handler->addCall($name . '_open', [], $pos), 79*71096e46SAndreas Gohr DOKU_LEXER_EXIT => $handler->addCall($name . '_close', [], $pos), 80*71096e46SAndreas Gohr DOKU_LEXER_UNMATCHED => $handler->addCall('cdata', [$match], $pos), 81*71096e46SAndreas Gohr default => true, 82*71096e46SAndreas Gohr }; 83*71096e46SAndreas Gohr return true; 84*71096e46SAndreas Gohr } 851f443476SAndreas Gohr} 86