Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
76.00% covered (warning)
76.00%
19 / 25
66.67% covered (warning)
66.67%
6 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
HydeSmartDocs
76.00% covered (warning)
76.00%
19 / 25
66.67% covered (warning)
66.67%
6 / 9
15.34
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 renderHeader
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 renderBody
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 renderFooter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 process
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 tokenize
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 addDynamicHeaderContent
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 addDynamicFooterContent
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
5.02
 renderSourceLink
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Hyde\Framework\Services;
4
5use Hyde\Framework\Concerns\FacadeHelpers\HydeSmartDocsFacade;
6use Hyde\Framework\Models\DocumentationPage;
7use Illuminate\Support\Str;
8
9/**
10 * Class to make Hyde documentation pages smarter,
11 * by dynamically enriching them with semantic HTML.
12 *
13 * @experimental ðŸ§ª Subject to change without notice.
14 */
15class HydeSmartDocs
16{
17    use HydeSmartDocsFacade;
18
19    protected DocumentationPage $page;
20    protected string $html;
21
22    protected string $header;
23    protected string $body;
24    protected string $footer;
25
26    public function __construct(DocumentationPage $page, string $html)
27    {
28        $this->page = $page;
29        $this->html = $html;
30    }
31
32    public function renderHeader(): string
33    {
34        return $this->header;
35    }
36
37    public function renderBody(): string
38    {
39        return $this->body;
40    }
41
42    public function renderFooter(): string
43    {
44        return $this->footer;
45    }
46
47    /** @internal */
48    public function process(): self
49    {
50        $this->tokenize();
51
52        $this->addDynamicHeaderContent();
53        $this->addDynamicFooterContent();
54
55        return $this;
56    }
57
58    protected function tokenize(): self
59    {
60        // The HTML content is expected to be two parts. To create semantic HTML,
61        // we need to split the content into header and body. We do this by
62        // extracting the first <h1> tag and everything before it.
63
64        // Split the HTML content by the first newline
65        $parts = explode("\n", $this->html, 2);
66
67        $this->header = $parts[0];
68        $this->body = $parts[1] ?? '';
69        $this->footer = '';
70
71        return $this;
72    }
73
74    protected function addDynamicHeaderContent(): self
75    {
76        // Hook to add dynamic content to the header.
77        // This is where we can add TOC, breadcrumbs, etc.
78
79        if ($this->canRenderSourceLink('header')) {
80            $this->header .= $this->renderSourceLink();
81        }
82
83        return $this;
84    }
85
86    protected function addDynamicFooterContent(): self
87    {
88        // Hook to add dynamic content to the footer.
89        // This is where we can add copyright, attributions, info, etc.
90
91        if (config('torchlight.attribution.enabled', true) && $this->hasTorchlight()) {
92            $this->footer .= Str::markdown(config(
93                'torchlight.attribution.markdown',
94                'Syntax highlighted by torchlight.dev'
95            ));
96        }
97
98        if ($this->canRenderSourceLink('footer')) {
99            $this->footer .= $this->renderSourceLink();
100        }
101
102        return $this;
103    }
104
105    protected function renderSourceLink(): string
106    {
107        return sprintf('<p class="edit-page-link"><a href="%s">%s</a></p>',
108            $this->page->getOnlineSourcePath(),
109            config('docs.edit_source_link_text', 'Edit page')
110        );
111    }
112}