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

InlineMentionParser::createGithubHandleParser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 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