xref: /dokuwiki/inc/Parsing/ParserMode/Table.php (revision 884caed926ca0aa0af6ce3f34ae3aa7317a3361a)
1<?php
2
3namespace dokuwiki\Parsing\ParserMode;
4
5use dokuwiki\Parsing\Handler;
6use dokuwiki\Parsing\Handler\Table as TableHandler;
7use dokuwiki\Parsing\ModeRegistry;
8
9class Table extends AbstractMode
10{
11    /** @inheritdoc */
12    protected function allowedCategories(): array
13    {
14        return [
15            ModeRegistry::CATEGORY_FORMATTING,
16            ModeRegistry::CATEGORY_SUBSTITUTION,
17            ModeRegistry::CATEGORY_DISABLED,
18            ModeRegistry::CATEGORY_PROTECTED,
19        ];
20    }
21
22    /** @inheritdoc */
23    public function getSort()
24    {
25        return 60;
26    }
27
28    /** @inheritdoc */
29    public function preConnect()
30    {
31        $this->registry->registerBlockEolMode('table');
32    }
33
34    /** @inheritdoc */
35    public function connectTo($mode)
36    {
37        $this->Lexer->addEntryPattern('[\t ]*\n\^', $mode, 'table');
38        $this->Lexer->addEntryPattern('[\t ]*\n\|', $mode, 'table');
39    }
40
41    /** @inheritdoc */
42    public function postConnect()
43    {
44        $this->Lexer->addPattern('\n\^', 'table');
45        $this->Lexer->addPattern('\n\|', 'table');
46        $this->Lexer->addPattern('[\t ]*:::[\t ]*(?=[\|\^])', 'table');
47        $this->Lexer->addPattern('[\t ]+', 'table');
48        $this->Lexer->addPattern('\^', 'table');
49        $this->Lexer->addPattern('\|', 'table');
50        $this->Lexer->addExitPattern('\n', 'table');
51    }
52
53    /** @inheritdoc */
54    public function handle($match, $state, $pos, Handler $handler)
55    {
56        switch ($state) {
57            case DOKU_LEXER_ENTER:
58                $handler->setCallWriter(new TableHandler($handler->getCallWriter()));
59
60                $handler->addCall('table_start', [$pos + 1], $pos);
61                if (trim($match) == '^') {
62                    $handler->addCall('tableheader', [], $pos);
63                } else {
64                    $handler->addCall('tablecell', [], $pos);
65                }
66                break;
67
68            case DOKU_LEXER_EXIT:
69                $handler->addCall('table_end', [$pos], $pos);
70                /** @var TableHandler $reWriter */
71                $reWriter = $handler->getCallWriter();
72                $handler->setCallWriter($reWriter->process());
73                break;
74
75            case DOKU_LEXER_UNMATCHED:
76                if (trim($match) != '') {
77                    $handler->addCall('cdata', [$match], $pos);
78                }
79                break;
80
81            case DOKU_LEXER_MATCHED:
82                if ($match == ' ') {
83                    $handler->addCall('cdata', [$match], $pos);
84                } elseif (preg_match('/:::/', $match)) {
85                    $handler->addCall('rowspan', [$match], $pos);
86                } elseif (preg_match('/\t+/', $match)) {
87                    $handler->addCall('table_align', [$match], $pos);
88                } elseif (preg_match('/ {2,}/', $match)) {
89                    $handler->addCall('table_align', [$match], $pos);
90                } elseif ($match == "\n|") {
91                    $handler->addCall('table_row', [], $pos);
92                    $handler->addCall('tablecell', [], $pos);
93                } elseif ($match == "\n^") {
94                    $handler->addCall('table_row', [], $pos);
95                    $handler->addCall('tableheader', [], $pos);
96                } elseif ($match == '|') {
97                    $handler->addCall('tablecell', [], $pos);
98                } elseif ($match == '^') {
99                    $handler->addCall('tableheader', [], $pos);
100                }
101                break;
102        }
103        return true;
104    }
105}
106