TL;DR: I built Scriba — a free, open-source (MIT) renderer that turns a LaTeX editorial (math, prose, tables, code, and step-by-step algorithm animations) into one self-contained, sanitized HTML file. Animations are driven by real code, not hand-drawn frames. To see it on real problems right now: 50 CSES problems where every editorial is explained with an animation — open any of them and press play. Or write your own in the playground, no signup.
Hello, Codeforces!
If you've ever written an editorial — for a school contest, a gym, or just a detailed solution comment — you know the drill. The prose and the math are the easy part. Then you hit "and now the DP table fills up like this", and you're hand-drawing cells in Excalidraw, screenshotting each state into step1.png, step2.png, … Then you find an off-by-one in your own explanation, and all nine screenshots are garbage. Re-draw, re-shoot, re-upload.
I did this one too many times while building the editorial corpus for my judge, and got tired of it. So I built something.
The friction with hand-made diagrams
- Screenshots go stale the moment the algorithm logic changes — fix a bug, redraw every frame.
- A GIF can't be paused mid-step, and readers can't step backwards.
- The diagram lives in a different tool than the statement, so they drift apart silently.
- KaTeX/MathJax solve the math beautifully, but an editorial is math + prose
- tables + code + "watch what happens at step 4".
- Sharing source with a co-setter means "here's the .tex, and also this Excalidraw link, and these PNGs".
What Scriba does
- Full statements, not just math: math, prose, tables, and code highlighting in one document, rendered server-side (the math inside goes through KaTeX — credit where due).
- 21 animation primitives: array, DP table, matrix/heatmap, graph, tree, stack, queue, deque, linked list, hash map, number line, code panel, variable watch… most editorial diagrams map 1-1 to a shape you already think in.
- Frames driven by real code: a sandboxed Starlark block (
\compute/\foreach) runs your actual loop and fills frames from its output — fix the logic once, every frame updates. - Self-contained & sanitized: math, styles, and the player script all inline in one HTML file — drop it into any page, no toolchain. Untrusted setters' statements can't script-inject your site.
- Free, MIT — live playground with shareable snippets, or
pip install scriba-tex.
(Honest scope: Scriba renders a LaTeX subset — body content plus its own animation syntax — not full LaTeX.)
What the source looks like
A minimal 3-step animation:
\begin{animation}[id="hello", label="Hello Scriba"]
\shape{a}{Array}{size=5, data=[3,1,4,1,5], label="my array"}
\step
\narrate{A simple array with 5 elements.}
\step
\recolor{a.cell[2]}{state=current}
\narrate{Highlight the middle element.}
\step
\recolor{a.cell[2]}{state=done}
\narrate{Mark it as done.}
\end{animation}
That renders as an inline player with play / pause / step controls.

The interesting part is when frames come from real logic. This is an actual example from the guide — the matrix-chain DP table, computed by the real nested loops inside a \compute block, then poured into the table:
\begin{animation}[id="matrix-chain", label="Matrix-chain DP table"]
\shape{dp}{DPTable}{rows=5, cols=5, label="dp[i][j]"}
\compute{
n = 5
p = [30, 35, 15, 5, 10, 20]
dp_vals = [[0 for _ in range(n)] for _ in range(n)]
for length in range(2, n + 1):
for i in range(n - length + 1):
j = i + length - 1
dp_vals[i][j] = 10**9
for k in range(i, j):
cost = dp_vals[i][k] + dp_vals[k+1][j] + p[i] * p[k+1] * p[j+1]
if cost < dp_vals[i][j]:
dp_vals[i][j] = cost
}
\step
\foreach{i}{0..4}
\foreach{j}{0..4}
\apply{dp.cell[${i}][${j}]}{value=${dp_vals[i][j]}}
\endforeach
\endforeach
\narrate{Minimum matrix-chain multiplication cost table, built with nested for loops.}
\end{animation}
If I later realize the cost formula was wrong, I fix the loop — not nine screenshots. And unlike VisuAlgo's fixed canonical examples, this runs your problem's data and your transition.
Don't take my word for it — 770 real problems use this
Every editorial on my judge (app.judge.zone) is rendered with Scriba, in 8 languages (including RTL Arabic). If you only click one link in this post, make it the first one:
- 50 CSES problems — intro to advanced, where every editorial explains the algorithm with a step-by-step animation: watch the DP table fill or the tree get re-rooted, instead of parsing three paragraphs of index notation. Open any editorial and press play — that's the whole pitch.
- 720 USACO problems — 65 contests, 2011–2026. The volume test: one pipeline, no per-page hand-tuning.
(And even if you never write editorials, the playground doubles as a free scratchpad for stepping through your own DP while upsolving.)
Try it
Open scriba.judge.zone — no signup. The LaTeX guide and animation guide cover every command with runnable examples. To render locally or self-host: pip install scriba-tex (v0.39.0), source on GitHub (MIT).
Feedback / bug reports / feature requests
- Next primitive: Trie, DSU forest, or Fenwick/BIT — which one would you actually use first?
- Which LaTeX command do you miss most inside statements?
Bug reports and PRs welcome on GitHub, or come argue about animation timing in the Discord: discord.gg/pg52FspEns.
Thanks
Scriba stands on KaTeX — all math inside statements is rendered through it server-side, and it's an absurdly good piece of software. Thanks also to every editorialist on CF whose hand-drawn DP tables and graph doodles over the years quietly defined the list of 21 primitives — this tool is basically those whiteboard drawings, made reproducible.
Happy animating.








