Completed
Push — master ( 4aabce...15a80b )
by Colin
04:43 queued 14s
created

src/Block/Parser/ListParser.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Block\Parser;
16
17
use League\CommonMark\Block\Element\ListBlock;
18
use League\CommonMark\Block\Element\ListData;
19
use League\CommonMark\Block\Element\ListItem;
20
use League\CommonMark\ContextInterface;
21
use League\CommonMark\Cursor;
22
use League\CommonMark\Util\RegexHelper;
23
24
class ListParser extends AbstractBlockParser
25
{
26
    /**
27
     * @param ContextInterface $context
28
     * @param Cursor           $cursor
29
     *
30
     * @return bool
31
     */
32 1632
    public function parse(ContextInterface $context, Cursor $cursor)
33
    {
34 1632
        if ($cursor->isIndented() && !($context->getContainer() instanceof ListBlock)) {
35 165
            return false;
36
        }
37
38 1572
        $tmpCursor = clone $cursor;
39 1572
        $indent = $tmpCursor->advanceToFirstNonSpace();
40 1572
        $rest = $tmpCursor->getRemainder();
41
42 1572
        $data = new ListData();
43 1572
        $data->markerOffset = $cursor->getIndent();
44
45 1572
        if ($matches = RegexHelper::matchAll('/^[*+-]/', $rest)) {
46 393
            $data->type = ListBlock::TYPE_UNORDERED;
47 393
            $data->delimiter = null;
48 393
            $data->bulletChar = $matches[0][0];
49 1572
        } elseif ($matches = RegexHelper::matchAll('/^(\d{1,9})([.)])/', $rest)) {
50 81
            $data->type = ListBlock::TYPE_ORDERED;
51 81
            $data->start = intval($matches[1]);
52 81
            $data->delimiter = $matches[2];
53 81
            $data->bulletChar = null;
54 81
        } else {
55 1389
            return false;
56
        }
57
58 456
        $markerLength = strlen($matches[0]);
59
60
        // Make sure we have spaces after
61 456
        $nextChar = $tmpCursor->peek($markerLength);
62 456
        if (!($nextChar === null || $nextChar === "\t" || $nextChar === ' ')) {
63 228
            return false;
64
        }
65
66
        // We've got a match! Advance offset and calculate padding
67 231
        $cursor->advanceToFirstNonSpace(); // to start of marker
68 231
        $cursor->advanceBy($markerLength, true); // to end of marker
69 231
        $data->padding = $this->calculateListMarkerPadding($cursor, $markerLength, $data);
0 ignored issues
show
The call to ListParser::calculateListMarkerPadding() has too many arguments starting with $data.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
70
71
        // add the list if needed
72 231
        $container = $context->getContainer();
73 231
        if (!$container || !($context->getContainer() instanceof ListBlock) || !$data->equals($container->getListData())) {
74 231
            $context->addBlock(new ListBlock($data));
75 231
        }
76
77
        // add the list item
78 231
        $context->addBlock(new ListItem($data));
79
80 231
        return true;
81
    }
82
83
    /**
84
     * @param Cursor $cursor
85
     * @param int    $markerLength
86
     *
87
     * @return int
88
     */
89 231
    private function calculateListMarkerPadding(Cursor $cursor, $markerLength)
90
    {
91 231
        $start = $cursor->saveState();
92 231
        $spacesStartCol = $cursor->getColumn();
93 231
        $spacesStartOffset = $cursor->getPosition();
94
        do {
95 231
            $cursor->advanceBy(1, true);
96 231
            $nextChar = $cursor->getCharacter();
97 231
        } while ($cursor->getColumn() - $spacesStartCol < 5 && ($nextChar === ' ' || $nextChar === "\t"));
98
99 231
        $blankItem = $cursor->peek() === null;
100 231
        $spacesAfterMarker = $cursor->getColumn() - $spacesStartCol;
101
102 231
        if ($spacesAfterMarker >= 5 || $spacesAfterMarker < 1 || $blankItem) {
103 69
            $cursor->restoreState($start);
104 69
            if ($cursor->peek() === ' ') {
105 9
                $cursor->advanceBy(1, true);
106 9
            }
107
108 69
            return $markerLength + 1;
109
        } else {
110 177
            return $markerLength + $spacesAfterMarker;
111
        }
112
    }
113
}
114