← Interactive tools

The making of the Paper Diagram viewer

A lightly edited transcript of the conversation that built the paper-diagram viewer.

A curated transcript of the conversation (with Claude Code) that produced the Paper Diagram viewer for tao-web — an app that renders a mathematical paper as an automatically laid-out dependency diagram of its theorems, lemmas and definitions — from a backlog idea to release.

How to read this. As with the other making-of transcripts, the point is to convey the process:

The logic core and exports were checked with headless Node unit tests throughout, and the UI wiring with a DOM-shim smoke test; the app was kept uncommitted for local testing until it was ready to publish.


1. The idea, recorded for later

The project began as one of several app ideas logged in the skill for future work:

Another idea based on this blog post […]. One needs an LLM to be able to take an arbitrary paper and extract out a diagram, and this is unviable as a public-facing applet due to arbitrary token expenditure etc. But perhaps what we can do is create a general file format (JSON?) for paper diagrams, a deterministic visualizer for reading such diagrams, and have an LLM backend that takes some of my papers and extracts out diagrams, which can then be stored as data files for this visualizer to use as examples, and supply some sort of editor (and/or JSON spec) for others to build their own diagrams, perhaps using their own AI agents.

The division of labour there — an LLM produces the diagrams offline; a small, deterministic app reads them — shaped everything that followed.

2. Format first

I'd like to work a little on the paper diagram project. Specifically, to begin designing the JSON type data format for a diagram of theorems and lemmas connected by dependencies. qui.ver.app already does something similar; actually if there is enough compatibility that an export to quiver is feasible that would be nice (also export to tikz). I don't know in advance exactly what attributes etc. I would want eventually so I'd like a design which is extensible, but JSON seems well suited for this.

Proposed a native paper-diagram JSON — nodes (id, kind, label, name, statement, weight, …) and typed dependency edges — with quiver and TikZ as lossy export targets rather than the storage format, since quiver's positional model can't hold statement metadata. Named fields (not positional arrays), open enums and preserve-unknown-fields on round-trip keep it extensible.

Yes, this all sounds good, I agree with the native plus export and the edge convention. Now that I think about it, I'd want the app to do most of the placement automatically, with a manual override if needed — similar to the LaTeX typesetting model. This is in contrast to quiver where all placement is done by hand. In particular it would be nice if after adding or removing a theorem, the diagram auto-adjusts by default […]. In particular I like using weight as a key piece of metadata rather than location. […] For prototyping purposes one can start with the Gilbreath paper, attached.

Settled the guiding principle: position is derived, not authored; weight drives size and emphasis, never layout. Hand-encoded the Gilbreath paper as the first diagram (25 nodes, 42 edges) to pin the format down.

3. The viewer, and automatic layout

After confirming the schema was a good enough base to start building, and a Stage 1 request:

Built the DOM-free core: load() validates the diagram (rejecting duplicate ids, dangling edges, self-loops and cycles) and computes longest-path ranks; a layered ("Sugiyama") layout turns the DAG into coordinates, with a force-directed "balance" relaxation as an on-demand alternative. Then an SVG viewer on the shared applet stylesheet, with pan, wheel-zoom, and a side panel.

I can see the demo now. The "balanced" mode squishes the nodes together horizontally […]. For the legend, adding an orientation might help, e.g. A --> B "B uses A", A ...> B "B generalizes A". In the current model did you assign different (subjective) weights to different lemmas/definitions, or are they all equal weight currently?

Can you make some visual indicators for weight, e.g. thickness of borders? 1-5 is a good range I think for such a subjective measure, it would be pointless to attempt any finer graining than this.

Spread the balanced layout horizontally, annotated the legend with the edge conventions, and mapped weight 1–5 to border thickness and box size.

4. Read-only, and the LaTeX question

Looks good. I was about to ask for a feature to edit the dependency graph in the GUI (e.g., to change weights), but I'm now thinking that the smarter thing to do is have LLMs edit the JSON directly in an offline mode […] and have the viewer be purely read-only. […] it may be better to just let users edit their JSONs directly via their favorite LLM than try to create a full fledged graph editor here.

With regard to LaTeX, I guess trying to have native LaTeX support is going to be extremely bloated. Unicode translation of LaTeX is clunky and breaks if the LaTeX is too advanced. […] Perhaps one compromise is a \pdfortexstring type approach where theorems can have both a LaTeX field and (optionally) a plain text field that would be the default display in this renderer, whereas the exports to quiver or TikZ would use the LaTeX version.

Adopted the split: every node may carry both a LaTeX statement and an optional plain-text plain; the viewer panel prefers plain, the exports use the LaTeX. No in-app math rendering (KaTeX was judged too heavy for a self-contained, no-CDN app).

5. Exports, and a file:// detour

Added the export module (toTikz, toQuiver/toQuiverURL) reading the live layout, opened via an overlay modal. An empty-modal bug and non-functional buttons followed:

In the latest version the browser is hijacked by a window with copy download and X buttons but with no text displayed, and also no way to close the window.

Works great! A separate issue is that the TikZ and quiver export buttons are reporting bugs, e.g., Error: the export module (paper-diagram-export.js) did not load — try a hard refresh, and serve the page over http rather than file://

The strict Content-Security-Policy blocked the sibling export script under a file:// opaque origin. A short exchange established that the live site runs over http (GitHub Pages), and that a local server (VS Code's Live Server, http://127.0.0.1:5500) is the right way to test locally. Two more issues surfaced in the process:

Back in the file:// version, I tested the TikZ. One issue is that latex $ symbols are escaped out upon export, which for TikZ is not the wanted behavior. The quiver app can strip away the backslashes on the $ but does not do so for underscores, so for instance $c_i$ becomes $c\_i$.

Uncaught SyntaxError: Unexpected end of input

Inlined the export module into the page (covered by the CSP's 'unsafe-inline'), keeping a synced standalone copy for the Node tests. Fixed the escaping so LaTeX text fields are emitted verbatim. The syntax error was a bare HTML fragment breaking Live Server's reload-script injection — wrapped the page as a complete <!doctype html> document, a lesson folded back into the skill.

6. Light in-app editing

Given that the TikZ and quiver exports adjust to user alterations, perhaps some minor edit capability is useful. I'm thinking of two types of edits. One is when a theorem is selected, that an edit button is enabled […] for theorem title, weight, LaTeX and plain text, and dependencies […]. The other capability would be to be able to drag theorems in and out of the main panel and into a panel of "ignored" theorems […]. When doing so, dependencies are updated transitively: so if one had A -> B -> C and B is dragged out […] then one is left with A -> C. (one would need some rule to handle generalizations; let's say that generalization is transitive but a hybrid of generalization and ordinary dependence reverts to dependence (as the "dominant allele").

Reversed the read-only decision for light editing: the full source of truth SRC is the working copy; the displayed diagram is a derived view = SRC minus ignored nodes with edges transitively contracted (generalization∘generalization stays a generalization; any dependence in the path dominates). A node editor (fields + a dependency sub-editor) mutates SRC and re-validates on save; an "ignored" tray restores nodes. The literal drag-between-panels was replaced with a button-plus-tray, which is robust against the pan/zoom gestures. Several refinements followed — the weight-threshold slider was reversed to fill toward the shown side, a truncated dependency dropdown was widened, and the kind legend became filter checkboxes.

7. A library of papers

Well, I'd like to have a library of several papers, not just one. […] there's no reason to restrict to my own papers, and actually diagramming some notable papers in my field would be interesting. Here is a notable recent paper (solving the Kakeya conjecture) worth diagramming, and then we can have a "Load paper" button or dropdown to select from the various papers in the library.

Made the viewer multi-paper with a dropdown; hand-encoded the Wang–Zahl Kakeya paper (56 nodes). This raised a question of scale:

So, even with the network restrictions mentioned previously, the app is able to load data from the supplementary file paper-diagram-data.js? How scaleable is this? Would, say, a library of 100 paper diagrams be feasible in this model?

Explained the two-tier model: a small curated set drives the dropdown; the rest live as individual diagrams/<id>.js files loaded on demand by injecting a same-origin <script> (allowed under the CSP, unlike a network fetch), which scales to hundreds of papers with no per-paper cost until it is opened.

The JSON button serves as both import and export. Perhaps calling it "Edit JSON" instead […]. Also, would an export to SVG be possible? […] I envisage eventually all of my ~300 previous published papers coming with a diagram, and to have a link to a URL derived from this app page that loads that specific diagram and displays it.

Added a standalone SVG export, turned the JSON view into a real import (paste/edit → validate → load), and added ?paper=<id> deep-links.

[…] currently, switching a paper changes the main header of the applet page to the title of the paper. I'd like the main header (and the text below) to be constant, and to have a subheader with the title of the paper closer to the applet (actually, I'd prefer if this header was more visibly part of the app itself than the surrounding HTML — an interface [where] actions inside the app alter the HTML outside of the ostensible boundaries of the app is a bad visual precedent […]). Also […] a small edit button to allow changing it directly […].

Moved the per-paper title and provenance inside the app's own header strip, leaving the page header constant, with an inline rename button. The principle — an app must not reach outside its own box — later also removed a stray document.title mutation.

8. Disclosure, and a design philosophy

Another point to add is that AI use will be disclosed on each of the pages containing AI-generated content. (Which would include this very section that we are drafting.)

[…] the discussion of the paper dependency diagrams should be replaced with a more generic disclaimer that while many of the applets display only deterministic mathematical concepts, a few (such as the paper diagramming applet) contain subjective LLM-generated content that is not intended to be authoritative. […] I think a footnote suffices for AI disclosure.

Added a data-driven "Design philosophy" section to the applets page (visual-aids-not-authorities; private and self-contained; transparent but not a template; feedback prefers issues over code PRs), an editorial-reading disclaimer atop the paper-diagram app, and an AI-disclosure footer on the original apps.

9. Filling the library

Let's fill out the library some more. […] we can demote the Gilbreath paper to the library only, and focus only on spectacular papers by other authors. I enclose three very highly regarded papers, can you diagram them one by one […]?

Curated the dropdown to spectacular papers by other authors — Wiles's proof of Fermat's Last Theorem, Perelman's Ricci-flow entropy formula, and Guth–Maynard on Dirichlet polynomials — with Gilbreath moved to the library-only catalogue.

Here is the paper that initially motivated the entire project […] "A counterexample to the periodic tiling conjecture" […]. In particular we included a diagram of the type this app produces. […] I notice that we also utilized the ability to give individual theorem boxes a background color. So, I guess the first thing to do is add a background color attribute in the JSON […] defaulting to white […]. Then make a diagram for this paper (ideally building upon the figure already in the paper) with some colorization […].

Added an optional per-node color field (rendered in the viewer and the SVG/TikZ exports, injection-safe, white by default) and diagrammed the periodic-tiling paper with its published tri-colour scheme.

10. More export targets, and unbundling

A guidance fix for the SVG export (its text must be saved as a .svg file), then two new formats:

Let's add the Mermaid and Dot exports.

Added Graphviz DOT and Mermaid flowchart exports — portable text graphs re-laid-out by their own tools — bringing the total to six targets (SVG, TikZ, quiver, DOT, Mermaid, JSON). A compile failure in the TikZ of the tiling paper — bare underscores and Unicode in node names breaking pdflatex — was fixed by making the export escape LaTeX-special characters and map the common math Unicode, verified by compiling every diagram.

Would it be worth unbundling the pre-loaded papers out of the main js file and load them by the regular library load feature? […] this can make it easier to maintain.

Moved every diagram out to its own lazy file, leaving the data module a pure index — one uniform loading mechanism.

11. A 1975 landmark, and release

The last diagram was the paper that had been the project's namesake motivation — Szemerédi's 1975 proof of his theorem, which famously prints its own (deliberately non-acyclic) logical flow chart:

Here is the source. […] one notable thing about this paper is that it already contains a (non-acyclic) graph indicating the "approximate" flow chart; it would be interesting to see how your version of the diagram compares (obviously it cannot be faithful, but perhaps there will be parallels).

Encoded Szemerédi's theorem as a 26-node DAG grouped by the paper's sections — necessarily linearising the simultaneous induction its own flow chart draws as cycles, while keeping the same landmarks.

After this I think we are nearly ready to go live. […] can you run the audits listed in the skill and also review the app documentation and code as a whole, taking into account the design philosophy choices of this project, to see if you recommend any final feature changes before alpha release?

Ran the routine audits (no silent failure modes; documentation faithfulness; tests green; a complete HTML document; file:// vs http) and recommended no new features — only two small polish items and the remaining publishing steps.

Let's implement your two minor ideas, catalog, generate a making of, and then push.

Added a multi-level undo for edits and deletes, made section/external/ref editable in the GUI, wrote the catalogue entry, and assembled this transcript — the last box before release.

Shortly after release, with the per-node colour field in place:

Now that we have colors, can you go back to earlier JSON diagrams and colorize them?

Retro-colourised the six earlier library diagrams by grouping each paper's nodes into its major sections (cited/external results left white) — a purely editorial layer over the kind-coloured borders, mirroring the section colouring of the Szemerédi and periodic-tiling diagrams. No source files were needed: the section, kind and dependency structure was already encoded in each diagram.


The app ships with its logic core, exports and rendering covered by Node unit tests and a DOM-shim smoke test. The pre-installed diagrams are LLM-generated editorial readings — a visual aid for orientation, not an authoritative account of any paper.