xref: /dokuwiki/inc/Parsing/Handler/Nest.php (revision ccc4c71ca88c25bcefb7f42eb01f0c040487e3a9)
1<?php
2
3namespace dokuwiki\Parsing\Handler;
4
5/**
6 * Generic call writer class to handle nesting of rendering instructions
7 * within a render instruction. Also see nest() method of renderer base class
8 *
9 * @author    Chris Smith <chris@jalakai.co.uk>
10 */
11class Nest implements ReWriterInterface
12{
13
14    /** @var CallWriterInterface original CallWriter */
15    protected $callWriter;
16
17    protected $calls = array();
18    protected $closingInstruction;
19
20    /**
21     * @inheritdoc
22     *
23     * @param  CallWriterInterface $CallWriter     the parser's current call writer, i.e. the one above us in the chain
24     * @param  string     $close          closing instruction name, this is required to properly terminate the
25     *                                    syntax mode if the document ends without a closing pattern
26     */
27    public function __construct(CallWriterInterface $CallWriter, $close = "nest_close")
28    {
29        $this->callWriter = $CallWriter;
30
31        $this->closingInstruction = $close;
32    }
33
34    /** @inheritdoc */
35    public function writeCall($call)
36    {
37        $this->calls[] = $call;
38    }
39
40    /** @inheritdoc */
41    public function writeCalls($calls)
42    {
43        $this->calls = array_merge($this->calls, $calls);
44    }
45
46    /** @inheritdoc */
47    public function finalise()
48    {
49        $last_call = end($this->calls);
50        $this->writeCall(array($this->closingInstruction,array(), $last_call[2]));
51
52        $this->process();
53        $this->callWriter->finalise();
54        unset($this->callWriter);
55    }
56
57    /** @inheritdoc */
58    public function process()
59    {
60        // merge consecutive cdata
61        $unmerged_calls = $this->calls;
62        $this->calls = array();
63
64        foreach ($unmerged_calls as $call) $this->addCall($call);
65
66        $first_call = reset($this->calls);
67        $this->callWriter->writeCall(array("nest", array($this->calls), $first_call[2]));
68
69        return $this->callWriter;
70    }
71
72    protected function addCall($call)
73    {
74        $key = count($this->calls);
75        if ($key and ($call[0] == 'cdata') and ($this->calls[$key-1][0] == 'cdata')) {
76            $this->calls[$key-1][1][0] .= $call[1][0];
77        } elseif ($call[0] == 'eol') {
78            // do nothing (eol shouldn't be allowed, to counter preformatted fix in #1652 & #1699)
79        } else {
80            $this->calls[] = $call;
81        }
82    }
83}
84