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