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);
|
||||
}
|
||||
|
||||
.toc ul {
|
||||
.toc > ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: calc(var(--unit--vertical) / 4);
|
||||
|
||||
> li {
|
||||
> ul {
|
||||
margin-left: var(--unit--horizontal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toc li {
|
||||
|
|
|
|||
|
|
@ -1283,11 +1283,14 @@ body.full-width #main-content {
|
|||
margin-bottom: calc(var(--unit--vertical) / 4);
|
||||
}
|
||||
|
||||
.toc ul {
|
||||
.toc > ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: calc(var(--unit--vertical) / 4);
|
||||
}
|
||||
.toc > ul > li > ul {
|
||||
margin-left: var(--unit--horizontal);
|
||||
}
|
||||
|
||||
.toc li {
|
||||
margin-left: 0;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
const H3_PATTERN = '/<h3>(.*?)<\/h3>/';
|
||||
const HEADING_PATTERN = '/<(h[34])(.*?)>(.*?)<\/\1>/';
|
||||
|
||||
function getContent($page) {
|
||||
if ($page->intendedTemplate() == 'grid') return $page->body()->toBlocks();
|
||||
|
|
@ -29,15 +29,23 @@ Kirby::plugin('actuel-inactuel/toc', [
|
|||
|
||||
'tocItems' => function(): array {
|
||||
$content = getTocContent($this);
|
||||
|
||||
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) => [
|
||||
'title' => $title,
|
||||
'slug' => Str::slug($title)
|
||||
], $matches[1]);
|
||||
$items = [];
|
||||
foreach ($matches as $m) {
|
||||
$entry = ['title' => $m[3], 'slug' => Str::slug($m[3])];
|
||||
|
||||
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 {
|
||||
|
|
@ -45,8 +53,8 @@ Kirby::plugin('actuel-inactuel/toc', [
|
|||
if (!$content) return '';
|
||||
|
||||
return preg_replace_callback(
|
||||
H3_PATTERN,
|
||||
fn($m) => '<h3 id="' . Str::slug($m[1]) . '">' . $m[1] . '</h3>',
|
||||
HEADING_PATTERN,
|
||||
fn($m) => '<' . $m[1] . ' id="' . Str::slug($m[3]) . '"' . $m[2] . '>' . $m[3] . '</' . $m[1] . '>',
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,16 @@
|
|||
<div class="light toc_label">table des matières</div>
|
||||
<ul>
|
||||
<?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 ?>
|
||||
</ul>
|
||||
</nav>
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
<?php elseif ($page->isBlockMode()->isTrue()): ?>
|
||||
<?= $page->bodyWithAnchors() ?>
|
||||
<?php else: ?>
|
||||
<?= $page->body() ?>
|
||||
<?= $page->bodyWithAnchors() ?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</article>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue