1<?php 2/** 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation; either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write to the Free Software Foundation, Inc., 15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 * http://www.gnu.org/copyleft/gpl.html 17 * 18 * @file 19 * @ingroup Parser 20 */ 21 22/** 23 * @ingroup Parser 24 * 25 * @property int $startPos 26 */ 27class PPDStackElement { 28 /** 29 * @var string Opening character (\n for heading) 30 */ 31 public $open; 32 33 /** 34 * @var string Matching closing character 35 */ 36 public $close; 37 38 /** 39 * @var string Saved prefix that may affect later processing, 40 * e.g. to differentiate `-{{{{` and `{{{{` after later seeing `}}}`. 41 */ 42 public $savedPrefix = ''; 43 44 /** 45 * @var int Number of opening characters found (number of "=" for heading) 46 */ 47 public $count; 48 49 /** 50 * @var PPDPart[] Array of PPDPart objects describing pipe-separated parts. 51 */ 52 public $parts; 53 54 /** 55 * @var bool True if the open char appeared at the start of the input line. 56 * Not set for headings. 57 */ 58 public $lineStart; 59 60 public $partClass = PPDPart::class; 61 62 public function __construct( $data = [] ) { 63 $class = $this->partClass; 64 $this->parts = [ new $class ]; 65 66 foreach ( $data as $name => $value ) { 67 $this->$name = $value; 68 } 69 } 70 71 public function &getAccum() { 72 return $this->parts[count( $this->parts ) - 1]->out; 73 } 74 75 public function addPart( $s = '' ) { 76 $class = $this->partClass; 77 $this->parts[] = new $class( $s ); 78 } 79 80 /** 81 * @return PPDPart 82 */ 83 public function getCurrentPart() { 84 return $this->parts[count( $this->parts ) - 1]; 85 } 86 87 /** 88 * @return array 89 */ 90 public function getFlags() { 91 $partCount = count( $this->parts ); 92 $findPipe = $this->open != "\n" && $this->open != '['; 93 return [ 94 'findPipe' => $findPipe, 95 'findEquals' => $findPipe && $partCount > 1 && !isset( $this->parts[$partCount - 1]->eqpos ), 96 'inHeading' => $this->open == "\n", 97 ]; 98 } 99 100 /** 101 * Get the output string that would result if the close is not found. 102 * 103 * @param bool|int $openingCount 104 * @return string 105 */ 106 public function breakSyntax( $openingCount = false ) { 107 if ( $this->open == "\n" ) { 108 $s = $this->savedPrefix . $this->parts[0]->out; 109 } else { 110 if ( $openingCount === false ) { 111 $openingCount = $this->count; 112 } 113 $s = substr( $this->open, 0, -1 ); 114 $s .= str_repeat( 115 substr( $this->open, -1 ), 116 $openingCount - strlen( $s ) 117 ); 118 $s = $this->savedPrefix . $s; 119 $first = true; 120 foreach ( $this->parts as $part ) { 121 if ( $first ) { 122 $first = false; 123 } else { 124 $s .= '|'; 125 } 126 $s .= $part->out; 127 } 128 } 129 return $s; 130 } 131} 132