Completed
Push — latest ( 609def...dcbb7e )
by Colin
14s queued 11s
created

src/Extension/Table/TableStartParser.php (3 issues)

Labels
Severity
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 105
    public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
26
    {
27 105
        $paragraph = $parserState->getParagraphContent();
28 105
        if ($paragraph === null || \strpos($paragraph, '|') === false || \strpos($paragraph, "\n") !== false) {
29 87
            return BlockStart::none();
1 ignored issue
show
Are you sure the usage of League\CommonMark\Parser\Block\BlockStart::none() targeting League\CommonMark\Parser\Block\BlockStart::none() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
30
        }
31
32 75
        $columns = self::parseSeparator($cursor);
33 75
        if (\count($columns) === 0) {
34
            return BlockStart::none();
1 ignored issue
show
Are you sure the usage of League\CommonMark\Parser\Block\BlockStart::none() targeting League\CommonMark\Parser\Block\BlockStart::none() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
35
        }
36
37 75
        $headerCells = TableParser::split($paragraph);
38 75
        if (\count($headerCells) > \count($columns)) {
39 3
            return BlockStart::none();
1 ignored issue
show
Are you sure the usage of League\CommonMark\Parser\Block\BlockStart::none() targeting League\CommonMark\Parser\Block\BlockStart::none() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
40
        }
41
42 72
        $cursor->advanceToEnd();
43
44 72
        return BlockStart::of(new TableParser($columns, $headerCells))
45 72
            ->at($cursor)
46 72
            ->replaceActiveBlockParser();
47
    }
48
49
    /**
50
     * @return array<int, string|null>
51
     *
52
     * @psalm-return list<string|null>
53
     */
54 75
    private static function parseSeparator(Cursor $cursor): array
55
    {
56 75
        $columns = [];
57 75
        $pipes   = 0;
58 75
        $valid   = false;
59
60 75
        while (! $cursor->isAtEnd()) {
61 75
            switch ($c = $cursor->getCharacter()) {
62 75
                case '|':
63 75
                    $cursor->advanceBy(1);
64 75
                    $pipes++;
65 75
                    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 75
                    $valid = true;
72 75
                    break;
73 75
                case '-':
74 66
                case ':':
75 75
                    if ($pipes === 0 && \count($columns) > 0) {
76
                        // Need a pipe after the first column (first column doesn't need to start with one)
77
                        return [];
78
                    }
79
80 75
                    $left  = false;
81 75
                    $right = false;
82 75
                    if ($c === ':') {
83 12
                        $left = true;
84 12
                        $cursor->advanceBy(1);
85
                    }
86
87 75
                    if ($cursor->match('/^-+/') === null) {
88
                        // Need at least one dash
89
                        return [];
90
                    }
91
92 75
                    if ($cursor->getCharacter() === ':') {
93 9
                        $right = true;
94 9
                        $cursor->advanceBy(1);
95
                    }
96
97 75
                    $columns[] = self::getAlignment($left, $right);
98
                    // Next, need another pipe
99 75
                    $pipes = 0;
100 75
                    break;
101 63
                case ' ':
102
                case "\t":
103
                    // White space is allowed between pipes and columns
104 63
                    $cursor->advanceToNextNonSpaceOrTab();
105 63
                    break;
106
                default:
107
                    // Any other character is invalid
108
                    return [];
109
            }
110
        }
111
112 75
        if (! $valid) {
113
            return [];
114
        }
115
116 75
        return $columns;
117
    }
118
119
    /**
120
     * @psalm-pure
121
     */
122 75
    private static function getAlignment(bool $left, bool $right): ?string
123
    {
124 75
        if ($left && $right) {
125 9
            return TableCell::ALIGN_CENTER;
126
        }
127
128 75
        if ($left) {
129 6
            return TableCell::ALIGN_LEFT;
130
        }
131
132 75
        if ($right) {
133 9
            return TableCell::ALIGN_RIGHT;
134
        }
135
136 69
        return null;
137
    }
138
}
139