import { renderInline } from "../inline/render.js"; import type { BlockHandler, IdentifyResult } from "./handler.type.js"; import { ITEM_SEPARATOR } from "./identify.js"; const FOOTNOTE_DEF = /^\[\^([\w-]+)\]:\s*(.*)$/; export const footnoteHandler = { identify(lines: string[], index: number): IdentifyResult | null { const firstMatch = lines[index].match(FOOTNOTE_DEF); if (!firstMatch) return null; const items: string[] = []; let i = index; while (i < lines.length) { const match = lines[i].match(FOOTNOTE_DEF); if (!match) break; const id = match[1]; const textParts = [match[2]]; i++; // Gather continuation lines (indented) while (i < lines.length) { const cur = lines[i]; if (cur.startsWith(" ") || cur.startsWith("\t")) { textParts.push(cur.replace(/^[ \t]+/, "")); i++; } else { break; } } items.push(`${id}:${textParts.join("\n")}`); } return { raw: items.join(ITEM_SEPARATOR), nextIndex: i, }; }, render(raw: string): string { const items = raw.split(ITEM_SEPARATOR); const listItems = items.map((item) => { const colonIdx = item.indexOf(":"); const id = item.slice(0, colonIdx); const text = item.slice(colonIdx + 1); return `
  • ${renderInline(text)} \u21A9\uFE0E

  • `; }); return `
      ${listItems.join("")}
    `; }, serialize(raw: string): string { const items = raw.split(ITEM_SEPARATOR); return items .map((item) => { const colonIdx = item.indexOf(":"); const id = item.slice(0, colonIdx); const text = item.slice(colonIdx + 1); return `[^${id}]: ${text}`; }) .join("\n"); }, } satisfies BlockHandler;