1<?php
2
3/*
4 * This file is part of the league/commonmark package.
5 *
6 * (c) Colin O'Dell <colinodell@gmail.com>
7 *
8 * Original code based on the CommonMark JS reference parser (https://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
15namespace League\CommonMark\Inline\Parser;
16
17use League\CommonMark\Inline\Element\Code;
18use League\CommonMark\Inline\Element\Text;
19use League\CommonMark\InlineParserContext;
20
21final class BacktickParser implements InlineParserInterface
22{
23    public function getCharacters(): array
24    {
25        return ['`'];
26    }
27
28    public function parse(InlineParserContext $inlineContext): bool
29    {
30        $cursor = $inlineContext->getCursor();
31
32        $ticks = $cursor->match('/^`+/');
33
34        $currentPosition = $cursor->getPosition();
35        $previousState = $cursor->saveState();
36
37        while ($matchingTicks = $cursor->match('/`+/m')) {
38            if ($matchingTicks === $ticks) {
39                $code = $cursor->getSubstring($currentPosition, $cursor->getPosition() - $currentPosition - \strlen($ticks));
40
41                $c = \preg_replace('/\n/m', ' ', $code);
42
43                if (
44                    !empty($c) &&
45                    $c[0] === ' ' &&
46                    \substr($c, -1, 1) === ' ' &&
47                    \preg_match('/[^ ]/', $c)
48                ) {
49                    $c = \substr($c, 1, -1);
50                }
51
52                $inlineContext->getContainer()->appendChild(new Code($c));
53
54                return true;
55            }
56        }
57
58        // If we got here, we didn't match a closing backtick sequence
59        $cursor->restoreState($previousState);
60        $inlineContext->getContainer()->appendChild(new Text($ticks));
61
62        return true;
63    }
64}
65