/** * Link completion source — extracts markdown headings from all .md files. * * Produces two entries per heading section, plus one for the file itself. * Uses github-slugger to match marked-gfm-heading-id's generated IDs. */ import Slugger from "github-slugger"; import type { CompletionSource, LinkCompletion } from "../types.js"; export const linksSource: CompletionSource = { key: "links", scan(index) { const items: LinkCompletion[] = []; for (const [filePath, content] of Object.entries(index)) { if (!filePath.endsWith(".md")) continue; // Strip .md extension for the router-friendly path const basePath = filePath.replace(/\.md$/, ""); const fileName = fileNameFromPath(basePath); const slugger = new Slugger(); // Add the file itself as a link (whole article) items.push({ path: basePath, label: fileName, section: null, }); // Parse headings for section-scoped links const headingRegex = /^(#{1,6})\s+(.+)$/gm; let match: RegExpExecArray | null; while ((match = headingRegex.exec(content)) !== null) { const title = match[2].trim(); const id = slugger.slug(title.toLowerCase()); items.push({ path: basePath, label: `${fileName} § ${title}`, section: id, }); } } return items; }, }; function fileNameFromPath(path: string): string { const parts = path.split("/").filter(Boolean); return parts[parts.length - 1] || path; }