xref: /dokuwiki/inc/Parsing/ParserMode/Footnote.php (revision 71096e46fcbfaeaa808667aba794e77fe2780169)
1be906b56SAndreas Gohr<?php
2be906b56SAndreas Gohr
3be906b56SAndreas Gohrnamespace dokuwiki\Parsing\ParserMode;
4be906b56SAndreas Gohr
5*71096e46SAndreas Gohruse dokuwiki\Parsing\Handler;
6*71096e46SAndreas Gohruse dokuwiki\Parsing\Handler\Nest;
7c8dd1b9dSAndreas Gohruse dokuwiki\Parsing\ModeRegistry;
8c8dd1b9dSAndreas Gohr
9be906b56SAndreas Gohrclass Footnote extends AbstractMode
10be906b56SAndreas Gohr{
11be906b56SAndreas Gohr    /**
12be906b56SAndreas Gohr     * Footnote constructor.
13be906b56SAndreas Gohr     */
14be906b56SAndreas Gohr    public function __construct()
15be906b56SAndreas Gohr    {
16c8dd1b9dSAndreas Gohr        $this->allowedModes = ModeRegistry::getInstance()->getModesForCategories([
17c8dd1b9dSAndreas Gohr            ModeRegistry::CATEGORY_CONTAINER,
18c8dd1b9dSAndreas Gohr            ModeRegistry::CATEGORY_FORMATTING,
19c8dd1b9dSAndreas Gohr            ModeRegistry::CATEGORY_SUBSTITION,
20c8dd1b9dSAndreas Gohr            ModeRegistry::CATEGORY_PROTECTED,
21c8dd1b9dSAndreas Gohr            ModeRegistry::CATEGORY_DISABLED,
22c8dd1b9dSAndreas Gohr        ]);
23be906b56SAndreas Gohr
24be906b56SAndreas Gohr        unset($this->allowedModes[array_search('footnote', $this->allowedModes)]);
25be906b56SAndreas Gohr    }
26be906b56SAndreas Gohr
27be906b56SAndreas Gohr    /** @inheritdoc */
28*71096e46SAndreas Gohr    public function getSort()
29*71096e46SAndreas Gohr    {
30*71096e46SAndreas Gohr        return 150;
31*71096e46SAndreas Gohr    }
32*71096e46SAndreas Gohr
33*71096e46SAndreas Gohr    /** @inheritdoc */
34be906b56SAndreas Gohr    public function connectTo($mode)
35be906b56SAndreas Gohr    {
36be906b56SAndreas Gohr        $this->Lexer->addEntryPattern(
37be906b56SAndreas Gohr            '\x28\x28(?=.*\x29\x29)',
38be906b56SAndreas Gohr            $mode,
39be906b56SAndreas Gohr            'footnote'
40be906b56SAndreas Gohr        );
41be906b56SAndreas Gohr    }
42be906b56SAndreas Gohr
43be906b56SAndreas Gohr    /** @inheritdoc */
44be906b56SAndreas Gohr    public function postConnect()
45be906b56SAndreas Gohr    {
46be906b56SAndreas Gohr        $this->Lexer->addExitPattern(
47be906b56SAndreas Gohr            '\x29\x29',
48be906b56SAndreas Gohr            'footnote'
49be906b56SAndreas Gohr        );
50be906b56SAndreas Gohr    }
51be906b56SAndreas Gohr
52be906b56SAndreas Gohr    /** @inheritdoc */
53*71096e46SAndreas Gohr    public function handle($match, $state, $pos, Handler $handler)
54be906b56SAndreas Gohr    {
55*71096e46SAndreas Gohr        switch ($state) {
56*71096e46SAndreas Gohr            case DOKU_LEXER_ENTER:
57*71096e46SAndreas Gohr                // footnotes can not be nested - however due to limitations in lexer it can't be prevented
58*71096e46SAndreas Gohr                // we will still enter a new footnote mode, we just do nothing
59*71096e46SAndreas Gohr                if ($handler->getStatus('footnote')) {
60*71096e46SAndreas Gohr                    $handler->addCall('cdata', [$match], $pos);
61*71096e46SAndreas Gohr                    break;
62*71096e46SAndreas Gohr                }
63*71096e46SAndreas Gohr                $handler->setStatus('footnote', true);
64*71096e46SAndreas Gohr
65*71096e46SAndreas Gohr                $handler->setCallWriter(new Nest($handler->getCallWriter(), 'footnote_close'));
66*71096e46SAndreas Gohr                $handler->addCall('footnote_open', [], $pos);
67*71096e46SAndreas Gohr                break;
68*71096e46SAndreas Gohr            case DOKU_LEXER_EXIT:
69*71096e46SAndreas Gohr                // check whether we have already exited the footnote mode, can happen if the modes were nested
70*71096e46SAndreas Gohr                if (!$handler->getStatus('footnote')) {
71*71096e46SAndreas Gohr                    $handler->addCall('cdata', [$match], $pos);
72*71096e46SAndreas Gohr                    break;
73*71096e46SAndreas Gohr                }
74*71096e46SAndreas Gohr
75*71096e46SAndreas Gohr                $handler->setStatus('footnote', false);
76*71096e46SAndreas Gohr                $handler->addCall('footnote_close', [], $pos);
77*71096e46SAndreas Gohr
78*71096e46SAndreas Gohr                /** @var Nest $reWriter */
79*71096e46SAndreas Gohr                $reWriter = $handler->getCallWriter();
80*71096e46SAndreas Gohr                $handler->setCallWriter($reWriter->process());
81*71096e46SAndreas Gohr                break;
82*71096e46SAndreas Gohr            case DOKU_LEXER_UNMATCHED:
83*71096e46SAndreas Gohr                $handler->addCall('cdata', [$match], $pos);
84*71096e46SAndreas Gohr                break;
85*71096e46SAndreas Gohr        }
86*71096e46SAndreas Gohr        return true;
87be906b56SAndreas Gohr    }
88be906b56SAndreas Gohr}
89