|
@@ -0,0 +1,76 @@
|
|
|
|
+<?php
|
|
|
|
+
|
|
|
|
+namespace App\Markdown\Parser;
|
|
|
|
+
|
|
|
|
+use App\Markdown\Block\IntroBlock;
|
|
|
|
+use League\CommonMark\Node\Block\AbstractBlock;
|
|
|
|
+use League\CommonMark\Node\Block\Paragraph;
|
|
|
|
+use League\CommonMark\Node\Inline\Text;
|
|
|
|
+use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
|
|
|
+use League\CommonMark\Parser\Cursor;
|
|
|
|
+use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
|
|
|
+use League\CommonMark\Parser\Block\BlockContinue;
|
|
|
|
+use League\CommonMark\Parser\Block\BlockContinueParserWithInlinesInterface;
|
|
|
|
+use League\CommonMark\Parser\Block\BlockStart;
|
|
|
|
+use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
|
|
|
+use League\CommonMark\Parser\InlineParserEngineInterface;
|
|
|
|
+use League\CommonMark\Parser\MarkdownParserStateInterface;
|
|
|
|
+
|
|
|
|
+class IntroParser extends AbstractBlockContinueParser implements BlockContinueParserWithInlinesInterface
|
|
|
|
+{
|
|
|
|
+ protected IntroBlock $introBlock;
|
|
|
|
+ protected Paragraph $paragraph;
|
|
|
|
+
|
|
|
|
+ public function __construct(string $className ='')
|
|
|
|
+ {
|
|
|
|
+ $this->introBlock = new IntroBlock($className);
|
|
|
|
+ $this->paragraph = new Paragraph();
|
|
|
|
+ $this->introBlock->appendChild($this->paragraph);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function getBlock(): AbstractBlock
|
|
|
|
+ {
|
|
|
|
+ return $this->introBlock;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
|
|
|
+ {
|
|
|
|
+ if ($cursor->getLine() === ':::') {
|
|
|
|
+ return BlockContinue::finished();
|
|
|
|
+ }
|
|
|
|
+ $line = $cursor->getRemainder();
|
|
|
|
+ $this->paragraph->appendChild(new Text($line));
|
|
|
|
+
|
|
|
|
+ return BlockContinue::at($cursor);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function parseInlines(InlineParserEngineInterface $inlineParser): void
|
|
|
|
+ {
|
|
|
|
+ $textContent = '';
|
|
|
|
+ foreach($this->paragraph->children() as $child) {
|
|
|
|
+ if ($child instanceof Text) {
|
|
|
|
+ $textContent .= $child->getLiteral();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ foreach($this->paragraph->children() as $child) {
|
|
|
|
+ $child->detach();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $inlineParser->parse($textContent, $this->paragraph);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static function createBlockStartParser(): BlockStartParserInterface
|
|
|
|
+ {
|
|
|
|
+ return new class implements BlockStartParserInterface
|
|
|
|
+ {
|
|
|
|
+ public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
|
|
|
+ {
|
|
|
|
+ if ($match = $cursor->match('/^:::\s+([^\s]+)/')) {
|
|
|
|
+ $className = explode(' ', $match)[1] ?? '';
|
|
|
|
+ return BlockStart::of(new IntroParser($className))->at($cursor);
|
|
|
|
+ }
|
|
|
|
+ return BlockStart::none();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+}
|