diff --git a/src/lib/Post.svelte b/src/lib/Post.svelte index 57166c9..a1e81d7 100644 --- a/src/lib/Post.svelte +++ b/src/lib/Post.svelte @@ -1,5 +1,6 @@ @@ -13,7 +14,7 @@
-

{title}

+

{title}

{formatDate(date)}

diff --git a/src/lib/slug.js b/src/lib/slug.js index 673747f..582eed8 100644 --- a/src/lib/slug.js +++ b/src/lib/slug.js @@ -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, '') -} \ No newline at end of file + .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); + } + }) + } +} diff --git a/svelte.config.js b/svelte.config.js index cbe9bfc..deaeb5f 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -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
element in src/app.html target: '#svelte',