xref: /dokuwiki/inc/Parsing/ParserMode/GfmEmphasisStrongUnderscore.php (revision 2bb62bca317961d66fa2908b40f183af01402a91)
1*2bb62bcaSAndreas Gohr<?php
2*2bb62bcaSAndreas Gohr
3*2bb62bcaSAndreas Gohrnamespace dokuwiki\Parsing\ParserMode;
4*2bb62bcaSAndreas Gohr
5*2bb62bcaSAndreas Gohr/**
6*2bb62bcaSAndreas Gohr * GFM / CommonMark em-wrapping-strong via triple underscores: `___text___`.
7*2bb62bcaSAndreas Gohr *
8*2bb62bcaSAndreas Gohr * Only loaded when Markdown is the only or preferred syntax. Renders as
9*2bb62bcaSAndreas Gohr * <em><strong>text</strong></em>. Only the exact 3+3 symmetric variant is
10*2bb62bcaSAndreas Gohr * supported; longer and asymmetric runs require CommonMark's full
11*2bb62bcaSAndreas Gohr * delimiter-pairing algorithm and are out of scope.
12*2bb62bcaSAndreas Gohr *
13*2bb62bcaSAndreas Gohr * Inherits `handle()` and `getSort()` from GfmEmphasisStrong since the
14*2bb62bcaSAndreas Gohr * emitted instructions and sort priority are identical; only the delimiter
15*2bb62bcaSAndreas Gohr * patterns and word-boundary rules differ.
16*2bb62bcaSAndreas Gohr */
17*2bb62bcaSAndreas Gohrclass GfmEmphasisStrongUnderscore extends GfmEmphasisStrong
18*2bb62bcaSAndreas Gohr{
19*2bb62bcaSAndreas Gohr    /** @inheritdoc */
20*2bb62bcaSAndreas Gohr    protected function getModeName(): string
21*2bb62bcaSAndreas Gohr    {
22*2bb62bcaSAndreas Gohr        return 'gfm_emphasis_strong_underscore';
23*2bb62bcaSAndreas Gohr    }
24*2bb62bcaSAndreas Gohr
25*2bb62bcaSAndreas Gohr    /** @inheritdoc */
26*2bb62bcaSAndreas Gohr    protected function getEntryPattern(): string
27*2bb62bcaSAndreas Gohr    {
28*2bb62bcaSAndreas Gohr        // NO_WORD_BEFORE + `(?<!_)` blocks intraword and longer-run openers.
29*2bb62bcaSAndreas Gohr        // `(?=[^\s_])` enforces the flanking-opener rule.
30*2bb62bcaSAndreas Gohr        // The closing-delimiter lookahead requires non-whitespace before `___`,
31*2bb62bcaSAndreas Gohr        // `(?!_)` for exactly-3 length, and NO_WORD_AFTER for word-boundary.
32*2bb62bcaSAndreas Gohr        return self::NO_WORD_BEFORE
33*2bb62bcaSAndreas Gohr            . '(?<!_)___(?=[^\s_])'
34*2bb62bcaSAndreas Gohr            . '(?=' . self::CONTENT_UNTIL_PARA . '[^\s]___(?!_)' . self::NO_WORD_AFTER . ')';
35*2bb62bcaSAndreas Gohr    }
36*2bb62bcaSAndreas Gohr
37*2bb62bcaSAndreas Gohr    /** @inheritdoc */
38*2bb62bcaSAndreas Gohr    protected function getExitPattern(): string
39*2bb62bcaSAndreas Gohr    {
40*2bb62bcaSAndreas Gohr        return '(?<=[^\s])___(?!_)' . self::NO_WORD_AFTER;
41*2bb62bcaSAndreas Gohr    }
42*2bb62bcaSAndreas Gohr}
43