/** * Math transformer tests. * * `@tiptap/extension-mathematics` only emits empty placeholders in its static * `renderHTML`, so the publisher must render them server-side. These tests * exercise the full publish path (renderArticleHTML) to guarantee the * published article contains rendered KaTeX, never raw LaTeX or empty nodes. */ import { describe, it, expect } from "vitest"; import { renderArticleHTML, type PublishMeta } from "../src/publisher/html-renderer.js"; import type { PublishCSS } from "../src/publisher/index.js"; const EMPTY_CSS: PublishCSS = { variables: "", reset: "", base: "", layout: "", print: "", editorTokens: "", article: "", components: "", publisher: "", }; const META: PublishMeta = { title: "Math Article", description: "A test article with math", authors: [{ name: "Alice", affiliationIndices: [1], affiliationNames: ["MIT"] }], affiliations: [{ name: "MIT" }], date: "2025-01-01", }; const doc = (content: any[]) => ({ type: "doc", content }); describe("math transformer", () => { it("renders an inline math placeholder into static KaTeX", async () => { const json = doc([ { type: "paragraph", content: [ { type: "text", text: "Energy is " }, { type: "inlineMath", attrs: { latex: "E = mc^2" } }, { type: "text", text: " famously." }, ], }, ]); const html = await renderArticleHTML(json, META, EMPTY_CSS); expect(html).toContain('class="katex"'); // KaTeX keeps the source in a MathML annotation, which is expected. expect(html).toContain("E = mc^2"); }); it("renders a block math placeholder in display mode", async () => { const json = doc([{ type: "blockMath", attrs: { latex: "\\int_0^1 x\\,dx = \\frac{1}{2}" } }]); const html = await renderArticleHTML(json, META, EMPTY_CSS); expect(html).toContain('class="katex"'); expect(html).toContain("katex-display"); }); it("does not throw on malformed LaTeX (renders an error node instead)", async () => { const json = doc([ { type: "paragraph", content: [{ type: "inlineMath", attrs: { latex: "\\frac{" } }] }, ]); const html = await renderArticleHTML(json, META, EMPTY_CSS); expect(html).toContain("katex"); }); it("drops empty math placeholders so they leave no invisible gap", async () => { const json = doc([ { type: "paragraph", content: [{ type: "inlineMath", attrs: { latex: "" } }] }, ]); const html = await renderArticleHTML(json, META, EMPTY_CSS); expect(html).not.toContain('data-type="inline-math"'); }); });