xref: /dokuwiki/inc/Parsing/ParserMode/AbstractFormatting.php (revision dba14ea3c4253d454e478f27d0ae9c47d2fa7aa6)
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