Skip to content

Commit

Permalink
Aside extension for Markdown
Browse files Browse the repository at this point in the history
  • Loading branch information
roberto-butti committed Jan 21, 2024
1 parent bedb2f2 commit 8dacfae
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Commands/BaseBuildCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Ibis\Commands;

use Ibis\Config;
use Ibis\Markdown\Extensions\AsideExtension;
use SplFileInfo;

use Illuminate\Filesystem\Filesystem;
Expand Down Expand Up @@ -71,6 +72,7 @@ protected function buildHtml(string $path, array $config): Collection
$environment->addExtension(new GithubFlavoredMarkdownExtension());
$environment->addExtension(new TableExtension());
$environment->addExtension(new FrontMatterExtension());
$environment->addExtension(new AsideExtension());

$environment->addRenderer(FencedCode::class, new FencedCodeRenderer([
'html', 'php', 'js', 'bash', 'json'
Expand Down
14 changes: 14 additions & 0 deletions src/Markdown/Extensions/Aside.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Ibis\Markdown\Extensions;

use League\CommonMark\Node\Block\AbstractBlock;

class Aside extends AbstractBlock
{
public function __construct()
{
parent::__construct();
}

}
52 changes: 52 additions & 0 deletions src/Markdown/Extensions/AsideBlockParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Ibis\Markdown\Extensions;

use League\CommonMark\Node\Block\AbstractBlock;
use League\CommonMark\Parser\Block\BlockContinue;
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
use League\CommonMark\Parser\Cursor;

class AsideBlockParser implements BlockContinueParserInterface
{
private readonly Aside $aside;

public function __construct()
{
$this->aside = new Aside();
}

public function getBlock(): AbstractBlock
{
return $this->aside;
}

public function isContainer(): bool
{
return true;
}

public function canHaveLazyContinuationLines(): bool
{
return false;
}

public function canContain(AbstractBlock $childBlock): bool
{
return true;
}

public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
{
if ($cursor->getLine() === ":::") {
return BlockContinue::finished();
}

return BlockContinue::at($cursor);
}

public function addLine(string $line): void {}

public function closeBlock(): void {}

}
15 changes: 15 additions & 0 deletions src/Markdown/Extensions/AsideExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Ibis\Markdown\Extensions;

use League\CommonMark\Environment\EnvironmentBuilderInterface;
use League\CommonMark\Extension\ExtensionInterface;

class AsideExtension implements ExtensionInterface
{
public function register(EnvironmentBuilderInterface $environment): void
{
$environment->addBlockStartParser(new AsideParser())
->addRenderer(Aside::class, new AsideRenderer());
}
}
23 changes: 23 additions & 0 deletions src/Markdown/Extensions/AsideParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Ibis\Markdown\Extensions;

use League\CommonMark\Parser\Block\BlockStart;
use League\CommonMark\Parser\Block\BlockStartParserInterface;
use League\CommonMark\Parser\Cursor;
use League\CommonMark\Parser\MarkdownParserStateInterface;

class AsideParser implements BlockStartParserInterface
{
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
{
if (!str_starts_with($cursor->getRemainder(), ':::note')) {
return BlockStart::none();
}

$cursor->advanceToNextNonSpaceOrTab();
$cursor->advanceToEnd();

return BlockStart::of(new AsideBlockParser())->at($cursor);
}
}
25 changes: 25 additions & 0 deletions src/Markdown/Extensions/AsideRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Ibis\Markdown\Extensions;

use League\CommonMark\Node\Node;
use League\CommonMark\Renderer\ChildNodeRendererInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use League\CommonMark\Util\HtmlElement;

class AsideRenderer implements NodeRendererInterface
{
public function render(Node $node, ChildNodeRendererInterface $childRenderer)
{
Aside::assertInstanceOf($node);

$attrs = $node->data->getData('attributes');
$contents = $childRenderer->renderNodes($node->children());

return new HtmlElement(
'blockquote',
['class' => 'notice'],
new HtmlElement('div', $attrs->export(), $contents)
);
}
}

0 comments on commit 8dacfae

Please sign in to comment.