xref: /dokuwiki/inc/Parsing/ParserMode/GfmLinebreak.php (revision b73ece99c18919754d993a1d1f5cb27140555705)
1<?php
2
3namespace dokuwiki\Parsing\ParserMode;
4
5use dokuwiki\Parsing\Handler;
6
7/**
8 * GFM hard line break: two-or-more trailing spaces, or a single
9 * backslash, immediately before a non-final newline.
10 *
11 * Both delimiter forms land in one mode because they share semantics
12 * (emit linebreak), share the block-boundary rule (no break at the
13 * end of a paragraph or other block), and share the next-line
14 * leading-whitespace consumption (GFM strips it). Keeping all hard-
15 * break logic in one pattern is cheaper than two and matches GFM
16 * spec section 6.7 directly.
17 *
18 * Bypass inside code spans and fenced blocks falls out for free:
19 * those are whole-span PROTECTED / FORMATTING modes that capture
20 * their body in one regex match, so SUBSTITUTION patterns never see
21 * the inner text — same mechanism that exempts GfmEscape from
22 * code spans.
23 *
24 * Coexists with DokuWiki's Linebreak mode (also at sort 140). The two
25 * delimiter shapes are disjoint: GfmLinebreak takes a single `\` (or
26 * two+ spaces) before a non-final newline, DW Linebreak takes `\\`
27 * before a space, tab, or newline.
28 */
29class GfmLinebreak extends AbstractMode
30{
31    /** @inheritdoc */
32    public function getSort()
33    {
34        return 140;
35    }
36
37    /** @inheritdoc */
38    public function connectTo($mode)
39    {
40        // (?:[ ]{2,}|\\)            two+ spaces OR one backslash
41        // \n                        the line ending
42        // (?![ \t]*(?:\n|\z))       not at a paragraph break or EOF
43        // [ \t]*                    swallow leading WS of the next line
44        $this->Lexer->addSpecialPattern(
45            '(?:[ ]{2,}|\\\\)\n(?![ \t]*(?:\n|\z))[ \t]*',
46            $mode,
47            'gfm_linebreak'
48        );
49    }
50
51    /** @inheritdoc */
52    public function handle($match, $state, $pos, Handler $handler)
53    {
54        $handler->addCall('linebreak', [], $pos);
55        return true;
56    }
57}
58