11f443476SAndreas Gohr<?php 21f443476SAndreas Gohr 31f443476SAndreas Gohrnamespace dokuwiki\Parsing\ParserMode; 41f443476SAndreas Gohr 571096e46SAndreas 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, 27*56c730b5SAndreas Gohr ModeRegistry::CATEGORY_SUBSTITUTION, 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 4971096e46SAndreas Gohr /** 5071096e46SAndreas Gohr * @return string The regex pattern that starts this formatting 5171096e46SAndreas Gohr */ 5271096e46SAndreas Gohr abstract protected function getEntryPattern(): string; 5371096e46SAndreas Gohr 5471096e46SAndreas Gohr /** 5571096e46SAndreas Gohr * @return string The regex pattern that ends this formatting 5671096e46SAndreas Gohr */ 5771096e46SAndreas Gohr abstract protected function getExitPattern(): string; 5871096e46SAndreas Gohr 5971096e46SAndreas Gohr /** 6071096e46SAndreas Gohr * @return string The mode name used for lexer registration 6171096e46SAndreas Gohr */ 6271096e46SAndreas Gohr abstract protected function getModeName(): string; 6371096e46SAndreas 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 } 7271096e46SAndreas Gohr 7371096e46SAndreas Gohr /** @inheritdoc */ 7471096e46SAndreas Gohr public function handle($match, $state, $pos, Handler $handler) 7571096e46SAndreas Gohr { 7671096e46SAndreas Gohr $name = $this->getModeName(); 7771096e46SAndreas Gohr match ($state) { 7871096e46SAndreas Gohr DOKU_LEXER_ENTER => $handler->addCall($name . '_open', [], $pos), 7971096e46SAndreas Gohr DOKU_LEXER_EXIT => $handler->addCall($name . '_close', [], $pos), 8071096e46SAndreas Gohr DOKU_LEXER_UNMATCHED => $handler->addCall('cdata', [$match], $pos), 8171096e46SAndreas Gohr default => true, 8271096e46SAndreas Gohr }; 8371096e46SAndreas Gohr return true; 8471096e46SAndreas Gohr } 851f443476SAndreas Gohr} 86