Passed
Branch refactor-markdown-helper (02b3eb)
by Caen
04:15
created

CodeblockFilepathProcessor::process()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 11
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 18
rs 9.9
1
<?php
2
3
namespace Hyde\Framework\Modules\Markdown;
4
5
/**
6
 * @see \Hyde\Framework\Testing\Feature\Services\Markdown\CodeblockFilepathProcessorTest
7
 */
8
class CodeblockFilepathProcessor
9
{
10
    public static function preprocess(string $markdown): string
11
    {
12
        $lines = explode("\n", $markdown);
13
14
        foreach ($lines as $index => $line) {
15
            if (static::lineMatchesPattern($line) && ! str_contains($line, '{"shortcodes": false}')) {
16
                // Add the meta-block two lines before the pattern, placing it just above the code block.
17
                // This prevents the meta-block from interfering with other processes.
18
                $lines[$index - 2] .= sprintf(
19
                    "\n<!-- HYDE[Filepath]%s -->",
20
                    trim(str_replace(static::$patterns, '', $line))
21
                );
22
23
                // Remove the original comment lines
24
                unset($lines[$index]);
25
                // Only unset the next line if it's empty
26
                if (trim($lines[$index + 1]) === '') {
27
                    unset($lines[$index + 1]);
28
                }
29
            }
30
        }
31
32
        return implode("\n", $lines);
33
    }
34
35
    public static function process(string $html): string
36
    {
37
        $lines = explode("\n", $html);
38
39
        foreach ($lines as $index => $line) {
40
            if (str_starts_with($line, '<!-- HYDE[Filepath]')) {
41
                $path = static::trimHydeDirective($line);
42
                unset($lines[$index]);
43
                $codeBlockLine = $index + 1;
44
                $label = static::resolveTemplate($path);
45
46
                $lines[$codeBlockLine] = str_contains($html, static::$torchlightKey)
47
                ? static::resolveTorchlightCodeLine($label, $lines[$codeBlockLine])
48
                : static::resolveCodeLine($label, $lines[$codeBlockLine]);
49
            }
50
        }
51
52
        return implode("\n", $lines);
53
    }
54
55
    protected static array $patterns = [
56
        '// filepath: ',
57
        '// Filepath: ',
58
        '# filepath: ',
59
        '# Filepath: ',
60
        '// filepath ',
61
        '// Filepath ',
62
        '# filepath ',
63
        '# Filepath ',
64
    ];
65
66
    protected static string $torchlightKey = '<!-- Syntax highlighted by torchlight.dev -->';
67
68
    protected static function lineMatchesPattern(string $line): bool
69
    {
70
        foreach (static::$patterns as $pattern) {
71
            if (str_starts_with($line, $pattern)) {
72
                return true;
73
            }
74
        }
75
76
        return false;
77
    }
78
79
    protected static function trimHydeDirective(string $line): string
80
    {
81
        return trim(str_replace('-->', '', str_replace(
82
            '<!-- HYDE[Filepath]',
83
            '',
84
            $line
85
        )));
86
    }
87
88
    protected static function resolveTemplate(string $path): string
89
    {
90
        return sprintf('<small class="filepath"><span class="sr-only">Filepath: </span>%s</small>', $path);
91
    }
92
93
    protected static function resolveTorchlightCodeLine(string $label, $lines): string|array
94
    {
95
        return str_replace(
96
            static::$torchlightKey,
97
            static::$torchlightKey.$label,
98
            $lines
99
        );
100
    }
101
102
    protected static function resolveCodeLine(string $label, $lines): string|array|null
103
    {
104
        return preg_replace(
105
            '/<pre><code class="language-(.*?)">/',
106
            '<pre><code class="language-$1">'.$label,
107
            $lines
108
        );
109
    }
110
}
111