add heading slugs
This commit is contained in:
parent
cb04687d0b
commit
14d74ccdee
@ -1,5 +1,6 @@
|
||||
<script context="module">
|
||||
import { formatDate } from './datefmt.js';
|
||||
import { makeSlug } from '$lib/slug.js';
|
||||
import Link from './Link.svelte';
|
||||
export { Link as a };
|
||||
</script>
|
||||
@ -13,7 +14,7 @@
|
||||
</svelte:head>
|
||||
|
||||
<div id="post">
|
||||
<h1>{title}</h1>
|
||||
<h1 id="{makeSlug(title)}">{title}</h1>
|
||||
<p><em>{formatDate(date)}</em></p>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
@ -1,10 +1,50 @@
|
||||
// this approach won't work if an attribute value contains ">"
|
||||
const tag = /<[^>]*?>/g
|
||||
const nonAlphaNum = /[^A-Za-z0-9\-]/g
|
||||
const nonAlphaNum = /[^A-Za-z0-9\-]/g;
|
||||
const space = /\s/g
|
||||
|
||||
export default function slugify(text) {
|
||||
return text.replace(tag, '')
|
||||
export function makeSlug(text) {
|
||||
return text
|
||||
.toLowerCase()
|
||||
.replace(space, '-')
|
||||
.replace(nonAlphNum, '')
|
||||
}
|
||||
.replace(nonAlphaNum, '')
|
||||
}
|
||||
|
||||
function apply(node, types, fn) {
|
||||
if (typeof types === 'string') {
|
||||
types = new Set([types]);
|
||||
}
|
||||
else if (!(types instanceof Set)) {
|
||||
types = new Set(types)
|
||||
console.log(types)
|
||||
}
|
||||
|
||||
if (types.has(node.type)) {
|
||||
fn(node);
|
||||
}
|
||||
if ('children' in node) {
|
||||
for (let child of node.children) {
|
||||
apply(child, types, fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTextContent(node) {
|
||||
let segments = [];
|
||||
apply(node, 'text', textNode => {
|
||||
// skip all-whitespace strings
|
||||
if (textNode.value.match(/^\s+$/)) return;
|
||||
segments.push(textNode.value.trim());
|
||||
});
|
||||
|
||||
return segments.join(' ');
|
||||
}
|
||||
|
||||
export default function slug() {
|
||||
return (tree) => {
|
||||
apply(tree, 'element', e => {
|
||||
if (e.tagName.match(/h[1-6]/)) {
|
||||
let text = getTextContent(e);
|
||||
e.properties.id = makeSlug(text);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
import { mdsvex } from 'mdsvex';
|
||||
import staticAdapter from '@sveltejs/adapter-static';
|
||||
import slug from './src/lib/slug.js';
|
||||
|
||||
|
||||
const config = {
|
||||
extensions: ['.svelte', '.svx'],
|
||||
preprocess: mdsvex({layout: './src/lib/Post.svelte'}),
|
||||
preprocess: mdsvex({
|
||||
layout: './src/lib/Post.svelte',
|
||||
rehypePlugins: [slug],
|
||||
}),
|
||||
kit: {
|
||||
// hydrate the <div id="svelte"> element in src/app.html
|
||||
target: '#svelte',
|
||||
|
Loading…
x
Reference in New Issue
Block a user