xref: /dokuwiki/inc/Parsing/ParserMode/Quotes.php (revision 3a5ba3950fc204126863b1163f31d6dd1eb85249)
1<?php
2
3namespace dokuwiki\Parsing\ParserMode;
4
5use dokuwiki\Parsing\Handler;
6
7class Quotes extends AbstractMode
8{
9    /** @inheritdoc */
10    public function getSort()
11    {
12        return 280;
13    }
14
15    /** @inheritdoc */
16    public function connectTo($mode)
17    {
18        global $conf;
19
20        // word boundaries around a quote: whitespace plus inline-formatting
21        // delimiters (/ ** __ etc.) that may sit next to it after being consumed
22        $ws   =  '\s/\#~:+=&%@\-\x28\x29\]\[{}><"\'*_';
23        $punc =  ';,\.?!';
24
25        if ($conf['typography'] == 2) {
26            $this->Lexer->addSpecialPattern(
27                "(?<=^|[$ws])'(?=[^$ws$punc])",
28                $mode,
29                'singlequoteopening'
30            );
31            $this->Lexer->addSpecialPattern(
32                "(?<=^|[^$ws]|[$punc])'(?=$|[$ws$punc])",
33                $mode,
34                'singlequoteclosing'
35            );
36            $this->Lexer->addSpecialPattern(
37                "(?<=^|[^$ws$punc])'(?=$|[^$ws$punc])",
38                $mode,
39                'apostrophe'
40            );
41        }
42
43        $this->Lexer->addSpecialPattern(
44            "(?<=^|[$ws])\"(?=[^$ws$punc])",
45            $mode,
46            'doublequoteopening'
47        );
48        $this->Lexer->addSpecialPattern(
49            "\"",
50            $mode,
51            'doublequoteclosing'
52        );
53    }
54
55    /** @inheritdoc */
56    public function postConnect()
57    {
58        // Map all sub-mode names back to 'quotes' so the Handler
59        // dispatches them to this mode object
60        $this->Lexer->mapHandler('singlequoteopening', 'quotes');
61        $this->Lexer->mapHandler('singlequoteclosing', 'quotes');
62        $this->Lexer->mapHandler('apostrophe', 'quotes');
63        $this->Lexer->mapHandler('doublequoteopening', 'quotes');
64        $this->Lexer->mapHandler('doublequoteclosing', 'quotes');
65    }
66
67    /** @inheritdoc */
68    public function handle($match, $state, $pos, Handler $handler)
69    {
70        $call = $handler->getModeName();
71
72        if ($call === 'doublequoteclosing' && $handler->getStatus('doublequote') <= 0) {
73            $call = 'doublequoteopening';
74        }
75
76        if ($call === 'doublequoteopening') {
77            $handler->setStatus('doublequote', $handler->getStatus('doublequote') + 1);
78        } elseif ($call === 'doublequoteclosing') {
79            $handler->setStatus('doublequote', max(0, $handler->getStatus('doublequote') - 1));
80        }
81
82        $handler->addCall($call, [], $pos);
83        return true;
84    }
85}
86