[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Plugins/Litedown/Parser/Passes/ -> Emphasis.php (source)

   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  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1