MODU is a normalization and typesetting engine for LLM output — the tangle of Markdown, LaTeX, tables and code that every other renderer assumes away. It arbitrates the boundary first, then typesets.
The laptop sold for $999. The span `price = $x * 2` is code. But $y = x^2$ is math.
MODU
The laptop sold for $999. The span price = $x * 2 is code. But y=x2 is math.
Why
Every other renderer assumes a human wrote valid source. MODU assumes an LLM didn't.
TeX, KaTeX, browsers, PreTeXt — all of them were born to typeset source a person wrote on purpose. Model output is not that. It is half-closed, mixed-syntax, delimiter-optional slop, and it is the input MODU was designed for first, not patched for later.
Built to swallow output from
ChatGPT
Claude
Gemini
Copilot
Llama
HWP(X)
What the engine actually does
Tables that survive math
A | inside $-\ln|\cos x|$ is an absolute value, not a column break. Splitting cells on | first is why table math breaks everywhere else.
Markdown and LaTeX fight over the same characters — | _ * $ \. Deciding who owns each one is the whole job, and it happens before anything renders. Headings, bold, lists and math all come out of the same tangled string.
□raw paste
# Quadratic roots
**The formula**:
$$x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$$
1. Compute $D = b^2 - 4ac$
2. If $D > 0$, two distinct real roots
- first item
- second *item*
MODU
Quadratic roots
The formula:
x=2a−b±b2−4ac
Compute D=b2−4ac
If D>0, two distinct real roots
first item
second item
Math with no delimiters
Models drop raw LaTeX straight into prose with no $ at all. MODU detects it on language boundaries, wraps it, and renders it anyway.
□raw paste
The line through them is \ell(x) = 3x + 3, and the discriminant is \frac{-b}{2a}.
MODU
The line through them is ℓ(x)=3x+3, and the discriminant is 2a−b.
Whatever delimiter the model felt like
$…$, \(…\), \[…\] — every model has its own habit, and some change habits mid-answer. All of it normalizes to one form.
□raw paste
Inline \(a^2+b^2=c^2\) and the block form:
\[E = mc^2\]
MODU
Inline a2+b2=c2 and the block form:
E=mc2
The $ that isn't math
$999 is a price. `price = $x` is code. $y = x^2$ is math. One character, three different answers, decided by context.
□raw paste
The laptop sold for $999. The span `price = $x * 2` is code. But $y = x^2$ is math.
MODU
The laptop sold for $999. The span price = $x * 2 is code. But y=x2 is math.
Unfinished input is fine
Streaming output arrives half-written — an open $$, an unclosed **. MODU typesets what already closed and leaves the rest as text, instead of throwing the document away.
□raw paste
The probability is:
$$P(A) = \frac{1}{2}$$
and the next one is $$P(B) = \frac{1{
MODU
The probability is:
P(A)=21
and the next one is P(B) = \frac{1{
At scale
Fifty thousand characters. One pass. Zero errors.
No headings, no bold — just Korean and English prose with hundreds of formulas, block equations jammed against paragraphs on purpose. MODU typeset the whole document live in your browser just now. Scroll it.
Typesetting the document…
Usage
String in, HTML out.
No framework, no store, no DOM required. The engine depends on katex and jszip and nothing else, so it runs at build time on the server or live in the browser — every example above was typeset by MODU when this page was built.
Not published to npm yet — the engine is being hardened first.
□modu
import { renderContentToHtml } from "modu";
// Is the | inside that cell an absolute value, or a column break?
// The engine decides before anything renders.
const html = renderContentToHtml(
"| $f(x)=|x|$ | $\\frac{1}{2}x|x|$ |\n|---|---|\n| a | b |"
);
Playground
Paste something that breaks.
Real output from ChatGPT, Claude, Gemini — or one of the adversarial cases below. It renders as you type, in your browser.