Passed
Push — master ( b5c57d...520bb2 )
by Caen
03:58 queued 13s
created

GeneratesTableOfContents::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Actions;
6
7
use Hyde\Facades\Config;
8
use Hyde\Markdown\Models\Markdown;
9
use League\CommonMark\Environment\Environment;
10
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
11
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
12
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
13
use League\CommonMark\MarkdownConverter;
14
15
use function strpos;
16
use function substr;
17
18
/**
19
 * Generates a table of contents for the Markdown document, most commonly used for the sidebar.
20
 */
21
class GeneratesTableOfContents
22
{
23
    protected string $markdown;
24
25
    public function __construct(Markdown|string $markdown)
26
    {
27
        $this->markdown = (string) $markdown;
28
    }
29
30
    public function execute(): string
31
    {
32
        $config = [
33
            'table_of_contents' => [
34
                'html_class' => 'table-of-contents',
35
                'position' => 'placeholder',
36
                'placeholder' => '[[START_TOC]]',
37
                'style' => 'bullet',
38
                'min_heading_level' => Config::getInt('docs.table_of_contents.min_heading_level', 2),
39
                'max_heading_level' => Config::getInt('docs.table_of_contents.max_heading_level', 4),
40
                'normalize' => 'relative',
41
            ],
42
            'heading_permalink' => [
43
                'fragment_prefix' => '',
44
            ],
45
        ];
46
47
        $environment = new Environment($config);
48
        $environment->addExtension(new CommonMarkCoreExtension());
49
        $environment->addExtension(new HeadingPermalinkExtension());
50
        $environment->addExtension(new TableOfContentsExtension());
51
52
        $converter = new MarkdownConverter($environment);
53
        $html = $converter->convert($this->markdown."\n[[START_TOC]]")->getContent();
54
55
        return $this->extractTableOfContents($html);
56
    }
57
58
    protected function extractTableOfContents(string $html): string
59
    {
60
        // The table of contents is always at the end of the document, so we can just strip everything before it.
61
        $position = strpos($html, '<ul class="table-of-contents">');
62
        if ($position === false) {
63
            // The document has no headings, so we'll just return an empty string.
64
            return '';
65
        }
66
67
        return substr($html, $position);
68
    }
69
}
70