TableStartParser::parseSeparator()   C
last analyzed

Complexity

Conditions 14
Paths 32

Size

Total Lines 63
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 14.3489

Importance

Changes 0
Metric Value
cc 14
eloc 38
c 0
b 0
f 0
nc 32
nop 1
dl 0
loc 63
ccs 29
cts 33
cp 0.8788
crap 14.3489
rs 6.2666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This is part of the league/commonmark package.
7
 *
8
 * (c) Martin Hasoň <[email protected]>
9
 * (c) Webuni s.r.o. <[email protected]>
10
 * (c) Colin O'Dell <[email protected]>
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 */
15
16
namespace League\CommonMark\Extension\Table;
17
18
use League\CommonMark\Parser\Block\BlockStart;
19
use League\CommonMark\Parser\Block\BlockStartParserInterface;
20
use League\CommonMark\Parser\Block\ParagraphParser;
21
use League\CommonMark\Parser\Cursor;
22
use League\CommonMark\Parser\MarkdownParserStateInterface;
23
24
final class TableStartParser implements BlockStartParserInterface
25
{
26 80
    private int $maxAutocompletedCells;
27
28 80
    public function __construct(int $maxAutocompletedCells = TableParser::DEFAULT_MAX_AUTOCOMPLETED_CELLS)
0 ignored issues
show
Bug introduced by
The type League\CommonMark\Extension\Table\TableParser was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29 80
    {
30 64
        $this->maxAutocompletedCells = $maxAutocompletedCells;
31
    }
32
33 58
    public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
34 58
    {
35 2
        $paragraph = $parserState->getParagraphContent();
36
        if ($paragraph === null || \strpos($paragraph, '|') === false) {
37
            return BlockStart::none();
38 58
        }
39 58
40
        $columns = self::parseSeparator($cursor);
41 58
        if (\count($columns) === 0) {
42 58
            return BlockStart::none();
43 2
        }
44
45
        $lastLineBreak = \strrpos($paragraph, "\n");
46 56
        $lastLine      = $lastLineBreak === false ? $paragraph : \substr($paragraph, $lastLineBreak + 1);
47
48 56
        $headerCells = TableParser::split($lastLine);
49
        if (\count($headerCells) > \count($columns)) {
50 56
            return BlockStart::none();
51 6
        }
52 6
53 6
        $cursor->advanceToEnd();
54
55
        $parsers = [];
56 56
57
        if ($lastLineBreak !== false) {
58 56
            $p = new ParagraphParser();
59 56
            $p->addLine(\substr($paragraph, 0, $lastLineBreak));
60 56
            $parsers[] = $p;
61
        }
62
63
        $parsers[] = new TableParser($columns, $headerCells, $this->maxAutocompletedCells);
64
65
        return BlockStart::of(...$parsers)
66
            ->at($cursor)
67
            ->replaceActiveBlockParser();
68
    }
69
70 58
    /**
71
     * @return array<int, string|null>
72 58
     *
73 58
     * @psalm-return array<int, TableCell::ALIGN_*|null>
74 58
     *
75
     * @phpstan-return array<int, TableCell::ALIGN_*|null>
76 58
     */
77 58
    private static function parseSeparator(Cursor $cursor): array
78 58
    {
79 58
        $columns = [];
80 58
        $pipes   = 0;
81 58
        $valid   = false;
82
83
        while (! $cursor->isAtEnd()) {
84
            switch ($c = $cursor->getCurrentCharacter()) {
85
                case '|':
86
                    $cursor->advanceBy(1);
87 58
                    $pipes++;
88 58
                    if ($pipes > 1) {
89 58
                        // More than one adjacent pipe not allowed
90 52
                        return [];
91 58
                    }
92
93
                    // Need at least one pipe, even for a one-column table
94
                    $valid = true;
95
                    break;
96 58
                case '-':
97 58
                case ':':
98 58
                    if ($pipes === 0 && \count($columns) > 0) {
99 12
                        // Need a pipe after the first column (first column doesn't need to start with one)
100 12
                        return [];
101
                    }
102
103 58
                    $left  = false;
104
                    $right = false;
105
                    if ($c === ':') {
106
                        $left = true;
107
                        $cursor->advanceBy(1);
108 58
                    }
109 8
110 8
                    if ($cursor->match('/^-+/') === null) {
111
                        // Need at least one dash
112
                        return [];
113 58
                    }
114
115 58
                    if ($cursor->getCurrentCharacter() === ':') {
116 58
                        $right = true;
117 50
                        $cursor->advanceBy(1);
118 2
                    }
119
120 50
                    $columns[] = self::getAlignment($left, $right);
121 50
                    // Next, need another pipe
122
                    $pipes = 0;
123
                    break;
124 2
                case ' ':
125
                case "\t":
126
                    // White space is allowed between pipes and columns
127
                    $cursor->advanceToNextNonSpaceOrTab();
128 58
                    break;
129
                default:
130
                    // Any other character is invalid
131
                    return [];
132 58
            }
133
        }
134
135
        if (! $valid) {
136
            return [];
137
        }
138
139
        return $columns;
140
    }
141
142 58
    /**
143
     * @psalm-return TableCell::ALIGN_*|null
144 58
     *
145 8
     * @phpstan-return TableCell::ALIGN_*|null
146
     *
147
     * @psalm-pure
148 58
     */
149 8
    private static function getAlignment(bool $left, bool $right): ?string
150
    {
151
        if ($left && $right) {
152 56
            return TableCell::ALIGN_CENTER;
153 8
        }
154
155
        if ($left) {
156 52
            return TableCell::ALIGN_LEFT;
157
        }
158
159
        if ($right) {
160
            return TableCell::ALIGN_RIGHT;
161
        }
162
163
        return null;
164
    }
165
}
166