Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.00% covered (success)
95.00%
19 / 20
87.50% covered (warning)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
BladeDownProcessor
95.00% covered (success)
95.00%
19 / 20
87.50% covered (warning)
87.50%
7 / 8
10
0.00% covered (danger)
0.00%
0 / 1
 render
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 preprocess
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 process
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 run
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 lineStartsWithDirective
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 processLine
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Hyde\Framework\Services\Markdown;
4
5use Illuminate\Support\Facades\Blade;
6
7/**
8 * Markdown Processor to render Laravel Blade within Markdown files.
9 *
10 * Works on a line-by-line basis by searching for a line starting with the directive.
11 * The preprocessor expands the directive to an HTML comment. The post-processor parses it.
12 *
13 * @example: [Blade]: {{ time() }}
14 * @example: [Blade]: @include('path/to/view.blade.php')
15 *
16 * @see \Tests\Feature\Services\BladeDownProcessorTest
17 */
18class BladeDownProcessor
19{
20    protected string $html;
21    protected string $output;
22
23    protected array $pageData = [];
24
25    public static function render(string $html, ?array $pageData = []): string
26    {
27        return (new static(static::preprocess($html), $pageData))->run()->get();
28    }
29
30    public static function preprocess(string $markdown): string
31    {
32        return implode("\n", array_map(function ($line) {
33            return str_starts_with(strtolower($line), strtolower('[Blade]:'))
34                ? '<!-- HYDE'.trim(htmlentities($line)).' -->'
35                : $line;
36        }, explode("\n", $markdown)));
37    }
38
39    public static function process(string $html, ?array $pageData = []): string
40    {
41        return (new static($html, $pageData))->run()->get();
42    }
43
44    public function __construct(string $html, ?array $pageData = [])
45    {
46        $this->html = $html;
47        $this->pageData = $pageData;
48    }
49
50    public function run(): self
51    {
52        $this->output = implode("\n", array_map(function ($line) {
53            return $this->lineStartsWithDirective($line)
54                ? $this->processLine($line)
55                : $line;
56        }, explode("\n", $this->html)));
57
58        return $this;
59    }
60
61    public function get(): string
62    {
63        return $this->output;
64    }
65
66    protected function lineStartsWithDirective(string $line): bool
67    {
68        return str_starts_with(strtolower($line), '<!-- hyde[blade]:');
69    }
70
71    protected function processLine(string $line): string
72    {
73        return Blade::render(
74            substr(substr(html_entity_decode($line), 18), 0, -4),
75            $this->pageData
76        );
77    }
78}