Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Emphasis.php

Zuletzt modifiziert: 02.04.2025, 15:04 - Dateigröße: 5.83 KiB


001  <?php
002   
003  /**
004  * @package   s9e\TextFormatter
005  * @copyright Copyright (c) 2010-2022 The s9e authors
006  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
007  */
008  namespace s9e\TextFormatter\Plugins\Litedown\Parser\Passes;
009   
010  class Emphasis extends AbstractPass
011  {
012      /**
013      * @var bool Whether current EM span is being closed by current emphasis mark
014      */
015      protected $closeEm;
016   
017      /**
018      * @var bool Whether current EM span is being closed by current emphasis mark
019      */
020      protected $closeStrong;
021   
022      /**
023      * @var integer Starting position of the current EM span in the text
024      */
025      protected $emPos;
026   
027      /**
028      * @var integer Ending position of the current EM span in the text
029      */
030      protected $emEndPos;
031   
032      /**
033      * @var integer Number of emphasis characters unused in current span
034      */
035      protected $remaining;
036   
037      /**
038      * @var integer Starting position of the current STRONG span in the text
039      */
040      protected $strongPos;
041   
042      /**
043      * @var integer Ending position of the current STRONG span in the text
044      */
045      protected $strongEndPos;
046   
047      /**
048      * {@inheritdoc}
049      */
050      public function parse()
051      {
052          $this->parseEmphasisByCharacter('*', '/\\*+/');
053          $this->parseEmphasisByCharacter('_', '/_+/');
054      }
055   
056      /**
057      * Adjust the ending position of current EM and STRONG spans
058      *
059      * @return void
060      */
061      protected function adjustEndingPositions()
062      {
063          if ($this->closeEm && $this->closeStrong)
064          {
065              if ($this->emPos < $this->strongPos)
066              {
067                  $this->emEndPos += 2;
068              }
069              else
070              {
071                  ++$this->strongEndPos;
072              }
073          }
074      }
075   
076      /**
077      * Adjust the starting position of current EM and STRONG spans
078      *
079      * If both EM and STRONG are set to start at the same position, we adjust their position
080      * to match the order they are closed. If they start and end at the same position, STRONG
081      * starts before EM to match Markdown's behaviour
082      *
083      * @return void
084      */
085      protected function adjustStartingPositions()
086      {
087          if ($this->emPos >= 0 && $this->emPos === $this->strongPos)
088          {
089              if ($this->closeEm)
090              {
091                  $this->emPos += 2;
092              }
093              else
094              {
095                  ++$this->strongPos;
096              }
097          }
098      }
099   
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  }