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 renderers current call writer 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