Completed
Push — master ( 7a0a03...73b89e )
by Colin
02:28
created

InlineMentionParser   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 4
dl 0
loc 67
ccs 24
cts 24
cp 1
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getCharacters() 0 4 1
A parse() 0 32 4
A createTwitterHandleParser() 0 4 1
A createGithubHandleParser() 0 5 1
1
<?php
2
3
/*
4
 * This file is part of the league/commonmark package.
5
 *
6
 * (c) Colin O'Dell <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace League\CommonMark\Extension\Autolink;
13
14
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
15
use League\CommonMark\Parser\Inline\InlineParserInterface;
16
use League\CommonMark\Parser\InlineParserContext;
17
18
final class InlineMentionParser implements InlineParserInterface
19
{
20
    /** @var string */
21
    private $linkPattern;
22
23
    /** @var string */
24
    private $handleRegex;
25
26
    /**
27
     * @param string $linkPattern
28
     * @param string $handleRegex
29
     */
30 6
    public function __construct($linkPattern, $handleRegex = '/^[A-Za-z0-9_]+(?!\w)/')
31
    {
32 6
        $this->linkPattern = $linkPattern;
33 6
        $this->handleRegex = $handleRegex;
34 6
    }
35
36 6
    public function getCharacters(): array
37
    {
38 6
        return ['@'];
39
    }
40
41 6
    public function parse(InlineParserContext $inlineContext): bool
42
    {
43 6
        $cursor = $inlineContext->getCursor();
44
45
        // The @ symbol must not have any other characters immediately prior
46 6
        $previousChar = $cursor->peek(-1);
47 6
        if ($previousChar !== null && $previousChar !== ' ') {
48
            // peek() doesn't modify the cursor, so no need to restore state first
49 3
            return false;
50
        }
51
52
        // Save the cursor state in case we need to rewind and bail
53 6
        $previousState = $cursor->saveState();
54
55
        // Advance past the @ symbol to keep parsing simpler
56 6
        $cursor->advance();
57
58
        // Parse the handle
59 6
        $handle = $cursor->match($this->handleRegex);
60 6
        if (empty($handle)) {
61
            // Regex failed to match; this isn't a valid Twitter handle
62 3
            $cursor->restoreState($previousState);
63
64 3
            return false;
65
        }
66
67 6
        $url = \sprintf($this->linkPattern, $handle);
68
69 6
        $inlineContext->getContainer()->appendChild(new Link($url, '@' . $handle));
70
71 6
        return true;
72
    }
73
74 3
    public static function createTwitterHandleParser(): self
75
    {
76 3
        return new self('https://twitter.com/%s', '/^[A-Za-z0-9_]{1,15}(?!\w)/');
77
    }
78
79 3
    public static function createGithubHandleParser(): self
80
    {
81
        // RegEx adapted from https://github.com/shinnn/github-username-regex/blob/master/index.js
82 3
        return new self('https://www.github.com/%s', '/^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}(?!\w)/');
83
    }
84
}
85