/** * `equation` — inline math node (LaTeX source). * * Stores `latex` (the source) + `alt` (fallback text). Rendering (KaTeX) is * the apps/web layer's concern; the package owns the node definition only. * The block-level `equation` block type (PRODUCT-SPEC §4) uses the same * LaTeX string in `content.text` — this inline node is for in-sentence math. */ import { mergeAttributes, Node } from "@tiptap/core"; export interface EquationOptions { readonly HTMLAttributes: Record; } declare module "@tiptap/core" { interface Config { options: EquationOptions; } } export const EquationNode = Node.create({ name: "factoryEquation", group: "inline", inline: true, atom: true, selectable: true, addOptions() { return { HTMLAttributes: { class: "factory-equation", }, }; }, addAttributes() { return { latex: { default: "", parseHTML: (element) => element.getAttribute("data-latex") ?? "", renderHTML: (attributes) => ({ "data-latex": attributes.latex }), }, alt: { default: null, parseHTML: (element) => element.getAttribute("data-alt"), renderHTML: (attributes) => attributes.alt === null ? {} : { "data-alt": attributes.alt }, }, }; }, parseHTML() { return [{ tag: "span.factory-equation" }]; }, renderHTML({ node, HTMLAttributes }) { return [ "span", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), (node.attrs.alt as string | null) ?? (node.attrs.latex as string) ?? "", ]; }, });