-
Notifications
You must be signed in to change notification settings - Fork 0
/
RelativeMarkdownLinks.php
73 lines (56 loc) · 2.24 KB
/
RelativeMarkdownLinks.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
namespace App\Listeners;
use DOMDocument;
use Illuminate\Support\Str;
use TightenCo\Jigsaw\Collection\Collection;
use TightenCo\Jigsaw\Collection\CollectionItem;
use TightenCo\Jigsaw\Jigsaw;
class RelativeMarkdownLinks
{
public function handle(Jigsaw $jigsaw): void
{
collect($jigsaw->getPages())
->filter(fn($page) => $page instanceof CollectionItem)
->each(function (CollectionItem $item) use ($jigsaw) {
$itemFolderName = $item->getPath();
$html = $jigsaw->readOutputFile($itemFolderName.'/index.html');
$document = new DOMDocument();
@$document->loadHTML($html);
$container = $document->getElementById('post-content');
if ($container === null) {
return;
}
/** @var \DOMElement[] $links */
$links = $container->getElementsByTagName('a');
foreach ($links as $link) {
$linkDestination = $link->getAttribute('href');
if (! $this->linkIsRelative($linkDestination)) {
continue;
}
$slug = $this->getSlugFromRelativeLink($linkDestination);
$newLink = $this->getPathForItem($slug, [$item->collection, ...$jigsaw->getCollections()]);
$link->setAttribute('href', $newLink);
}
$jigsaw->writeOutputFile($itemFolderName.'/index.html', $document->saveHTML());
});
}
private function getSlugFromRelativeLink(string $relativeLink): string
{
$fileName = basename($relativeLink);
return Str::before($fileName, '.md');
}
private function getPathForItem(string $slug, array $collections): string
{
/** @var Collection<string, CollectionItem> $collection */
foreach ($collections as $collection) {
if ($linkedItem = $collection->get($slug)) {
return $linkedItem->getPath();
}
}
throw new \RuntimeException('Could not get absolute link for "'.$slug.'".');
}
private function linkIsRelative(string $link): bool
{
return str_contains($link, './');
}
}