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