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