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