|
4 | 4 |
|
5 | 5 | use App\Extensions\TorchlightWithCopyExtension; |
6 | 6 | use League\CommonMark\CommonMarkConverter; |
| 7 | +use League\CommonMark\Environment\Environment; |
| 8 | +use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; |
7 | 9 | use League\CommonMark\Extension\CommonMark\Node\Block\Heading; |
| 10 | +use League\CommonMark\Extension\Embed\Bridge\OscaroteroEmbedAdapter; |
| 11 | +use League\CommonMark\Extension\Embed\Embed as EmbedNode; |
| 12 | +use League\CommonMark\Extension\Embed\EmbedExtension; |
| 13 | +use League\CommonMark\Extension\Embed\EmbedRenderer; |
| 14 | +use League\CommonMark\Extension\GithubFlavoredMarkdownExtension; |
8 | 15 | use League\CommonMark\Extension\Table\TableExtension; |
| 16 | +use League\CommonMark\MarkdownConverter; |
| 17 | +use League\CommonMark\Renderer\HtmlDecorator; |
| 18 | +use Torchlight\Commonmark\V2\TorchlightExtension; |
9 | 19 |
|
10 | 20 | class CommonMark |
11 | 21 | { |
| 22 | + protected static ?MarkdownConverter $converter = null; |
| 23 | + |
12 | 24 | public static function convertToHtml(string $markdown): string |
13 | 25 | { |
14 | | - $converter = new CommonMarkConverter; |
15 | | - $converter->getEnvironment()->addRenderer(Heading::class, new HeadingRenderer); |
16 | | - $converter->getEnvironment()->addExtension(new TableExtension); |
17 | | - $converter->getEnvironment()->addExtension(new TorchlightWithCopyExtension); |
| 26 | + return static::getConverter()->convert($markdown)->getContent(); |
| 27 | + } |
| 28 | + |
| 29 | + protected static function getConverter(): MarkdownConverter |
| 30 | + { |
| 31 | + if (static::$converter === null) { |
| 32 | + $config = [ |
| 33 | + 'html_input' => 'allow', |
| 34 | + 'allow_unsafe_links' => false, |
| 35 | + 'max_nesting_level' => 10, |
| 36 | + 'embed' => [ |
| 37 | + 'adapter' => new OscaroteroEmbedAdapter, |
| 38 | + 'fallback' => 'link', |
| 39 | + ], |
| 40 | + ]; |
| 41 | + |
| 42 | + $environment = new Environment($config); |
| 43 | + |
| 44 | + $environment->addExtension(new CommonMarkCoreExtension); |
| 45 | + $environment->addExtension(new GithubFlavoredMarkdownExtension); |
| 46 | + $environment->addRenderer(Heading::class, new HeadingRenderer); |
| 47 | + $environment->addExtension(new TableExtension); |
| 48 | + $environment->addExtension(new EmbedExtension); |
| 49 | + |
| 50 | + $environment->addRenderer( |
| 51 | + EmbedNode::class, |
| 52 | + new HtmlDecorator(new EmbedRenderer, 'div', ['class' => 'relative aspect-video w-full']) |
| 53 | + ); |
| 54 | + |
| 55 | + // Add Torchlight extension if available |
| 56 | + if (class_exists(TorchlightExtension::class)) { |
| 57 | + $environment->addExtension(new TorchlightWithCopyExtension); |
| 58 | + } |
| 59 | + |
| 60 | + static::$converter = new MarkdownConverter($environment); |
| 61 | + } |
18 | 62 |
|
19 | | - return $converter->convert($markdown); |
| 63 | + return static::$converter; |
20 | 64 | } |
21 | 65 | } |
0 commit comments