start work on table of contents

This commit is contained in:
Joseph Montanaro 2023-08-20 22:04:21 -07:00
parent b1dc3ae0ea
commit 33d6838dc4
4 changed files with 90 additions and 1 deletions

View File

@ -3,6 +3,7 @@
import { formatDate } from './datefmt.js';
import { makeSlug } from '$lib/utils.js';
import Toc from './Toc.svelte';
import Link from './Link.svelte';
export { Link as a };
</script>
@ -11,6 +12,7 @@
export let title, date;
export const description = '';
export const draft = false;
export let toc = null;
</script>
<style>
@ -29,5 +31,6 @@
<div id="post">
<h1 id="{makeSlug(title)}">{title}</h1>
<p class="subtitle">{formatDate(date)}</p>
<Toc items={toc} />
<slot></slot>
</div>

67
src/lib/Toc.svelte Normal file
View File

@ -0,0 +1,67 @@
<script>
import { makeSlug } from '$lib/utils.js';
export let items;
console.log(items);
</script>
<style>
/* move everything out to the left and center it vertically */
#toc {
position: fixed;
left: 1rem;
/* setting top at 50vh sticks it halfway down the viewport,
then translating back up by 50% gets it vertically centered
even with a dynamic width */
top: 50vh;
transform: translateY(-50%);
color: var(--content-color-faded);
}
/* margin-left is to match the list items; this allows the accent bar
for the current item to appear to float out in space */
h5 {
margin-left: 0.5rem;
padding-bottom: 0.25em;
margin-bottom: 0.25em;
border-bottom: 0.1em solid currentcolor;
font-variant: petite-caps;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
margin-left: var(--indent, 0);
padding-left: 0.5rem;
margin-bottom: 0.15rem;
font-size: 0.9rem;
}
li.current {
border-left: 0.1rem solid var(--accent-color);
}
a {
color: inherit;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
<div id="toc">
<h5>Table of Contents</h5>
<ul>
{#each items as item}
<li style:--indent="{(item.depth - 2) * 0.75}em">
<a href="#{makeSlug(item.text)}">{item.text}</a>
</li>
{/each}
</ul>
</div>

View File

@ -4,7 +4,7 @@ import { toText } from 'hast-util-to-text';
import { makeSlug } from '../lib/utils.js';
export function localPlugins() {
export function localRehype() {
let printed = false;
return (tree, vfile) => {

19
src/plugins/remark.js Normal file
View File

@ -0,0 +1,19 @@
import { visit } from 'unist-util-visit';
import { toString } from 'mdast-util-to-string';
// build table of contents and inject into frontmatter
export function localRemark() {
return (tree, vfile) => {
let toc = [];
visit(tree, 'heading', node => {
toc.push({
text: toString(node),
depth: node.depth,
});
});
vfile.data.fm.toc = toc;
}
}