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