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