Files
2026-08-03 19:18:22 -07:00

44 lines
1.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** One entry in a proposal's table of contents. */
export interface Heading {
id: string;
title: string;
depth: number;
}
/** The slug a heading gets in the rendered document, and in its `#` link. */
export function headingId(text: string): string {
return text
.toLowerCase()
.replace(/[^a-z0-9\s-]/g, '')
.trim()
.replace(/\s+/g, '-')
.replace(/-+/g, '-');
}
/**
* Pull h2–h4 out of markdown source.
*
* Fenced blocks are skipped: proposals are full of shell transcripts and ASCII
* diagrams whose `#` comment lines are not headings.
*/
export function extractHeadings(markdown: string): Heading[] {
const headings: Heading[] = [];
let inFence = false;
for (const line of markdown.split('\n')) {
if (/^\s*(```|~~~)/.test(line)) {
inFence = !inFence;
continue;
}
if (inFence) continue;
const match = line.match(/^(#{2,4})\s+(.+?)\s*#*\s*$/);
if (!match) continue;
const title = match[2].trim();
headings.push({ id: headingId(title), title, depth: match[1].length });
}
return headings;
}