ReferenceParser   A
last analyzed

Coupling/Cohesion

Components 1
Dependencies 4

Complexity

Total Complexity 12

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Test Coverage

Coverage 97.92%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 4
dl 0
loc 102
ccs 47
cts 48
cp 0.9792
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C parse() 0 82 11
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;
16
17
use League\CommonMark\Reference\Reference;
18
use League\CommonMark\Reference\ReferenceMap;
19
use League\CommonMark\Util\LinkParserHelper;
20
21
class ReferenceParser
22
{
23
    /**
24
     * @var ReferenceMap
25
     */
26
    protected $referenceMap;
27
28 1950
    public function __construct(ReferenceMap $referenceMap)
29
    {
30 1950
        $this->referenceMap = $referenceMap;
31 1950
    }
32
33
    /**
34
     * Attempt to parse a link reference, modifying the refmap.
35
     *
36
     * @param Cursor $cursor
37
     *
38
     * @return bool
39
     */
40 390
    public function parse(Cursor $cursor)
41
    {
42 390
        if ($cursor->isAtEnd()) {
43
            return false;
44
        }
45
46 390
        $initialState = $cursor->saveState();
47
48 390
        $matchChars = LinkParserHelper::parseLinkLabel($cursor);
49 390
        if ($matchChars === 0) {
50 48
            $cursor->restoreState($initialState);
51
52 48
            return false;
53
        }
54
55
        // We need to trim the opening and closing brackets from the previously-matched text
56 366
        $label = substr($cursor->getPreviousText(), 1, -1);
57
58 366
        if (preg_match('/[^\s]/', $label) === 0) {
59 6
            $cursor->restoreState($initialState);
60
61 6
            return false;
62
        }
63
64 360
        if ($cursor->getCharacter() !== ':') {
65 273
            $cursor->restoreState($initialState);
66
67 273
            return false;
68
        }
69
70
        // Advance past the colon
71 231
        $cursor->advance();
72
73
        // Link URL
74 231
        $cursor->advanceToNextNonSpaceOrNewline();
75
76 231
        $destination = LinkParserHelper::parseLinkDestination($cursor);
77 231
        if (empty($destination)) {
78 3
            $cursor->restoreState($initialState);
79
80 3
            return false;
81
        }
82
83 228
        $previousState = $cursor->saveState();
84 228
        $cursor->advanceToNextNonSpaceOrNewline();
85
86 228
        $title = LinkParserHelper::parseLinkTitle($cursor);
87 228
        if ($title === null) {
88 123
            $title = '';
89 123
            $cursor->restoreState($previousState);
90 41
        }
91
92
        // Make sure we're at line end:
93 228
        $atLineEnd = true;
94 228
        if ($cursor->match('/^ *(?:\n|$)/') === null) {
95 9
            if ($title === '') {
96 3
                $atLineEnd = false;
97 1
            } else {
98
                // The potential title we found is not at the line end,
99
                // but it could still be a legal link reference if we
100
                // discard the title
101 6
                $title = '';
102
                // rewind before spaces
103 6
                $cursor->restoreState($previousState);
104
                // and instead check if the link URL is at the line end
105 6
                $atLineEnd = $cursor->match('/^ *(?:\n|$)/') !== null;
106
            }
107 3
        }
108
109 228
        if (!$atLineEnd) {
110 6
            $cursor->restoreState($initialState);
111
112 6
            return false;
113
        }
114
115 222
        if (!$this->referenceMap->contains($label)) {
116 222
            $reference = new Reference($label, $destination, $title);
117 222
            $this->referenceMap->addReference($reference);
118 74
        }
119
120 222
        return true;
121
    }
122
}
123