[Tool] Scriba — a free renderer for LaTeX editorials with step-by-step algorithm animations

Revision en2, by ZhangShan, 2026-07-16 11:03:08

TL;DR: I built Scriba — a free, open-source (MIT) renderer that takes a LaTeX subset and turns a full problem statement — math, prose, tables, highlighted code and step-by-step algorithm animations — into one self-contained, sanitized HTML file. Animations are driven by real code, not hand-drawn frames. No signup: open the playground, paste, render.

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 get to "and now the DP table fills up like this", and suddenly you're hand-drawing cells in Excalidraw, screenshotting each state, numbering the PNGs, and pasting them in order. 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 9 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.
  • One self-contained HTML file: everything inlines — math, styles, the tiny player script. Drop it into any page; no LaTeX toolchain or JS library to integrate on the client. Output is sanitized, so rendering statements from untrusted setters won't script-inject your site.
  • Live playground with shareable snippet links — write, render, send a link.
  • Free, MIT, pip install scriba-tex.

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.

GIF/video của player — nên quay bằng ví dụ matrix-chain bên dưới

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.

How is this different from VisuAlgo / drawing by hand?

Visualizers like VisuAlgo are great for learning a canonical algorithm, but they animate their fixed examples — you can't feed them your problem's data or your transition. Scriba animations are part of your LaTeX source and run your logic. And compared to the Excalidraw/TikZ + screenshot workflow, the diagram can't drift out of sync with the statement, because they're the same file.

To be honest about scope: Scriba renders a subset of LaTeX (body content, not the preamble) plus its own animation syntax. It is not, and doesn't try to be, full LaTeX.

Battle-tested on a real corpus

Every editorial on my judge (app.judge.zone) is rendered with Scriba: 770 problems — 65 USACO contests (2011–2026) plus a curated 50-problem CSES batch spanning intro to advanced — with statements and editorials in 8 languages (including RTL Arabic), animations included. So the renderer has survived a real multilingual corpus, not just demos.

Even if you never write an editorial: the playground works as a free scratchpad — paste your own DP transition or graph trace while upsolving and step through it, instead of dry-running it on paper.

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

Two concrete questions I'd love answers to:

  1. Next primitive: Trie, DSU forest, or Fenwick/BIT — which one would you actually use first?
  2. 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.

Tags tools, latex, editorial, visualization, animation, open source

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en6 English ZhangShan 2026-07-16 16:08:28 90
en5 English ZhangShan 2026-07-16 13:53:48 74
en4 English ZhangShan 2026-07-16 13:46:58 0 (published)
en3 English ZhangShan 2026-07-16 13:44:13 3245
en2 English ZhangShan 2026-07-16 11:03:08 0 (saved to drafts)
en1 English ZhangShan 2026-07-16 10:59:44 7017 Initial revision (published)