瀏覽代碼

Squashed commit of the following:

commit 269eb671661c5a4216c677aeb546c9f11dc348db
Merge: c856ff5 4306def
Author: Sangfroid <francois@fdlibre.eu>
Date:   Thu Oct 31 18:47:47 2024 +0100

    Merge branch 'master' into introblock-extension

commit c856ff50f5ed2e7e31cdf0f85172ec47a73152ea
Merge: 9c07e37 a822095
Author: Sangfroid <francois@fdlibre.eu>
Date:   Thu Oct 31 18:13:02 2024 +0100

    Merge branch 'master' into introblock-extension

commit 9c07e379fe2084a0edf6e406373953a541344f94
Author: Sangfroid <francois@fdlibre.eu>
Date:   Thu Oct 31 18:04:27 2024 +0100

    Possibilité de mettre un bloc d'intro

commit 998007ee8dceb5891135753c24d91c5c15183fab
Author: Sangfroid <francois@fdlibre.eu>
Date:   Thu Oct 31 15:23:58 2024 +0100

    Ca marche avec des paragraphes à l\'intérieur du block

commit 67820664cc0c654ea26184b723e42038a53d4bee
Author: Sangfroid <francois@fdlibre.eu>
Date:   Thu Oct 31 14:37:46 2024 +0100

    Extension block pour un div avec une classe, marchotte
Sangfroid 1 月之前
父節點
當前提交
f4600ea0ea

二進制
assets/fonts/alegreya/alegreya-latin-400-italic.woff


二進制
assets/fonts/alegreya/alegreya-latin-400-italic.woff2


二進制
assets/fonts/alegreya/alegreya-latin-400-normal.woff


二進制
assets/fonts/alegreya/alegreya-latin-400-normal.woff2


二進制
assets/fonts/alegreya/alegreya-latin-700-italic.woff


二進制
assets/fonts/alegreya/alegreya-latin-700-italic.woff2


二進制
assets/fonts/alegreya/alegreya-latin-700-normal.woff


二進制
assets/fonts/alegreya/alegreya-latin-700-normal.woff2


+ 13 - 0
assets/styles/app.css

@@ -14,6 +14,14 @@
     }
 } */
 
+@font-face {
+  font-family: 'Alegreya';
+  src: url('../fonts/alegreya/alegreya-latin-700-normal.woff2') format('woff2'),
+       url('../fonts/alegreya/alegreya-latin-700-normal.woff') format('woff');
+  font-weight: 700;
+  font-style: normal;
+}
+
 body {
   margin: 0;
   padding: 0;
@@ -269,6 +277,11 @@ main h1 a:hover {
   font-size: 1.5em;
 }
 
+.intro {
+  font-family: 'Alegreya', serif;
+  font-size: 1.1em;
+}
+
 @media screen and (max-width: 1400px) {
   #header {
     height: 250px;

+ 31 - 0
src/Markdown/Block/IntroBlock.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Markdown\Block;
+
+use League\CommonMark\Node\Block\AbstractBlock;
+use League\CommonMark\Node\StringContainerInterface;
+
+class IntroBlock extends AbstractBlock implements StringContainerInterface
+{
+    protected string $literal;
+
+    public function __construct(protected string $className)
+    {
+        $this->literal = '';
+    }
+
+    public function getClassName(): string
+    {
+        return $this->className;
+    }
+    
+    public function setLiteral(string $literal): void
+    {
+        $this->literal = $literal;
+    }
+
+    public function getLiteral(): string
+    {
+        return $this->literal;
+    }
+}

+ 18 - 0
src/Markdown/Extension/IntroExtension.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Markdown\Extension;
+
+use App\Markdown\Block\IntroBlock;
+use App\Markdown\Parser\IntroParser;
+use App\Markdown\Render\IntroRenderer;
+use League\CommonMark\Environment\EnvironmentBuilderInterface;
+use League\CommonMark\Extension\ExtensionInterface;
+
+class IntroExtension implements ExtensionInterface
+{
+    public function register(EnvironmentBuilderInterface $environment): void
+    {
+        $environment->addBlockStartParser(IntroParser::createBlockStartParser(), 0);
+        $environment->addRenderer(IntroBlock::class, new IntroRenderer(), 0);
+    }
+}

+ 99 - 0
src/Markdown/Parser/IntroParser.php

@@ -0,0 +1,99 @@
+<?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;
+use Twig\Node\TextNode;
+
+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 (trim($cursor->getLine()) === ':::') {
+            return BlockContinue::finished();
+        }
+        // $line = $cursor->getRemainder();
+        // $this->paragraph->appendChild(new Text($line));
+        //$this->introBlock->appendChild(new Text($cursor->getRemainder()));
+
+        $line = $cursor->getRemainder();
+        $paragraph =new Paragraph();
+        $paragraph->appendChild(new Text($line));
+        $this->introBlock->appendChild($paragraph);
+        return BlockContinue::at($cursor);
+    }
+
+    public function parseInlines(InlineParserEngineInterface $inlineParser): void
+    {
+        foreach($this->introBlock->children() as $child) {
+            if ($child instanceof Paragraph) {
+                $textContent = '';
+
+                foreach($child->children() as $textNode) {
+                    if ($textNode instanceof Text) {
+                        $textContent .= $textNode->getLiteral();
+                    }
+                }
+
+                foreach($child->children() as $textNode) {
+                    $textNode->detach();
+                }
+
+                $inlineParser->parse($textContent, $child);
+            }
+        }
+    //     $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();
+            }
+        };
+    }
+}

+ 20 - 0
src/Markdown/Render/IntroRenderer.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Markdown\Render;
+
+use App\Markdown\Block\IntroBlock;
+use League\CommonMark\Node\Node;
+use League\CommonMark\Renderer\ChildNodeRendererInterface;
+use League\CommonMark\Renderer\NodeRendererInterface;
+use League\CommonMark\Util\HtmlElement;
+
+class IntroRenderer implements NodeRendererInterface
+{
+    public function render(Node $node, ChildNodeRendererInterface $childRenderer)
+    {
+        IntroBlock::assertInstanceOf($node);
+        /** @var IntroBlock $node */
+        $attrs = ['class' => $node->getClassName()];
+        return new HtmlElement('div', $attrs, $childRenderer->renderNodes($node->children()));
+    }
+}

+ 2 - 0
src/Service/MarkdownParser.php

@@ -3,6 +3,7 @@
 namespace App\Service;
 
 use App\Markdown\Extension\ColorExtension;
+use App\Markdown\Extension\IntroExtension;
 use Embed\Embed;
 use League\CommonMark\Environment\Environment;
 use League\CommonMark\Extension\Autolink\AutolinkExtension;
@@ -65,6 +66,7 @@ class MarkdownParser
         $environment->addExtension(new TableExtension());
         $environment->addExtension(new EmbedExtension());
         $environment->addExtension(new ColorExtension());
+        $environment->addExtension(new IntroExtension());
 
         $this->converter = new MarkdownConverter($environment);
     }