Completed
Push — refactor-parsing ( adbb6b...fbe6de )
by Colin
08:21 queued 07:01
created

TableStartParser::getAlignment()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.5555
c 0
b 0
f 0
cc 5
nc 4
nop 2
crap 5
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\Cursor;
21
use League\CommonMark\Parser\MarkdownParserStateInterface;
22
23
final class TableStartParser implements BlockStartParserInterface
24
{
25 90
    public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
26
    {
27 90
        $paragraph = $parserState->getParagraphContent();
28 90
        if ($paragraph === null || \strpos($paragraph, '|') === false || \strpos($paragraph, "\n") !== false) {
29 75
            return BlockStart::none();
30
        }
31
32 72
        $columns = self::parseSeparator($cursor);
33 72
        if (empty($columns)) {
34
            return BlockStart::none();
35
        }
36
37 72
        $headerCells = TableParser::split($paragraph);
38 72
        if (\count($headerCells) > \count($columns)) {
39 3
            return BlockStart::none();
40
        }
41
42 69
        $cursor->advanceToEnd();
43
44 69
        return BlockStart::of(new TableParser($columns, $headerCells))
45 69
            ->at($cursor)
46 69
            ->replaceActiveBlockParser();
47
    }
48
49
    /**
50
     * @param Cursor $cursor
51
     *
52
     * @return array<int, string>
0 ignored issues
show
Documentation introduced by
The doc-type array<int, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
53
     */
54 72
    private static function parseSeparator(Cursor $cursor): array
55
    {
56 72
        $columns = [];
57 72
        $pipes = 0;
58 72
        $valid = false;
59
60 72
        while (!$cursor->isAtEnd()) {
61 72
            switch ($c = $cursor->getCharacter()) {
62 72
                case '|':
63 72
                    $cursor->advanceBy(1);
64 72
                    $pipes++;
65 72
                    if ($pipes > 1) {
66
                        // More than one adjacent pipe not allowed
67
                        return [];
68
                    }
69
70
                    // Need at least one pipe, even for a one-column table
71 72
                    $valid = true;
72 72
                    break;
73 72
                case '-':
74 66
                case ':':
75 72
                    if ($pipes === 0 && !empty($columns)) {
76
                        // Need a pipe after the first column (first column doesn't need to start with one)
77
                        return [];
78
                    }
79 72
                    $left = false;
80 72
                    $right = false;
81 72
                    if ($c === ':') {
82 12
                        $left = true;
83 12
                        $cursor->advanceBy(1);
84
                    }
85 72
                    if ($cursor->match('/^-+/') === null) {
86
                        // Need at least one dash
87
                        return [];
88
                    }
89 72
                    if ($cursor->getCharacter() === ':') {
90 9
                        $right = true;
91 9
                        $cursor->advanceBy(1);
92
                    }
93 72
                    $columns[] = self::getAlignment($left, $right);
94
                    // Next, need another pipe
95 72
                    $pipes = 0;
96 72
                    break;
97 63
                case ' ':
98
                case "\t":
99
                    // White space is allowed between pipes and columns
100 63
                    $cursor->advanceToNextNonSpaceOrTab();
101 63
                    break;
102
                default:
103
                    // Any other character is invalid
104
                    return [];
105
            }
106
        }
107
108 72
        if (!$valid) {
109
            return [];
110
        }
111
112 72
        return $columns;
113
    }
114
115 72
    private static function getAlignment(bool $left, bool $right): ?string
116
    {
117 72
        if ($left && $right) {
118 9
            return TableCell::ALIGN_CENTER;
119 72
        } elseif ($left) {
120 6
            return TableCell::ALIGN_LEFT;
121 72
        } elseif ($right) {
122 9
            return TableCell::ALIGN_RIGHT;
123
        }
124
125 66
        return null;
126
    }
127
}
128