Completed
Branch wip/litedown (377511)
by Josh
03:42
created

InlineCode::execute()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 0
cts 22
cp 0
rs 8.439
c 0
b 0
f 0
cc 6
eloc 16
nc 7
nop 0
crap 42
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2017 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Plugins\Litedown\Parser;
9
10
class InlineCode extends AbstractParser
11
{
12
	/**
13
	* Add the tag pair for an inline code span
14
	*
15
	* @param  array $left  Left marker
16
	* @param  array $right Right marker
17
	* @return void
18
	*/
19
	protected function addInlineCodeTags($left, $right)
20
	{
21
		$startTagPos = $left['pos'];
22
		$startTagLen = $left['len'] + $left['trimAfter'];
23
		$endTagPos   = $right['pos'] - $right['trimBefore'];
24
		$endTagLen   = $right['len'] + $right['trimBefore'];
25
		$this->parser->addTagPair('C', $startTagPos, $startTagLen, $endTagPos, $endTagLen);
26
		$this->overwrite($startTagPos, $endTagPos + $endTagLen - $startTagPos);
27
	}
28
29
	/**
30
	* Capture and return inline code markers
31
	*
32
	* @return array
33
	*/
34
	protected function getInlineCodeMarkers()
35
	{
36
		$pos = strpos($this->text, '`');
37
		if ($pos === false)
38
		{
39
			return [];
40
		}
41
42
		preg_match_all(
43
			'/(`+)(\\s*)[^\\x17`]*/',
44
			str_replace("\x1BB", '\\`', $this->text),
45
			$matches,
46
			PREG_OFFSET_CAPTURE | PREG_SET_ORDER,
47
			$pos
48
		);
49
		$trimNext = 0;
50
		$markers  = [];
51
		foreach ($matches as $m)
52
		{
53
			$markers[] = [
54
				'pos'        => $m[0][1],
55
				'len'        => strlen($m[1][0]),
56
				'trimBefore' => $trimNext,
57
				'trimAfter'  => strlen($m[2][0]),
58
				'next'       => $m[0][1] + strlen($m[0][0])
59
			];
60
			$trimNext = strlen($m[0][0]) - strlen(rtrim($m[0][0]));
61
		}
62
63
		return $markers;
64
	}
65
66
	/**
67
	* {@inheritdoc}
68
	*/
69
	protected function execute()
70
	{
71
		$markers = $this->getInlineCodeMarkers();
72
		$i       = -1;
73
		$cnt     = count($markers);
74
		while (++$i < ($cnt - 1))
75
		{
76
			$pos = $markers[$i]['next'];
77
			$j   = $i;
78
			if ($this->text[$markers[$i]['pos']] !== '`')
79
			{
80
				// Adjust the left marker if its first backtick was escaped
81
				++$markers[$i]['pos'];
82
				--$markers[$i]['len'];
83
			}
84
			while (++$j < $cnt && $markers[$j]['pos'] === $pos)
85
			{
86
				if ($markers[$j]['len'] === $markers[$i]['len'])
87
				{
88
					$this->addInlineCodeTags($markers[$i], $markers[$j]);
89
					$i = $j;
90
					break;
91
				}
92
				$pos = $markers[$j]['next'];
93
			}
94
		}
95
	}
96
}