1<?php 2 3declare(strict_types=1); 4 5/* 6 * This file is part of the league/commonmark package. 7 * 8 * (c) Colin O'Dell <colinodell@gmail.com> 9 * 10 * For the full copyright and license information, please view the LICENSE 11 * file that was distributed with this source code. 12 */ 13 14namespace League\CommonMark\Extension\TaskList; 15 16use League\CommonMark\Extension\CommonMark\Node\Block\ListItem; 17use League\CommonMark\Node\Block\Paragraph; 18use League\CommonMark\Parser\Inline\InlineParserInterface; 19use League\CommonMark\Parser\Inline\InlineParserMatch; 20use League\CommonMark\Parser\InlineParserContext; 21 22final class TaskListItemMarkerParser implements InlineParserInterface 23{ 24 public function getMatchDefinition(): InlineParserMatch 25 { 26 return InlineParserMatch::oneOf('[ ]', '[x]'); 27 } 28 29 public function parse(InlineParserContext $inlineContext): bool 30 { 31 $container = $inlineContext->getContainer(); 32 33 // Checkbox must come at the beginning of the first paragraph of the list item 34 if ($container->hasChildren() || ! ($container instanceof Paragraph && $container->parent() && $container->parent() instanceof ListItem)) { 35 return false; 36 } 37 38 $cursor = $inlineContext->getCursor(); 39 $oldState = $cursor->saveState(); 40 41 $cursor->advanceBy(3); 42 43 if ($cursor->getNextNonSpaceCharacter() === null) { 44 $cursor->restoreState($oldState); 45 46 return false; 47 } 48 49 $isChecked = $inlineContext->getFullMatch() !== '[ ]'; 50 51 $container->appendChild(new TaskListItemMarker($isChecked)); 52 53 return true; 54 } 55} 56