Completed
Push — master ( 66ba8a...c35dd4 )
by Colin
02:41
created

InlineMentionParser::createTwitterHandleParser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
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-ext-autolink 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\Ext\Autolink;
13
14
use League\CommonMark\Inline\Element\Link;
15
use League\CommonMark\Inline\Parser\InlineParserInterface;
16
use League\CommonMark\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
    /**
37
     * {@inheritdoc}
38
     */
39 6
    public function getCharacters(): array
40
    {
41 6
        return ['@'];
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 6
    public function parse(InlineParserContext $inlineContext): bool
48
    {
49 6
        $cursor = $inlineContext->getCursor();
50
51
        // The @ symbol must not have any other characters immediately prior
52 6
        $previousChar = $cursor->peek(-1);
53 6
        if ($previousChar !== null && $previousChar !== ' ') {
54
            // peek() doesn't modify the cursor, so no need to restore state first
55 3
            return false;
56
        }
57
58
        // Save the cursor state in case we need to rewind and bail
59 6
        $previousState = $cursor->saveState();
60
61
        // Advance past the @ symbol to keep parsing simpler
62 6
        $cursor->advance();
63
64
        // Parse the handle
65 6
        $handle = $cursor->match($this->handleRegex);
66 6
        if (empty($handle)) {
67
            // Regex failed to match; this isn't a valid Twitter handle
68 3
            $cursor->restoreState($previousState);
69
70 3
            return false;
71
        }
72
73 6
        $url = \sprintf($this->linkPattern, $handle);
74
75 6
        $inlineContext->getContainer()->appendChild(new Link($url, '@' . $handle));
76
77 6
        return true;
78
    }
79
80 3
    public static function createTwitterHandleParser()
81
    {
82 3
        return new self('https://twitter.com/%s', '/^[A-Za-z0-9_]{1,15}(?!\w)/');
83
    }
84
85 3
    public static function createGithubHandleParser()
86
    {
87
        // RegEx adapted from https://github.com/shinnn/github-username-regex/blob/master/index.js
88 3
        return new self('https://www.github.com/%s', '/^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}(?!\w)/');
89
    }
90
}
91