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 protected function getClosingCall(): string 42 { 43 return $this->closingInstruction; 44 } 45 46 /** @inheritdoc */ 47 public function process() 48 { 49 // merge consecutive cdata 50 $unmerged_calls = $this->calls; 51 $this->calls = []; 52 53 foreach ($unmerged_calls as $call) $this->addCall($call); 54 55 $first_call = reset($this->calls); 56 $this->callWriter->writeCall(["nest", [$this->calls], $first_call[2]]); 57 58 return $this->callWriter; 59 } 60 61 /** 62 * @param array $call 63 */ 64 protected function addCall($call) 65 { 66 $key = count($this->calls); 67 if ($key && $call[0] == 'cdata' && $this->calls[$key - 1][0] == 'cdata') { 68 $this->calls[$key - 1][1][0] .= $call[1][0]; 69 } elseif ($call[0] == 'eol') { 70 // do nothing (eol shouldn't be allowed, to counter preformatted fix in #1652 & #1699) 71 } else { 72 $this->calls[] = $call; 73 } 74 } 75} 76