[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * @package s9e\TextFormatter 5 * @copyright Copyright (c) 2010-2019 The s9e Authors 6 * @license http://www.opensource.org/licenses/mit-license.php The MIT License 7 */ 8 namespace s9e\TextFormatter\Plugins\BBCodes; 9 use RuntimeException; 10 use s9e\TextFormatter\Parser\Tag; 11 use s9e\TextFormatter\Plugins\ParserBase; 12 class Parser extends ParserBase 13 { 14 protected $attributes; 15 protected $bbcodeConfig; 16 protected $bbcodeName; 17 protected $bbcodeSuffix; 18 protected $pos; 19 protected $startPos; 20 protected $text; 21 protected $textLen; 22 protected $uppercaseText; 23 public function parse($text, array $matches) 24 { 25 $this->text = $text; 26 $this->textLen = \strlen($text); 27 $this->uppercaseText = ''; 28 foreach ($matches as $m) 29 { 30 $this->bbcodeName = \strtoupper($m[1][0]); 31 if (!isset($this->config['bbcodes'][$this->bbcodeName])) 32 continue; 33 $this->bbcodeConfig = $this->config['bbcodes'][$this->bbcodeName]; 34 $this->startPos = $m[0][1]; 35 $this->pos = $this->startPos + \strlen($m[0][0]); 36 try 37 { 38 $this->parseBBCode(); 39 } 40 catch (RuntimeException $e) 41 { 42 } 43 } 44 } 45 protected function addBBCodeEndTag() 46 { 47 return $this->parser->addEndTag($this->getTagName(), $this->startPos, $this->pos - $this->startPos); 48 } 49 protected function addBBCodeSelfClosingTag() 50 { 51 $tag = $this->parser->addSelfClosingTag($this->getTagName(), $this->startPos, $this->pos - $this->startPos); 52 $tag->setAttributes($this->attributes); 53 return $tag; 54 } 55 protected function addBBCodeStartTag() 56 { 57 $tag = $this->parser->addStartTag($this->getTagName(), $this->startPos, $this->pos - $this->startPos); 58 $tag->setAttributes($this->attributes); 59 return $tag; 60 } 61 protected function captureEndTag() 62 { 63 if (empty($this->uppercaseText)) 64 $this->uppercaseText = \strtoupper($this->text); 65 $match = '[/' . $this->bbcodeName . $this->bbcodeSuffix . ']'; 66 $endTagPos = \strpos($this->uppercaseText, $match, $this->pos); 67 if ($endTagPos === \false) 68 return; 69 return $this->parser->addEndTag($this->getTagName(), $endTagPos, \strlen($match)); 70 } 71 protected function getTagName() 72 { 73 return (isset($this->bbcodeConfig['tagName'])) 74 ? $this->bbcodeConfig['tagName'] 75 : $this->bbcodeName; 76 } 77 protected function parseAttributes() 78 { 79 $firstPos = $this->pos; 80 $this->attributes = []; 81 while ($this->pos < $this->textLen) 82 { 83 $c = $this->text[$this->pos]; 84 if (\strpos(" \n\t", $c) !== \false) 85 { 86 ++$this->pos; 87 continue; 88 } 89 if (\strpos('/]', $c) !== \false) 90 return; 91 $spn = \strspn($this->text, 'abcdefghijklmnopqrstuvwxyz_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-', $this->pos); 92 if ($spn) 93 { 94 $attrName = \strtolower(\substr($this->text, $this->pos, $spn)); 95 $this->pos += $spn; 96 if ($this->pos >= $this->textLen) 97 throw new RuntimeException; 98 if ($this->text[$this->pos] !== '=') 99 continue; 100 } 101 elseif ($c === '=' && $this->pos === $firstPos) 102 $attrName = (isset($this->bbcodeConfig['defaultAttribute'])) 103 ? $this->bbcodeConfig['defaultAttribute'] 104 : \strtolower($this->bbcodeName); 105 else 106 throw new RuntimeException; 107 if (++$this->pos >= $this->textLen) 108 throw new RuntimeException; 109 $this->attributes[$attrName] = $this->parseAttributeValue(); 110 } 111 } 112 protected function parseAttributeValue() 113 { 114 if ($this->text[$this->pos] === '"' || $this->text[$this->pos] === "'") 115 return $this->parseQuotedAttributeValue(); 116 if (!\preg_match('#[^\\]\\n]*?(?=\\s*(?:\\s/)?\\]|\\s+[-\\w]+=)#', $this->text, $m, \null, $this->pos)) 117 throw new RuntimeException; 118 $attrValue = $m[0]; 119 $this->pos += \strlen($attrValue); 120 return $attrValue; 121 } 122 protected function parseBBCode() 123 { 124 $this->parseBBCodeSuffix(); 125 if ($this->text[$this->startPos + 1] === '/') 126 { 127 if (\substr($this->text, $this->pos, 1) === ']' && $this->bbcodeSuffix === '') 128 { 129 ++$this->pos; 130 $this->addBBCodeEndTag(); 131 } 132 return; 133 } 134 $this->parseAttributes(); 135 if (\substr($this->text, $this->pos, 1) === ']') 136 ++$this->pos; 137 else 138 { 139 if (\substr($this->text, $this->pos, 2) === '/]') 140 { 141 $this->pos += 2; 142 $this->addBBCodeSelfClosingTag(); 143 } 144 return; 145 } 146 $contentAttributes = []; 147 if (isset($this->bbcodeConfig['contentAttributes'])) 148 foreach ($this->bbcodeConfig['contentAttributes'] as $attrName) 149 if (!isset($this->attributes[$attrName])) 150 $contentAttributes[] = $attrName; 151 $requireEndTag = ($this->bbcodeSuffix || !empty($this->bbcodeConfig['forceLookahead'])); 152 $endTag = ($requireEndTag || !empty($contentAttributes)) ? $this->captureEndTag() : \null; 153 if (isset($endTag)) 154 foreach ($contentAttributes as $attrName) 155 $this->attributes[$attrName] = \substr($this->text, $this->pos, $endTag->getPos() - $this->pos); 156 elseif ($requireEndTag) 157 return; 158 $tag = $this->addBBCodeStartTag(); 159 if (isset($endTag)) 160 $tag->pairWith($endTag); 161 } 162 protected function parseBBCodeSuffix() 163 { 164 $this->bbcodeSuffix = ''; 165 if ($this->text[$this->pos] === ':') 166 { 167 $spn = 1 + \strspn($this->text, '0123456789', 1 + $this->pos); 168 $this->bbcodeSuffix = \substr($this->text, $this->pos, $spn); 169 $this->pos += $spn; 170 } 171 } 172 protected function parseQuotedAttributeValue() 173 { 174 $quote = $this->text[$this->pos]; 175 $valuePos = $this->pos + 1; 176 while (1) 177 { 178 $this->pos = \strpos($this->text, $quote, $this->pos + 1); 179 if ($this->pos === \false) 180 throw new RuntimeException; 181 $n = 0; 182 do 183 { 184 ++$n; 185 } 186 while ($this->text[$this->pos - $n] === '\\'); 187 if ($n % 2) 188 break; 189 } 190 $attrValue = \preg_replace( 191 '#\\\\([\\\\\'"])#', 192 '$1', 193 \substr($this->text, $valuePos, $this->pos - $valuePos) 194 ); 195 ++$this->pos; 196 return $attrValue; 197 } 198 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |