xref: /dokuwiki/inc/Parsing/ParserMode/GfmEmphasis.php (revision bcefb8ae61f4ff776efdbad9508c8ee8e5c548a6)
1*bcefb8aeSAndreas Gohr<?php
2*bcefb8aeSAndreas Gohr
3*bcefb8aeSAndreas Gohrnamespace dokuwiki\Parsing\ParserMode;
4*bcefb8aeSAndreas Gohr
5*bcefb8aeSAndreas Gohr/**
6*bcefb8aeSAndreas Gohr * GFM / CommonMark emphasis via single asterisks: `*text*`.
7*bcefb8aeSAndreas Gohr *
8*bcefb8aeSAndreas Gohr * Emits emphasis_open / emphasis_close — the same instructions as DokuWiki's
9*bcefb8aeSAndreas Gohr * Emphasis (`//`), so both syntaxes render as <em>.
10*bcefb8aeSAndreas Gohr */
11*bcefb8aeSAndreas Gohrclass GfmEmphasis extends AbstractFormatting
12*bcefb8aeSAndreas Gohr{
13*bcefb8aeSAndreas Gohr    /** @inheritdoc */
14*bcefb8aeSAndreas Gohr    public function getSort()
15*bcefb8aeSAndreas Gohr    {
16*bcefb8aeSAndreas Gohr        return 80;
17*bcefb8aeSAndreas Gohr    }
18*bcefb8aeSAndreas Gohr
19*bcefb8aeSAndreas Gohr    /** @inheritdoc */
20*bcefb8aeSAndreas Gohr    protected function getModeName(): string
21*bcefb8aeSAndreas Gohr    {
22*bcefb8aeSAndreas Gohr        return 'gfm_emphasis';
23*bcefb8aeSAndreas Gohr    }
24*bcefb8aeSAndreas Gohr
25*bcefb8aeSAndreas Gohr    /** @inheritdoc */
26*bcefb8aeSAndreas Gohr    protected function getInstructionName(): string
27*bcefb8aeSAndreas Gohr    {
28*bcefb8aeSAndreas Gohr        return 'emphasis';
29*bcefb8aeSAndreas Gohr    }
30*bcefb8aeSAndreas Gohr
31*bcefb8aeSAndreas Gohr    /** @inheritdoc */
32*bcefb8aeSAndreas Gohr    protected function getEntryPattern(): string
33*bcefb8aeSAndreas Gohr    {
34*bcefb8aeSAndreas Gohr        // Broken down:
35*bcefb8aeSAndreas Gohr        //   \*                        — opening `*`
36*bcefb8aeSAndreas Gohr        //   (?=                       — lookahead: a valid closer must exist
37*bcefb8aeSAndreas Gohr        //     [^\s*]                  —   first body char: not whitespace, not `*`
38*bcefb8aeSAndreas Gohr        //                                 (flanking-opener rule)
39*bcefb8aeSAndreas Gohr        //     (?:                     —   optional: more body
40*bcefb8aeSAndreas Gohr        //       (?:NOT_AT_PARA_BREAK  —     …any non-`*` char that doesn't
41*bcefb8aeSAndreas Gohr        //          [^*])*             —     start a paragraph break
42*bcefb8aeSAndreas Gohr        //       [^\s*]                —     last body char: not whitespace, not `*`
43*bcefb8aeSAndreas Gohr        //                                 (flanking-closer rule)
44*bcefb8aeSAndreas Gohr        //     )?                      —   `?` so single-char bodies like `*a*`
45*bcefb8aeSAndreas Gohr        //                                 also match
46*bcefb8aeSAndreas Gohr        //     \*                      —   closing `*`
47*bcefb8aeSAndreas Gohr        //   )
48*bcefb8aeSAndreas Gohr        return '\*(?=[^\s*](?:(?:' . self::NOT_AT_PARA_BREAK . '[^*])*[^\s*])?\*)';
49*bcefb8aeSAndreas Gohr    }
50*bcefb8aeSAndreas Gohr
51*bcefb8aeSAndreas Gohr    /** @inheritdoc */
52*bcefb8aeSAndreas Gohr    protected function getExitPattern(): string
53*bcefb8aeSAndreas Gohr    {
54*bcefb8aeSAndreas Gohr        return '(?<=[^\s])\*';
55*bcefb8aeSAndreas Gohr    }
56*bcefb8aeSAndreas Gohr}
57