Skip to content

Commit

Permalink
Render special blockquotes on the backend (#351)
Browse files Browse the repository at this point in the history
* Render blockquotes on the server

* Compile Assets

* Formatting

---------

Co-authored-by: timacdonald <[email protected]>
  • Loading branch information
timacdonald and timacdonald authored Jul 16, 2024
1 parent c548128 commit f3e245e
Show file tree
Hide file tree
Showing 16 changed files with 140 additions and 117 deletions.
93 changes: 93 additions & 0 deletions app/Markdown/BlockQuoteRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace App\Markdown;

use Illuminate\Support\Facades\Vite;
use Illuminate\Support\Str;
use League\CommonMark\Extension\CommonMark\Renderer\Block\BlockQuoteRenderer as BaseBlockQuoteRenderer;
use League\CommonMark\Node\Node;
use League\CommonMark\Renderer\ChildNodeRendererInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use League\CommonMark\Util\HtmlElement;

class BlockQuoteRenderer implements NodeRendererInterface
{
/**
* @return \Stringable|string|null
*/
public function render(Node $node, ChildNodeRendererInterface $childRenderer)
{
$element = (new BaseBlockQuoteRenderer($node))->render($node, $childRenderer);

if (
! $element instanceof HtmlElement ||
$element->getTagName() !== 'blockquote'
) {
return $element;
}

$html = trim($element->getContents(true));

if (! str_starts_with($html, '<p>')) {
return $element;
}

$paragraphPartial = Str::after($html, '<p>');

if (preg_match('/^\[!(NOTE|WARNING)\](?:<br \/>)?/', $paragraphPartial, $matches) === 1) {
// GitHub styled notes, e.g.,
// > [!NOTE] Content
// or
// > [!NOTE]
// > Content

[$asset, $class] = match ($matches[1]) {
'WARNING' => [Vite::content('resources/images/exclamation.svg'), 'bg-red-600'],
'NOTE' => [Vite::content('resources/images/lightbulb.svg'), 'bg-purple-600'],
};
} elseif (preg_match('/^<strong>(Note|Warning):?<\/strong>:?(?:<br \/>)?/', $paragraphPartial, $matches) === 1) {
// Legacy GitHub styled notes, e.g.,
// > **Note:** Content
// or
// > **Note**: Content
// or
// > **Note** Content
// or
// > **Note:**
// > Content
// or
// > **Note**:
// > Content
// or
// > **Note**
// > Content

[$asset, $class] = match ($matches[1]) {
'Warning' => [Vite::content('resources/images/exclamation.svg'), 'bg-red-600'],
'Note' => [Vite::content('resources/images/lightbulb.svg'), 'bg-purple-600'],
};
} elseif (preg_match('/^\{(note|tip|video)\}/', $paragraphPartial, $matches) === 1) {
// Legacy Laravel styled notes, e.g.,
// > {tip} Content

[$asset, $class] = match ($matches[1]) {
'note' => [Vite::content('resources/images/exclamation.svg'), 'bg-red-600'],
'tip' => [Vite::content('resources/images/lightbulb.svg'), 'bg-purple-600'],
'video' => [Vite::content('resources/images/laracast.svg'), 'bg-blue-600'],
};
} else {
return $element;
}

$paragraphPartial = str_replace($matches[0], '', $paragraphPartial);

return <<<HTML
<div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout">
<div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 {$class}">
<div class="opacity-75">{$asset}</div>
</div>
<p class="mb-0 lg:ml-6 callout">{$paragraphPartial}
</div>
HTML;
}
}
18 changes: 17 additions & 1 deletion app/Markdown/GithubFlavoredMarkdownConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@

namespace App\Markdown;

use Illuminate\Support\Str;
use League\CommonMark\Extension\Autolink\AutolinkExtension;
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
use League\CommonMark\Extension\Table\TableExtension;
use League\CommonMark\Extension\TaskList\TaskListExtension;
use League\CommonMark\MarkdownConverter;
use League\CommonMark\Environment\Environment;
use App\Markdown\GithubFlavoredMarkdownExtension;
use Illuminate\Support\Facades\Vite;
use League\CommonMark\Node\Node;
use League\CommonMark\Renderer\ChildNodeRendererInterface;
use League\CommonMark\Util\HtmlElement;
use Torchlight\Commonmark\V2\TorchlightExtension;
use Laravel\Unfenced\UnfencedExtension;
use League\CommonMark\Environment\EnvironmentInterface;
use League\CommonMark\Extension\Attributes\AttributesExtension;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\CommonMark\Node\Block\BlockQuote;
use League\CommonMark\Renderer\NodeRendererInterface;

/**
* Converts GitHub Flavored Markdown to HTML.
Expand All @@ -25,11 +36,16 @@ public function __construct(array $config = [])
{
$environment = new Environment($config);
$environment->addExtension(new CommonMarkCoreExtension());
$environment->addExtension(new GithubFlavoredMarkdownExtension());
$environment->addExtension(new AutolinkExtension());
$environment->addExtension(new StrikethroughExtension());
$environment->addExtension(new TableExtension());
$environment->addExtension(new TaskListExtension());
$environment->addExtension(new UnfencedExtension());
$environment->addExtension(new AttributesExtension());
$environment->addExtension(new TorchlightExtension());

$environment->addRenderer(BlockQuote::class, new BlockQuoteRenderer());

parent::__construct($environment);
}

Expand Down
21 changes: 0 additions & 21 deletions app/Markdown/GithubFlavoredMarkdownExtension.php

This file was deleted.

Loading

0 comments on commit f3e245e

Please sign in to comment.