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