Skip to content

Commit 8186f39

Browse files
committed
feat: support displaying h3 subtitles
1 parent dba433f commit 8186f39

File tree

3 files changed

+49
-10
lines changed

3 files changed

+49
-10
lines changed

src/Web/Documentation/ChapterView.php

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,44 @@ public function isCurrent(Chapter $other): bool
3535

3636
public function getSubChapters(): array
3737
{
38-
preg_match_all('/<h2.*>.*<a.*href="(?<uri>.*?)".*<\/span>(?<title>.*)<\/a><\/h2>/', $this->currentChapter->body, $matches);
38+
// TODO: clean up
39+
preg_match_all('/<h2.*>.*<a.*href="(?<uri>.*?)".*<\/span>(?<title>.*)<\/a><\/h2>/', $this->currentChapter->body, $h2Matches);
40+
preg_match_all('/<h3.*>.*<a.*href="(?<h3uri>.*?)".*<\/span>(?<h3title>.*)<\/a><\/h3>/', $this->currentChapter->body, $h3Matches);
3941

4042
$subChapters = [];
4143

42-
foreach ($matches[0] as $key => $match) {
43-
$subChapters[$matches['uri'][$key]] = $matches['title'][$key];
44+
foreach ($h2Matches[0] as $key => $match) {
45+
$h2Uri = $h2Matches['uri'][$key];
46+
$h2Title = $h2Matches['title'][$key];
47+
$subChapters[$h2Uri] = [
48+
'title' => $h2Title,
49+
'children' => [],
50+
];
51+
}
52+
53+
foreach ($h3Matches[0] as $key => $match) {
54+
$h3Uri = $h3Matches['h3uri'][$key];
55+
$h3Title = $h3Matches['h3title'][$key];
56+
$parentH2Uri = null;
57+
$h3Position = strpos($this->currentChapter->body, $match);
58+
59+
foreach ($h2Matches[0] as $h2Key => $h2Match) {
60+
$h2Position = strpos($this->currentChapter->body, $h2Match);
61+
if ($h2Position < $h3Position) {
62+
$parentH2Uri = $h2Matches['uri'][$h2Key];
63+
} else {
64+
break;
65+
}
66+
}
67+
68+
if ($parentH2Uri !== null && isset($subChapters[$parentH2Uri])) {
69+
$subChapters[$parentH2Uri]['children'][$h3Uri] = $h3Title;
70+
} else {
71+
$subChapters[$h3Uri] = [
72+
'title' => $h3Title,
73+
'children' => [],
74+
];
75+
}
4476
}
4577

4678
return $subChapters;

src/Web/Documentation/show.view.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,18 @@
9696
<div :if="($subChapters = $this->getSubChapters()) !== []" class="text-sm flex flex-col grow">
9797
<span class="inline-block font-bold text-[--primary] mb-3">On this page</span>
9898
<ul class="flex flex-col">
99-
<li :foreach="$subChapters as $url => $title">
100-
<a :href="$url" :data-on-this-page="$title" class="group relative text-sm flex items-center focus-visible:outline-(--ui-primary) py-1 text-(--ui-text-muted) hover:text-(--ui-text) data-[active]:text-(--ui-primary) transition-colors">
101-
{{ \Tempest\Support\Str\strip_tags($title) }}
102-
</a>
103-
</li>
99+
<x-template :foreach="$subChapters as $url => $chapter">
100+
<li>
101+
<a :href="$url" :data-on-this-page="$chapter['title']" class="group relative text-sm flex items-center focus-visible:outline-(--ui-primary) py-1 text-(--ui-text-muted) hover:text-(--ui-text) data-[active]:text-(--ui-primary) transition-colors">
102+
{{ \Tempest\Support\Str\strip_tags($chapter['title']) }}
103+
</a>
104+
</li>
105+
<li :foreach="$chapter['children'] as $url => $title">
106+
<a :href="$url" :data-on-this-page="$title" class="pl-4 group relative text-sm flex items-center focus-visible:outline-(--ui-primary) py-1 text-(--ui-text-dimmed) hover:text-(--ui-text) data-[active]:text-(--ui-primary) transition-colors">
107+
{{ \Tempest\Support\Str\strip_tags($title) }}</span>
108+
</a>
109+
</li>
110+
</x-template>
104111
</ul>
105112
<div class="my-10 mt-auto flex">
106113
<a href="#top" class="border border-(--ui-border) bg-(--ui-bg-elevated) text-(--ui-text-muted) hover:text-(--ui-text) transition rounded-lg p-2">

src/Web/assets/highlight-current-prose-title.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
function findPreviousH2(element: Element | null): HTMLHeadingElement | null {
22
while (element && element.previousElementSibling) {
33
element = element.previousElementSibling
4-
if (element.tagName === 'H2') {
4+
if (element.tagName === 'H2' || element.tagName === 'H3') {
55
return element as HTMLHeadingElement
66
}
77
}
@@ -17,7 +17,7 @@ function updateActiveChapters(): void {
1717
for (const el of elements) {
1818
const rect = el.getBoundingClientRect()
1919
if (rect.top - topMargin >= 0 && rect.bottom <= window.innerHeight) {
20-
if (el.tagName === 'H2' || el.tagName === 'H1') {
20+
if (el.tagName === 'H3' || el.tagName === 'H2' || el.tagName === 'H1') {
2121
if (el.textContent) {
2222
visibleH2s.add(el.textContent.trim())
2323
}

0 commit comments

Comments
 (0)