Completed
Push — master ( 83739a...a13ee4 )
by Colin
14s queued 11s
created

QuoteParser::determineFlanking()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 14
cts 14
cp 1
rs 8.8333
c 0
b 0
f 0
cc 7
nc 16
nop 2
crap 7
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 (http://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\Extension\SmartPunct;
16
17
use League\CommonMark\Delimiter\Delimiter;
18
use League\CommonMark\Inline\Parser\InlineParserInterface;
19
use League\CommonMark\InlineParserContext;
20
use League\CommonMark\Util\RegexHelper;
21
22
final class QuoteParser implements InlineParserInterface
23
{
24
    public const DOUBLE_QUOTES = [Quote::DOUBLE_QUOTE, Quote::DOUBLE_QUOTE_OPENER, Quote::DOUBLE_QUOTE_CLOSER];
25
    public const SINGLE_QUOTES = [Quote::SINGLE_QUOTE, Quote::SINGLE_QUOTE_OPENER, Quote::SINGLE_QUOTE_CLOSER];
26
27
    /**
28
     * @return string[]
29
     */
30 51
    public function getCharacters(): array
31
    {
32 51
        return array_merge(self::DOUBLE_QUOTES, self::SINGLE_QUOTES);
33
    }
34
35
    /**
36
     * Normalizes any quote characters found and manually adds them to the delimiter stack
37
     *
38
     * @param InlineParserContext $inlineContext
39
     *
40
     * @return bool
41
     */
42 33
    public function parse(InlineParserContext $inlineContext): bool
43
    {
44 33
        $cursor = $inlineContext->getCursor();
45 33
        $normalizedCharacter = $this->getNormalizedQuoteCharacter($cursor->getCharacter());
46
47 33
        $charBefore = $cursor->peek(-1);
48 33
        if ($charBefore === null) {
49 27
            $charBefore = "\n";
50
        }
51
52 33
        $cursor->advance();
53
54 33
        $charAfter = $cursor->getCharacter();
55 33
        if ($charAfter === null) {
56 21
            $charAfter = "\n";
57
        }
58
59 33
        [$leftFlanking, $rightFlanking] = $this->determineFlanking($charBefore, $charAfter);
0 ignored issues
show
Bug introduced by
The variable $leftFlanking does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $rightFlanking does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
60 33
        $canOpen = $leftFlanking && !$rightFlanking;
61 33
        $canClose = $rightFlanking;
62
63 33
        $node = new Quote($normalizedCharacter, ['delim' => true]);
64 33
        $inlineContext->getContainer()->appendChild($node);
65
66
        // Add entry to stack to this opener
67 33
        $inlineContext->getDelimiterStack()->push(new Delimiter($normalizedCharacter, 1, $node, $canOpen, $canClose));
68
69 33
        return true;
70
    }
71
72
    /**
73
     * @param string $character
74
     *
75
     * @return string|null
76
     */
77 33
    private function getNormalizedQuoteCharacter($character)
78
    {
79 33
        if (in_array($character, self::DOUBLE_QUOTES)) {
80 18
            return Quote::DOUBLE_QUOTE;
81 30
        } elseif (in_array($character, self::SINGLE_QUOTES)) {
82 30
            return Quote::SINGLE_QUOTE;
83
        }
84
85
        return $character;
86
    }
87
88
    /**
89
     * @param string $charBefore
90
     * @param string $charAfter
91
     *
92
     * @return bool[]
93
     */
94 33
    private function determineFlanking($charBefore, $charAfter)
95
    {
96 33
        $afterIsWhitespace = preg_match('/\pZ|\s/u', $charAfter);
97 33
        $afterIsPunctuation = preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter);
98 33
        $beforeIsWhitespace = preg_match('/\pZ|\s/u', $charBefore);
99 33
        $beforeIsPunctuation = preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore);
100
101 33
        $leftFlanking = !$afterIsWhitespace &&
102 33
            !($afterIsPunctuation &&
103 33
                !$beforeIsWhitespace &&
104 33
                !$beforeIsPunctuation);
105
106 33
        $rightFlanking = !$beforeIsWhitespace &&
107 33
            !($beforeIsPunctuation &&
108 33
                !$afterIsWhitespace &&
109 33
                !$afterIsPunctuation);
110
111 33
        return [$leftFlanking, $rightFlanking];
112
    }
113
}
114