Completed
Push — latest ( 76d169...995567 )
by Colin
22s queued 10s
created

MentionParser::getMatchDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
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\Mention;
15
16
use League\CommonMark\Extension\Mention\Generator\CallbackGenerator;
17
use League\CommonMark\Extension\Mention\Generator\MentionGeneratorInterface;
18
use League\CommonMark\Extension\Mention\Generator\StringTemplateLinkGenerator;
19
use League\CommonMark\Parser\Inline\InlineParserInterface;
20
use League\CommonMark\Parser\Inline\InlineParserMatch;
21
use League\CommonMark\Parser\InlineParserContext;
22
23
final class MentionParser implements InlineParserInterface
24
{
25
    /**
26
     * @var string
27
     *
28
     * @psalm-readonly
29
     */
30
    private $symbol;
31
32
    /**
33
     * @var string
34
     *
35
     * @psalm-readonly
36
     */
37
    private $mentionRegex;
38
39
    /**
40
     * @var MentionGeneratorInterface
41
     *
42
     * @psalm-readonly
43
     */
44
    private $mentionGenerator;
45
46 30
    public function __construct(string $symbol, string $mentionRegex, MentionGeneratorInterface $mentionGenerator)
47
    {
48 30
        $this->symbol           = $symbol;
49 30
        $this->mentionRegex     = $mentionRegex;
50 30
        $this->mentionGenerator = $mentionGenerator;
51 30
    }
52
53 30
    public function getMatchDefinition(): InlineParserMatch
54
    {
55 30
        return InlineParserMatch::string($this->symbol);
56
    }
57
58 27
    public function parse(string $match, InlineParserContext $inlineContext): bool
59
    {
60 27
        $cursor = $inlineContext->getCursor();
61
62
        // The symbol must not have any other characters immediately prior
63 27
        $previousChar = $cursor->peek(-1);
64 27
        if ($previousChar !== null && $previousChar !== ' ') {
65
            // peek() doesn't modify the cursor, so no need to restore state first
66 3
            return false;
67
        }
68
69
        // Save the cursor state in case we need to rewind and bail
70 24
        $previousState = $cursor->saveState();
71
72
        // Advance past the symbol to keep parsing simpler
73 24
        $cursor->advance();
74
75
        // Parse the identifier
76 24
        $identifier = $cursor->match($this->mentionRegex);
77 24
        if ($identifier === null) {
78
            // Regex failed to match; this isn't a valid mention
79 3
            $cursor->restoreState($previousState);
80
81 3
            return false;
82
        }
83
84 21
        $mention = $this->mentionGenerator->generateMention(new Mention($this->symbol, $identifier));
85
86 21
        if ($mention === null) {
87 3
            $cursor->restoreState($previousState);
88
89 3
            return false;
90
        }
91
92 18
        $inlineContext->getContainer()->appendChild($mention);
93
94 18
        return true;
95
    }
96
97 3
    public static function createWithStringTemplate(string $symbol, string $mentionRegex, string $urlTemplate): MentionParser
98
    {
99 3
        return new self($symbol, $mentionRegex, new StringTemplateLinkGenerator($urlTemplate));
100
    }
101
102 9
    public static function createWithCallback(string $symbol, string $mentionRegex, callable $callback): MentionParser
103
    {
104 9
        return new self($symbol, $mentionRegex, new CallbackGenerator($callback));
105
    }
106
}
107