xref: /dokuwiki/inc/Parsing/Handler/Quote.php (revision 69ac5662a92b13b9b9e3da1545f512c3acf7244e)
1<?php
2
3namespace dokuwiki\Parsing\Handler;
4
5class Quote implements ReWriterInterface
6{
7
8    /** @var CallWriterInterface original CallWriter */
9    protected $callWriter;
10
11    protected $calls = array();
12
13    protected $quoteCalls = array();
14
15    /** @inheritdoc */
16    public function __construct(CallWriterInterface $CallWriter)
17    {
18        $this->callWriter = $CallWriter;
19    }
20
21    /** @inheritdoc */
22    public function writeCall($call)
23    {
24        $this->calls[] = $call;
25    }
26
27    /**
28     * @inheritdoc
29     *
30     * Probably not needed but just in case...
31     */
32    public function writeCalls($calls)
33    {
34        $this->calls = array_merge($this->calls, $calls);
35    }
36
37    /** @inheritdoc */
38    public function finalise()
39    {
40        $last_call = end($this->calls);
41        $this->writeCall(array('quote_end',array(), $last_call[2]));
42
43        $this->process();
44        $this->callWriter->finalise();
45        unset($this->callWriter);
46    }
47
48    /** @inheritdoc */
49    public function process()
50    {
51
52        $quoteDepth = 1;
53
54        foreach ($this->calls as $call) {
55            switch ($call[0]) {
56
57                /** @noinspection PhpMissingBreakStatementInspection */
58                case 'quote_start':
59                    $this->quoteCalls[] = array('quote_open',array(),$call[2]);
60                    // fallthrough
61                case 'quote_newline':
62                    $quoteLength = $this->getDepth($call[1][0]);
63
64                    if ($quoteLength > $quoteDepth) {
65                        $quoteDiff = $quoteLength - $quoteDepth;
66                        for ($i = 1; $i <= $quoteDiff; $i++) {
67                            $this->quoteCalls[] = array('quote_open',array(),$call[2]);
68                        }
69                    } elseif ($quoteLength < $quoteDepth) {
70                        $quoteDiff = $quoteDepth - $quoteLength;
71                        for ($i = 1; $i <= $quoteDiff; $i++) {
72                            $this->quoteCalls[] = array('quote_close',array(),$call[2]);
73                        }
74                    } else {
75                        if ($call[0] != 'quote_start') $this->quoteCalls[] = array('linebreak',array(),$call[2]);
76                    }
77
78                    $quoteDepth = $quoteLength;
79
80                    break;
81
82                case 'quote_end':
83                    if ($quoteDepth > 1) {
84                        $quoteDiff = $quoteDepth - 1;
85                        for ($i = 1; $i <= $quoteDiff; $i++) {
86                            $this->quoteCalls[] = array('quote_close',array(),$call[2]);
87                        }
88                    }
89
90                    $this->quoteCalls[] = array('quote_close',array(),$call[2]);
91
92                    $this->callWriter->writeCalls($this->quoteCalls);
93                    break;
94
95                default:
96                    $this->quoteCalls[] = $call;
97                    break;
98            }
99        }
100
101        return $this->callWriter;
102    }
103
104    protected function getDepth($marker)
105    {
106        preg_match('/>{1,}/', $marker, $matches);
107        $quoteLength = strlen($matches[0]);
108        return $quoteLength;
109    }
110}
111