SetExtHeadingParser::parse()   B
last analyzed

Complexity

Conditions 6
Paths 7

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 15
cts 15
cp 1
rs 8.8657
c 0
b 0
f 0
cc 6
nc 7
nop 2
crap 6
1
<?php
2
3
/*
4
 * This file is part of the league/commonmark package.
5
 *
6
 * (c) Colin O'Dell <[email protected]>
7
 *
8
 * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
9
 *  - (c) John MacFarlane
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace League\CommonMark\Block\Parser;
16
17
use League\CommonMark\Block\Element\Heading;
18
use League\CommonMark\Block\Element\Paragraph;
19
use League\CommonMark\ContextInterface;
20
use League\CommonMark\Cursor;
21
use League\CommonMark\Reference\ReferenceParser;
22
use League\CommonMark\Util\RegexHelper;
23
24
final class SetExtHeadingParser implements BlockParserInterface
25
{
26
    /**
27
     * @param ContextInterface $context
28
     * @param Cursor           $cursor
29
     *
30
     * @return bool
31
     */
32 1869
    public function parse(ContextInterface $context, Cursor $cursor): bool
33
    {
34 1869
        if ($cursor->isIndented()) {
35 180
            return false;
36
        }
37
38 1812
        if (!($context->getContainer() instanceof Paragraph)) {
39 1812
            return false;
40
        }
41
42 333
        $match = RegexHelper::matchAll('/^(?:=+|-+)[ \t]*$/', $cursor->getLine(), $cursor->getNextNonSpacePosition());
43 333
        if ($match === null) {
44 288
            return false;
45
        }
46
47 60
        $level = $match[0][0] === '=' ? 1 : 2;
48 60
        $strings = $context->getContainer()->getStrings();
49
50 60
        $strings = $this->resolveReferenceLinkDefinitions($strings, $context->getReferenceParser());
51 60
        if (empty($strings)) {
52 3
            return false;
53
        }
54
55 57
        $context->replaceContainerBlock(new Heading($level, $strings));
56
57 57
        return true;
58
    }
59
60
    /**
61
     * Resolve reference link definition
62
     *
63
     * @see https://github.com/commonmark/commonmark.js/commit/993bbe335931af847460effa99b2411eb643577d
64
     *
65
     * @param string[]        $strings
66
     * @param ReferenceParser $referenceParser
67
     *
68
     * @return string[]
69
     */
70 60
    private function resolveReferenceLinkDefinitions(array $strings, ReferenceParser $referenceParser): array
71
    {
72 60
        foreach ($strings as &$string) {
73 60
            $cursor = new Cursor($string);
74 60
            while ($cursor->getCharacter() === '[' && $referenceParser->parse($cursor)) {
75 6
                $string = $cursor->getRemainder();
76
            }
77
78 60
            if ($string !== '') {
79 58
                break;
80
            }
81
        }
82
83
        return \array_filter($strings, function ($s) {
84 60
            return $s !== '';
85 60
        });
86
    }
87
}
88