1<?php 2 3namespace dokuwiki\Parsing\ParserMode; 4 5use dokuwiki\Parsing\ModeRegistry; 6 7/** 8 * Base class for inline formatting modes (bold, italic, underline, etc.) 9 * 10 * Each concrete subclass defines its entry/exit patterns, mode name, and sort order. 11 */ 12abstract class AbstractFormatting extends AbstractMode 13{ 14 /** 15 * @return string The regex pattern that starts this formatting 16 */ 17 abstract protected function getEntryPattern(): string; 18 19 /** 20 * @return string The regex pattern that ends this formatting 21 */ 22 abstract protected function getExitPattern(): string; 23 24 /** 25 * @return string The mode name used for lexer registration 26 */ 27 abstract protected function getModeName(): string; 28 29 /** 30 * Constructor. Sets up allowed modes for this formatting type. 31 * 32 * Formatting modes accept other formatting, substitutions, and disabled modes, 33 * but exclude themselves to prevent self-nesting (e.g. bold inside bold). 34 */ 35 public function __construct() 36 { 37 $self = $this->getModeName(); 38 $this->allowedModes = array_filter( 39 ModeRegistry::getInstance()->getModesForCategories([ 40 ModeRegistry::CATEGORY_FORMATTING, 41 ModeRegistry::CATEGORY_SUBSTITION, 42 ModeRegistry::CATEGORY_DISABLED, 43 ]), 44 static fn($mode) => $mode !== $self 45 ); 46 } 47 48 /** @inheritdoc */ 49 public function connectTo($mode) 50 { 51 // Can't nest formatting in itself 52 if ($mode === $this->getModeName()) { 53 return; 54 } 55 56 $this->Lexer->addEntryPattern( 57 $this->getEntryPattern(), 58 $mode, 59 $this->getModeName() 60 ); 61 } 62 63 /** @inheritdoc */ 64 public function postConnect() 65 { 66 $this->Lexer->addExitPattern( 67 $this->getExitPattern(), 68 $this->getModeName() 69 ); 70 } 71} 72