Files
amosblomqvist 08e64466ad chain line: the logic is the connective — LaTeX ∧ and ⟹ via KaTeX (owner ruling)
'A → B → C' misread as chained implication when A and B are
CO-premises. The honest shape (owner, 2026-09-30): premises join
with the LaTeX LAND (∧), the conclusion separates by the LaTeX
IMPLICATION (⟹) — A ∧ B ⟹ C.

The glyphs are REAL KaTeX renders — components/latex-glyph.tsx wraps
katex.renderToString (cached per command; the app's math engine, the
stylesheet already rides app-wide from app/layout.tsx). No SVGs, no
font-dependent unicode. PROMINENT in the theme foreground (white in
the dark theme) per the owner's same-round ruling — the logic is the
payload, not the old dim gray. A lonely chip carries no glyph (it
reads as a standalone proposition); the plain-text '→' survives only
in the row's aria-label (formatChainLine, the screen-reader form).
2026-09-30 01:35:59 +03:00

54 lines
1.8 KiB
TypeScript

import katex from "katex";
/**
* THE LaTeX glyph seam (owner ruling, 2026-09-30): UI connectors that
* want math symbols render the REAL LaTeX glyphs through KaTeX — the
* app's math engine, already shipped (app/layout.tsx carries the
* katex stylesheet) — never hand-rolled SVGs or font-dependent
* unicode. Born for the chain table's logical connectives: premises
* join with \land (∧), the conclusion separates with \implies (⟹) —
* `A ∧ B ⟹ C`, not the misleading `A → B → C`.
*
* Prominent by the same ruling: the connectives render in the
* theme's FOREGROUND (white in the dark theme) — the chain line's
* logic is the payload, not decoration. Callers pass the class.
*/
/** Cached katex HTML per command — the glyph set is tiny and
* renderToString is pure; one render per command per process. */
const cache = new Map<string, string>();
/** The raw katex HTML for a LaTeX command (pure, sync — SSR-safe). */
export function latexGlyphHtml(cmd: string): string {
let html = cache.get(cmd);
if (html === undefined) {
html = katex.renderToString(cmd, { throwOnError: false, output: "html" });
cache.set(cmd, html);
}
return html;
}
/** One rendered LaTeX glyph. `cmd` is the LaTeX command ("\land",
* "\implies"); the output is aria-hidden — callers carry the textual
* aria-label (formatChainLine keeps the plain-text form). */
export function LatexGlyph({
cmd,
testid,
className,
}: {
cmd: string;
testid?: string;
className?: string;
}) {
return (
<span
data-testid={testid}
aria-hidden="true"
className={className}
// katex.renderToString is the library's own trusted output
// (the same thing rehype-katex injects for markdown math).
dangerouslySetInnerHTML={{ __html: latexGlyphHtml(cmd) }}
/>
);
}