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 34
CRAP Score 14.2288

Importance

Changes 0
Metric Value
eloc 38
dl 0
loc 63
ccs 34
cts 38
cp 0.8947
rs 6.2666
c 0
b 0
f 0
cc 14
nc 32
nop 1
crap 14.2288

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