Completed
Branch master (446cf6)
by Guillaume
04:16 queued 01:26
created

Jigsaw   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 15
eloc 76
dl 0
loc 153
c 0
b 0
f 0
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A updateTextSize() 0 8 1
A sectionEntries() 0 19 3
A insertDashTableOfContents() 0 8 1
A updateContainer() 0 21 1
A guideEntries() 0 17 2
A removeJavaScript() 0 3 1
A updateTopPadding() 0 5 1
A removeHeader() 0 4 1
A format() 0 14 1
A entries() 0 9 1
A removeFooter() 0 3 1
A updateH4Padding() 0 4 1
1
<?php
2
3
namespace App\Docsets;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Support\Collection;
7
use Wa72\HtmlPageDom\HtmlPageCrawler;
8
use Illuminate\Support\Facades\Storage;
9
10
class Jigsaw extends BaseDocset
11
{
12
    public const CODE = 'jigsaw';
13
    public const NAME = 'Jigsaw';
14
    public const URL = 'jigsaw.tighten.co';
15
    public const INDEX = 'installation.html';
16
    public const PLAYGROUND = '';
17
    public const ICON_16 = '../icon.png';
18
    public const ICON_32 = '../[email protected]';
19
    public const EXTERNAL_DOMAINS = [];
20
21
22
    public function entries(string $file): Collection
23
    {
24
        $crawler = HtmlPageCrawler::create(Storage::get($file));
25
26
        $entries = collect();
27
        $entries = $entries->merge($this->guideEntries($crawler, $file));
28
        $entries = $entries->merge($this->sectionEntries($crawler, $file));
29
30
        return $entries;
31
    }
32
33
    protected function guideEntries(HtmlPageCrawler $crawler, string $file)
34
    {
35
        $entries = collect();
36
37
        $crawler->filter('h2')->each(static function (HtmlPageCrawler $node) use ($entries, $file) {
38
            $fileBasename = basename($file);
39
40
            if ($fileBasename !== 'index.html') {
41
                $entries->push([
42
                    'name' => trim($node->text()),
43
                    'type' => 'Guide',
44
                    'path' => $fileBasename
45
                ]);
46
            }
47
        });
48
49
        return $entries;
50
    }
51
52
    protected function sectionEntries(HtmlPageCrawler $crawler, string $file)
53
    {
54
        $entries = collect();
55
56
        $parent = $crawler->filter('h4')->first()->text() ?: $crawler->filter('h2')->first()->text();
57
58
        $crawler->filter('h3')->each(static function (HtmlPageCrawler $node) use ($entries, $file, $parent) {
59
            $fileBasename = basename($file);
60
61
            if ($fileBasename !== 'index.html') {
62
                $entries->push([
63
                    'name' => trim($node->text() . ' - ' . $parent),
64
                    'type' => 'Section',
65
                    'path' => $fileBasename . '#' . Str::slug($node->text())
66
                ]);
67
            }
68
        });
69
70
        return $entries;
71
    }
72
73
    public function format(string $html): string
74
    {
75
        $crawler = HtmlPageCrawler::create($html);
76
77
        $this->removeHeader($crawler);
78
        $this->removeFooter($crawler);
79
        $this->updateTopPadding($crawler);
80
        $this->updateContainer($crawler);
81
        $this->updateTextSize($crawler);
82
        $this->updateH4Padding($crawler);
83
        $this->removeJavaScript($crawler);
84
        $this->insertDashTableOfContents($crawler);
85
86
        return $crawler->saveHTML();
87
    }
88
89
    protected function removeHeader(HtmlPageCrawler $crawler)
90
    {
91
        $crawler->filter('#vue-app > div:first-child')->remove();
92
        $crawler->filter('#vue-app > header')->remove();
93
    }
94
95
    protected function removeFooter(HtmlPageCrawler $crawler)
96
    {
97
        $crawler->filter('footer')->remove();
98
    }
99
100
    protected function updateTopPadding(HtmlPageCrawler $crawler)
101
    {
102
        $crawler->filter('#vue-app > div > div > div')
103
            ->removeClass('pt-4')
104
            ->css('margin-top', '-1.5rem')
105
        ;
106
    }
107
108
    protected function updateContainer(HtmlPageCrawler $crawler)
109
    {
110
        $crawler->filter('#vue-app > div')
111
            ->removeClass('pt-16')
112
            ->removeClass('md:pt-24')
113
            ->removeClass('lg:pt-32')
114
            ->removeClass('md:px-6')
115
        ;
116
117
        $crawler->filter('#vue-app > div > div')
118
            ->removeClass('max-w-3xl')
119
        ;
120
121
        $crawler->filter('div.markdown')
122
            ->removeClass('lg:max-w-md')
123
            ->removeClass('xl:max-w-lg')
124
            ->removeClass('md:mb-6')
125
            ->removeClass('lg:mb-10')
126
            ->removeClass('xl:px-10')
127
            ->removeClass('sm:shadow')
128
            ->removeClass('md:rounded-lg')
129
        ;
130
    }
131
132
    protected function updateTextSize(HtmlPageCrawler $crawler)
133
    {
134
        $crawler->filter('h2')
135
            ->addClass('text-3xl')
136
        ;
137
138
        $crawler->filter('h3')
139
            ->css('font-size', '1.5rem')
140
        ;
141
    }
142
143
    protected function updateH4Padding(HtmlPageCrawler $crawler)
144
    {
145
        $crawler->filter('h4')
146
            ->css('margin-top', '2.5rem')
147
        ;
148
    }
149
150
    protected function removeJavaScript(HtmlPageCrawler $crawler)
151
    {
152
        $crawler->filter('script')->remove();
153
    }
154
155
    protected function insertDashTableOfContents(HtmlPageCrawler $crawler)
156
    {
157
        $crawler->filter('h2')
158
            ->before('<a name="//apple_ref/cpp/Section/Top" class="dashAnchor"></a>');
159
160
        $crawler->filter('h3')->each(static function (HtmlPageCrawler $node) {
161
            $node->before(
162
                '<a id="' . Str::slug($node->text()) . '" name="//apple_ref/cpp/Section/' . rawurlencode($node->text()) . '" class="dashAnchor"></a>'
163
            );
164
        });
165
    }
166
}
167