[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package s9e\TextFormatter 5 * @copyright Copyright (c) 2010-2022 The s9e authors 6 * @license http://www.opensource.org/licenses/mit-license.php The MIT License 7 */ 8 namespace s9e\TextFormatter\Plugins\Litedown\Parser\Passes; 9 10 class Emphasis extends AbstractPass 11 { 12 /** 13 * @var bool Whether current EM span is being closed by current emphasis mark 14 */ 15 protected $closeEm; 16 17 /** 18 * @var bool Whether current EM span is being closed by current emphasis mark 19 */ 20 protected $closeStrong; 21 22 /** 23 * @var integer Starting position of the current EM span in the text 24 */ 25 protected $emPos; 26 27 /** 28 * @var integer Ending position of the current EM span in the text 29 */ 30 protected $emEndPos; 31 32 /** 33 * @var integer Number of emphasis characters unused in current span 34 */ 35 protected $remaining; 36 37 /** 38 * @var integer Starting position of the current STRONG span in the text 39 */ 40 protected $strongPos; 41 42 /** 43 * @var integer Ending position of the current STRONG span in the text 44 */ 45 protected $strongEndPos; 46 47 /** 48 * {@inheritdoc} 49 */ 50 public function parse() 51 { 52 $this->parseEmphasisByCharacter('*', '/\\*+/'); 53 $this->parseEmphasisByCharacter('_', '/_+/'); 54 } 55 56 /** 57 * Adjust the ending position of current EM and STRONG spans 58 * 59 * @return void 60 */ 61 protected function adjustEndingPositions() 62 { 63 if ($this->closeEm && $this->closeStrong) 64 { 65 if ($this->emPos < $this->strongPos) 66 { 67 $this->emEndPos += 2; 68 } 69 else 70 { 71 ++$this->strongEndPos; 72 } 73 } 74 } 75 76 /** 77 * Adjust the starting position of current EM and STRONG spans 78 * 79 * If both EM and STRONG are set to start at the same position, we adjust their position 80 * to match the order they are closed. If they start and end at the same position, STRONG 81 * starts before EM to match Markdown's behaviour 82 * 83 * @return void 84 */ 85 protected function adjustStartingPositions() 86 { 87 if ($this->emPos >= 0 && $this->emPos === $this->strongPos) 88 { 89 if ($this->closeEm) 90 { 91 $this->emPos += 2; 92 } 93 else 94 { 95 ++$this->strongPos; 96 } 97 } 98 } 99 100 /** 101 * End current valid EM and STRONG spans 102 * 103 * @return void 104 */ 105 protected function closeSpans() 106 { 107 if ($this->closeEm) 108 { 109 --$this->remaining; 110 $this->parser->addTagPair('EM', $this->emPos, 1, $this->emEndPos, 1); 111 $this->emPos = -1; 112 } 113 if ($this->closeStrong) 114 { 115 $this->remaining -= 2; 116 $this->parser->addTagPair('STRONG', $this->strongPos, 2, $this->strongEndPos, 2); 117 $this->strongPos = -1; 118 } 119 } 120 121 /** 122 * Parse emphasis and strong applied using given character 123 * 124 * @param string $character Markup character, either * or _ 125 * @param string $regexp Regexp used to match the series of emphasis character 126 * @return void 127 */ 128 protected function parseEmphasisByCharacter($character, $regexp) 129 { 130 $pos = $this->text->indexOf($character); 131 if ($pos === false) 132 { 133 return; 134 } 135 136 foreach ($this->getEmphasisByBlock($regexp, $pos) as $block) 137 { 138 $this->processEmphasisBlock($block); 139 } 140 } 141 142 /** 143 * Get emphasis markup split by block 144 * 145 * @param string $regexp Regexp used to match emphasis 146 * @param integer $pos Position in the text of the first emphasis character 147 * @return array[] Each array contains a list of [matchPos, matchLen] pairs 148 */ 149 protected function getEmphasisByBlock($regexp, $pos) 150 { 151 $block = []; 152 $blocks = []; 153 $breakPos = $this->text->indexOf("\x17", $pos); 154 155 preg_match_all($regexp, $this->text, $matches, PREG_OFFSET_CAPTURE, $pos); 156 foreach ($matches[0] as $m) 157 { 158 $matchPos = $m[1]; 159 $matchLen = strlen($m[0]); 160 161 // Test whether we've just passed the limits of a block 162 if ($matchPos > $breakPos) 163 { 164 $blocks[] = $block; 165 $block = []; 166 $breakPos = $this->text->indexOf("\x17", $matchPos); 167 } 168 169 // Test whether we should ignore this markup 170 if (!$this->ignoreEmphasis($matchPos, $matchLen)) 171 { 172 $block[] = [$matchPos, $matchLen]; 173 } 174 } 175 $blocks[] = $block; 176 177 return $blocks; 178 } 179 180 /** 181 * Test whether emphasis should be ignored at the given position in the text 182 * 183 * @param integer $matchPos Position of the emphasis in the text 184 * @param integer $matchLen Length of the emphasis 185 * @return bool 186 */ 187 protected function ignoreEmphasis($matchPos, $matchLen) 188 { 189 // Ignore single underscores between alphanumeric characters 190 return ($this->text->charAt($matchPos) === '_' && $matchLen === 1 && $this->text->isSurroundedByAlnum($matchPos, $matchLen)); 191 } 192 193 /** 194 * Open EM and STRONG spans whose content starts at given position 195 * 196 * @param integer $pos 197 * @return void 198 */ 199 protected function openSpans($pos) 200 { 201 if ($this->remaining & 1) 202 { 203 $this->emPos = $pos - $this->remaining; 204 } 205 if ($this->remaining & 2) 206 { 207 $this->strongPos = $pos - $this->remaining; 208 } 209 } 210 211 /** 212 * Process a list of emphasis markup strings 213 * 214 * @param array[] $block List of [matchPos, matchLen] pairs 215 * @return void 216 */ 217 protected function processEmphasisBlock(array $block) 218 { 219 $this->emPos = -1; 220 $this->strongPos = -1; 221 foreach ($block as list($matchPos, $matchLen)) 222 { 223 $this->processEmphasisMatch($matchPos, $matchLen); 224 } 225 } 226 227 /** 228 * Process an emphasis mark 229 * 230 * @param integer $matchPos 231 * @param integer $matchLen 232 * @return void 233 */ 234 protected function processEmphasisMatch($matchPos, $matchLen) 235 { 236 $canOpen = !$this->text->isBeforeWhitespace($matchPos + $matchLen - 1); 237 $canClose = !$this->text->isAfterWhitespace($matchPos); 238 $closeLen = ($canClose) ? min($matchLen, 3) : 0; 239 240 $this->closeEm = ($closeLen & 1) && $this->emPos >= 0; 241 $this->closeStrong = ($closeLen & 2) && $this->strongPos >= 0; 242 $this->emEndPos = $matchPos; 243 $this->strongEndPos = $matchPos; 244 $this->remaining = $matchLen; 245 246 $this->adjustStartingPositions(); 247 $this->adjustEndingPositions(); 248 $this->closeSpans(); 249 250 // Adjust the length of unused markup remaining in current match 251 $this->remaining = ($canOpen) ? min($this->remaining, 3) : 0; 252 $this->openSpans($matchPos + $matchLen); 253 } 254 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |