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