toc : add h4 support with nested structure and fix anchors in non-block mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4e5440a7ae
commit
b724ed1244
6 changed files with 40 additions and 14 deletions
|
|
@ -28,10 +28,16 @@
|
||||||
margin-bottom: calc(var(--unit--vertical) / 4);
|
margin-bottom: calc(var(--unit--vertical) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc ul {
|
.toc > ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: calc(var(--unit--vertical) / 4);
|
gap: calc(var(--unit--vertical) / 4);
|
||||||
|
|
||||||
|
> li {
|
||||||
|
> ul {
|
||||||
|
margin-left: var(--unit--horizontal);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc li {
|
.toc li {
|
||||||
|
|
|
||||||
|
|
@ -1283,11 +1283,14 @@ body.full-width #main-content {
|
||||||
margin-bottom: calc(var(--unit--vertical) / 4);
|
margin-bottom: calc(var(--unit--vertical) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc ul {
|
.toc > ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: calc(var(--unit--vertical) / 4);
|
gap: calc(var(--unit--vertical) / 4);
|
||||||
}
|
}
|
||||||
|
.toc > ul > li > ul {
|
||||||
|
margin-left: var(--unit--horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
.toc li {
|
.toc li {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
const H3_PATTERN = '/<h3>(.*?)<\/h3>/';
|
const HEADING_PATTERN = '/<(h[34])(.*?)>(.*?)<\/\1>/';
|
||||||
|
|
||||||
function getContent($page) {
|
function getContent($page) {
|
||||||
if ($page->intendedTemplate() == 'grid') return $page->body()->toBlocks();
|
if ($page->intendedTemplate() == 'grid') return $page->body()->toBlocks();
|
||||||
|
|
@ -29,15 +29,23 @@ Kirby::plugin('actuel-inactuel/toc', [
|
||||||
|
|
||||||
'tocItems' => function(): array {
|
'tocItems' => function(): array {
|
||||||
$content = getTocContent($this);
|
$content = getTocContent($this);
|
||||||
|
|
||||||
if (!$content) return [];
|
if (!$content) return [];
|
||||||
|
|
||||||
preg_match_all(H3_PATTERN, $content, $matches);
|
preg_match_all(HEADING_PATTERN, $content, $matches, PREG_SET_ORDER);
|
||||||
|
|
||||||
return array_map(fn($title) => [
|
$items = [];
|
||||||
'title' => $title,
|
foreach ($matches as $m) {
|
||||||
'slug' => Str::slug($title)
|
$entry = ['title' => $m[3], 'slug' => Str::slug($m[3])];
|
||||||
], $matches[1]);
|
|
||||||
|
if ($m[1] === 'h3') {
|
||||||
|
$entry['children'] = [];
|
||||||
|
$items[] = $entry;
|
||||||
|
} elseif ($m[1] === 'h4' && count($items) > 0) {
|
||||||
|
$items[count($items) - 1]['children'][] = $entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
},
|
},
|
||||||
|
|
||||||
'bodyWithAnchors' => function(): string {
|
'bodyWithAnchors' => function(): string {
|
||||||
|
|
@ -45,8 +53,8 @@ Kirby::plugin('actuel-inactuel/toc', [
|
||||||
if (!$content) return '';
|
if (!$content) return '';
|
||||||
|
|
||||||
return preg_replace_callback(
|
return preg_replace_callback(
|
||||||
H3_PATTERN,
|
HEADING_PATTERN,
|
||||||
fn($m) => '<h3 id="' . Str::slug($m[1]) . '">' . $m[1] . '</h3>',
|
fn($m) => '<' . $m[1] . ' id="' . Str::slug($m[3]) . '"' . $m[2] . '>' . $m[3] . '</' . $m[1] . '>',
|
||||||
$content
|
$content
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,16 @@
|
||||||
<div class="light toc_label">table des matières</div>
|
<div class="light toc_label">table des matières</div>
|
||||||
<ul>
|
<ul>
|
||||||
<?php foreach ($page->tocItems() as $item): ?>
|
<?php foreach ($page->tocItems() as $item): ?>
|
||||||
<li><a href="#<?= $item['slug'] ?>"><?= $item['title'] ?></a></li>
|
<li>
|
||||||
|
<a href="#<?= $item['slug'] ?>"><?= $item['title'] ?></a>
|
||||||
|
<?php if (!empty($item['children'])): ?>
|
||||||
|
<ul>
|
||||||
|
<?php foreach ($item['children'] as $child): ?>
|
||||||
|
<li><a href="#<?= $child['slug'] ?>"><?= $child['title'] ?></a></li>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</ul>
|
||||||
|
<?php endif ?>
|
||||||
|
</li>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
<?php elseif ($page->isBlockMode()->isTrue()): ?>
|
<?php elseif ($page->isBlockMode()->isTrue()): ?>
|
||||||
<?= $page->bodyWithAnchors() ?>
|
<?= $page->bodyWithAnchors() ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?= $page->body() ?>
|
<?= $page->bodyWithAnchors() ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue