<?php
/**
* @package s9e\TextFormatter
* @copyright Copyright (c) 2010-2021 The s9e authors
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace s9e\TextFormatter\Plugins\Litedown\Parser\Passes;
class InlineCode extends AbstractPass
{
/**
* {@inheritdoc}
*/
public function parse()
{
$markers = $this->getInlineCodeMarkers();
$i = -1;
$cnt = count($markers);
while (++$i < ($cnt - 1))
{
$pos = $markers[$i]['next'];
$j = $i;
if ($this->text->charAt($markers[$i]['pos']) !== '`')
{
// Adjust the left marker if its first backtick was escaped
++$markers[$i]['pos'];
--$markers[$i]['len'];
}
while (++$j < $cnt && $markers[$j]['pos'] === $pos)
{
if ($markers[$j]['len'] === $markers[$i]['len'])
{
$this->addInlineCodeTags($markers[$i], $markers[$j]);
$i = $j;
break;
}
$pos = $markers[$j]['next'];
}
}
}
/**
* Add the tag pair for an inline code span
*
* @param array $left Left marker
* @param array $right Right marker
* @return void
*/
protected function addInlineCodeTags($left, $right)
{
$startPos = $left['pos'];
$startLen = $left['len'] + $left['trimAfter'];
$endPos = $right['pos'] - $right['trimBefore'];
$endLen = $right['len'] + $right['trimBefore'];
$this->parser->addTagPair('C', $startPos, $startLen, $endPos, $endLen);
$this->text->overwrite($startPos, $endPos + $endLen - $startPos);
}
/**
* Capture and return inline code markers
*
* @return array
*/
protected function getInlineCodeMarkers()
{
$pos = $this->text->indexOf('`');
if ($pos === false)
{
return [];
}
preg_match_all(
'/(`+)(\\s*)[^\\x17`]*/',
str_replace("\x1BD", '\\`', $this->text),
$matches,
PREG_OFFSET_CAPTURE | PREG_SET_ORDER,
$pos
);
$trimNext = 0;
$markers = [];
foreach ($matches as $m)
{
$markers[] = [
'pos' => $m[0][1],
'len' => strlen($m[1][0]),
'trimBefore' => $trimNext,
'trimAfter' => strlen($m[2][0]),
'next' => $m[0][1] + strlen($m[0][0])
];
$trimNext = strlen($m[0][0]) - strlen(rtrim($m[0][0]));
}
return $markers;
}
}