/
MarkdownToHtmlViewHelper.php
115 lines (99 loc) 路 3.42 KB
/
MarkdownToHtmlViewHelper.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS extension "solver".
*
* Copyright (C) 2024 Elias H盲u脽ler <elias@haeussler.dev>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace EliasHaeussler\Typo3Solver\ViewHelpers;
use Closure;
use Parsedown;
use TYPO3Fluid\Fluid;
use function preg_replace;
use function preg_replace_callback;
/**
* MarkdownToHtmlViewHelper
*
* @author Elias H盲u脽ler <elias@haeussler.dev>
* @license GPL-2.0-or-later
*/
final class MarkdownToHtmlViewHelper extends Fluid\Core\ViewHelper\AbstractViewHelper
{
use Fluid\Core\ViewHelper\Traits\CompileWithContentArgumentAndRenderStatic;
protected $escapeChildren = false;
protected $escapeOutput = false;
public function initializeArguments(): void
{
$this->registerArgument(
'markdown',
'string',
'The markdown text to convert',
);
$this->registerArgument(
'replaceLineNumbersInCodeSnippets',
'boolean',
'Whether to replace line numbers following the error page markup',
false,
false,
);
}
/**
* @param array{replaceLineNumbersInCodeSnippets?: bool} $arguments
*/
public static function renderStatic(
array $arguments,
Closure $renderChildrenClosure,
Fluid\Core\Rendering\RenderingContextInterface $renderingContext,
): string {
$markdown = $renderChildrenClosure();
$replaceLineNumbers = $arguments['replaceLineNumbersInCodeSnippets'] ?? false;
// Convert markdown to HTML
$parsedown = new Parsedown();
$parsedown->setSafeMode(true);
$html = $parsedown->text($markdown);
// Replace line numbers
if ($replaceLineNumbers) {
$html = self::replaceLineNumbersInCodeSnippets($html);
}
return $html;
}
private static function replaceLineNumbersInCodeSnippets(string $html): string
{
return preg_replace(
'/<\/span>\s*<span/',
'</span><span',
preg_replace_callback(
'/<pre><code>(.*?)<\/code><\/pre>/s',
static fn (array $matches): string => self::replaceLineNumbersInCodeSnippet($matches[1]),
$html,
) ?? $html,
) ?? $html;
}
private static function replaceLineNumbersInCodeSnippet(string $codeSnippet): string
{
$replacements = 0;
$codeSnippetWithLineNumbers = preg_replace(
'/^(\d+)\s(.*)$/m',
'<span data-line="$1">$2</span>',
$codeSnippet,
count: $replacements,
);
if ($replacements === 0) {
return '<pre><code>' . $codeSnippet . '</code></pre>';
}
return '<pre class="has-line-numbers">' . $codeSnippetWithLineNumbers . '</pre>';
}
}