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 */ 11be906b56SAndreas Gohrclass Nest implements ReWriterInterface 12be906b56SAndreas Gohr{ 13be906b56SAndreas Gohr 14be906b56SAndreas Gohr /** @var CallWriterInterface original CallWriter */ 15be906b56SAndreas Gohr protected $callWriter; 16be906b56SAndreas Gohr 17be906b56SAndreas Gohr protected $calls = array(); 18be906b56SAndreas Gohr protected $closingInstruction; 19be906b56SAndreas Gohr 20be906b56SAndreas Gohr /** 21be906b56SAndreas Gohr * @inheritdoc 22be906b56SAndreas Gohr * 23*661c1ddcSChristopher Smith * @param CallWriterInterface $CallWriter the parser's current call writer, i.e. the one above us in the chain 24be906b56SAndreas Gohr * @param string $close closing instruction name, this is required to properly terminate the 25be906b56SAndreas Gohr * syntax mode if the document ends without a closing pattern 26be906b56SAndreas Gohr */ 27be906b56SAndreas Gohr public function __construct(CallWriterInterface $CallWriter, $close = "nest_close") 28be906b56SAndreas Gohr { 29be906b56SAndreas Gohr $this->callWriter = $CallWriter; 30be906b56SAndreas Gohr 31be906b56SAndreas Gohr $this->closingInstruction = $close; 32be906b56SAndreas Gohr } 33be906b56SAndreas Gohr 34be906b56SAndreas Gohr /** @inheritdoc */ 35be906b56SAndreas Gohr public function writeCall($call) 36be906b56SAndreas Gohr { 37be906b56SAndreas Gohr $this->calls[] = $call; 38be906b56SAndreas Gohr } 39be906b56SAndreas Gohr 40be906b56SAndreas Gohr /** @inheritdoc */ 41be906b56SAndreas Gohr public function writeCalls($calls) 42be906b56SAndreas Gohr { 43be906b56SAndreas Gohr $this->calls = array_merge($this->calls, $calls); 44be906b56SAndreas Gohr } 45be906b56SAndreas Gohr 46be906b56SAndreas Gohr /** @inheritdoc */ 47be906b56SAndreas Gohr public function finalise() 48be906b56SAndreas Gohr { 49be906b56SAndreas Gohr $last_call = end($this->calls); 50be906b56SAndreas Gohr $this->writeCall(array($this->closingInstruction,array(), $last_call[2])); 51be906b56SAndreas Gohr 52be906b56SAndreas Gohr $this->process(); 53be906b56SAndreas Gohr $this->callWriter->finalise(); 54be906b56SAndreas Gohr unset($this->callWriter); 55be906b56SAndreas Gohr } 56be906b56SAndreas Gohr 57be906b56SAndreas Gohr /** @inheritdoc */ 58be906b56SAndreas Gohr public function process() 59be906b56SAndreas Gohr { 60be906b56SAndreas Gohr // merge consecutive cdata 61be906b56SAndreas Gohr $unmerged_calls = $this->calls; 62be906b56SAndreas Gohr $this->calls = array(); 63be906b56SAndreas Gohr 64be906b56SAndreas Gohr foreach ($unmerged_calls as $call) $this->addCall($call); 65be906b56SAndreas Gohr 66be906b56SAndreas Gohr $first_call = reset($this->calls); 67be906b56SAndreas Gohr $this->callWriter->writeCall(array("nest", array($this->calls), $first_call[2])); 68be906b56SAndreas Gohr 69be906b56SAndreas Gohr return $this->callWriter; 70be906b56SAndreas Gohr } 71be906b56SAndreas Gohr 72be906b56SAndreas Gohr protected function addCall($call) 73be906b56SAndreas Gohr { 74be906b56SAndreas Gohr $key = count($this->calls); 75be906b56SAndreas Gohr if ($key and ($call[0] == 'cdata') and ($this->calls[$key-1][0] == 'cdata')) { 76be906b56SAndreas Gohr $this->calls[$key-1][1][0] .= $call[1][0]; 77be906b56SAndreas Gohr } elseif ($call[0] == 'eol') { 78be906b56SAndreas Gohr // do nothing (eol shouldn't be allowed, to counter preformatted fix in #1652 & #1699) 79be906b56SAndreas Gohr } else { 80be906b56SAndreas Gohr $this->calls[] = $call; 81be906b56SAndreas Gohr } 82be906b56SAndreas Gohr } 83be906b56SAndreas Gohr} 84