Completed
Push — latest ( 6c0640...3af091 )
by Colin
16s queued 11s
created

HeadingStartParser   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 57
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
eloc 31
dl 0
loc 57
ccs 31
cts 31
cp 1
rs 10
c 1
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A tryStart() 0 25 5
A getAtxHeader() 0 18 2
A getSetextHeadingLevel() 0 8 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the league/commonmark package.
7
 *
8
 * (c) Colin O'Dell <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace League\CommonMark\Extension\CommonMark\Parser\Block;
15
16
use League\CommonMark\Parser\Block\BlockStart;
17
use League\CommonMark\Parser\Block\BlockStartParserInterface;
18
use League\CommonMark\Parser\Cursor;
19
use League\CommonMark\Parser\MarkdownParserStateInterface;
20
use League\CommonMark\Util\RegexHelper;
21
22
class HeadingStartParser implements BlockStartParserInterface
23
{
24 2289
    public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
25
    {
26 2289
        if ($cursor->isIndented()) {
27 195
            return BlockStart::none();
28
        }
29
30 2190
        $cursor->advanceToNextNonSpaceOrTab();
31
32 2190
        if ($atxHeading = self::getAtxHeader($cursor)) {
33 171
            return BlockStart::of($atxHeading)->at($cursor);
34
        }
35
36 2049
        $setextHeadingLevel = self::getSetextHeadingLevel($cursor);
37 2049
        if ($setextHeadingLevel > 0) {
38 141
            $content = $parserState->getParagraphContent();
39 141
            if ($content !== null) {
40 75
                $cursor->advanceToEnd();
41
42 75
                return BlockStart::of(new HeadingParser($setextHeadingLevel, $content))
43 75
                    ->at($cursor)
44 75
                    ->replaceActiveBlockParser();
45
            }
46
        }
47
48 2004
        return BlockStart::none();
49
    }
50
51 2190
    private static function getAtxHeader(Cursor $cursor): ?HeadingParser
52
    {
53 2190
        $match = RegexHelper::matchFirst('/^#{1,6}(?:[ \t]+|$)/', $cursor->getLine(), $cursor->getNextNonSpacePosition());
54 2190
        if (! $match) {
55 2049
            return null;
56
        }
57
58 171
        $cursor->advanceToNextNonSpaceOrTab();
59 171
        $cursor->advanceBy(\strlen($match[0]));
60
61 171
        $level = \strlen(\trim($match[0]));
62 171
        $str   = $cursor->getRemainder();
63 171
        $str   = \preg_replace('/^[ \t]*#+[ \t]*$/', '', $str);
64
        \assert(\is_string($str));
65 171
        $str = \preg_replace('/[ \t]+#+[ \t]*$/', '', $str);
66
        \assert(\is_string($str));
67
68 171
        return new HeadingParser($level, $str);
69
    }
70
71 2049
    private static function getSetextHeadingLevel(Cursor $cursor): int
72
    {
73 2049
        $match = RegexHelper::matchFirst('/^(?:=+|-+)[ \t]*$/', $cursor->getLine(), $cursor->getNextNonSpacePosition());
74 2049
        if ($match === null) {
75 1962
            return 0;
76
        }
77
78 141
        return $match[0][0] === '=' ? 1 : 2;
79
    }
80
}
81