1
0
cms11/app/Services/Markdown/Formatter.php

116 lines
3.9 KiB
PHP
Raw Normal View History

<?php
namespace App\Services\Markdown;
use App\Classes\Bundle;
use Illuminate\Support\Facades\Blade;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\DisallowedRawHtml\DisallowedRawHtmlExtension;
use League\CommonMark\Extension\ExternalLink\ExternalLinkExtension;
use League\CommonMark\Extension\Footnote\FootnoteExtension;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
use League\CommonMark\Extension\Table\TableExtension;
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
use League\CommonMark\Extension\TaskList\TaskListExtension;
use League\CommonMark\MarkdownConverter;
use Spatie\CommonMarkShikiHighlighter\HighlightCodeExtension;
/**
* Formats markdown content using a variety of CommonMark extensions
* and custom renderers, also incorporating Blade template rendering.
*/
class Formatter
{
/**
* Constructor.
*
* @param string $source The markdown source content.
*/
public function __construct(protected string $source, protected ?Bundle $bundle = null)
{
}
/**
* Renders the markdown content with all enabled extensions and custom processing.
*
* @return string The rendered HTML content.
*/
public function render(): string
{
2024-04-22 21:51:50 +02:00
if (empty($this->source)) {
return $this->source;
}
// First, process the source with Blade to handle any dynamic content
$result = Blade::render($this->source);
// Convert markdown to HTML using the configured environment and extensions
$converter = new MarkdownConverter($this->prepareEnvironment());
$converted = $converter->convert($result);
// Perform final adjustments like inserting non-breaking spaces
$result = $this->insertNonBreakingSpaces($converted->getContent());
return $result;
}
/**
* Prepares the markdown parser environment with extensions and custom renderers.
*
* @return Environment The configured markdown environment.
*/
protected function prepareEnvironment(): Environment
{
// Load markdown configuration and initialize the environment
$environment = new Environment(config('markdown'));
// Define all the extensions to be used
$extensions = [
new CommonMarkCoreExtension(),
2024-04-25 01:37:28 +02:00
new HighlightCodeExtension(theme: 'tokyo-night'),
new FrontMatterExtension(),
new FootnoteExtension(),
new ExternalLinkExtension(),
new HeadingPermalinkExtension(),
new StrikethroughExtension(),
new TableExtension(),
new TableOfContentsExtension(),
new DisallowedRawHtmlExtension(),
new TaskListExtension(),
];
// Add each extension to the environment
foreach ($extensions as $extension) {
$environment->addExtension($extension);
}
return $environment;
}
/**
* Inserts non-breaking spaces before certain punctuation marks in French typography.
*
* @param string $html The HTML content to process.
* @return string The processed HTML content with non-breaking spaces added.
*/
protected function insertNonBreakingSpaces(string $html): string
{
// Define patterns for spaces that should be replaced with non-breaking spaces
$patterns = [
'/ (\;)/',
'/ (\:)/',
'/ (\!)/',
'/ (\?)/',
];
// Corresponding replacements for each pattern
$replacements = array_fill(0, count($patterns), '&nbsp;$1');
// Perform the replacements and return the modified HTML
return preg_replace($patterns, $replacements, $html);
}
}