mp-tikz-wasm

Diagram tags

Every figure below is a <script> or custom tag in the HTML source, typeset by MetaPost, pdfTeX, LuaTeX (for graph drawing) and dvisvgm. On this copy of the page the figures were saved in advance — mpost-wasm --prerender tags.html wrote them to figures/ — so they load as small static files, and the engines start only for the deliberately broken figure at the bottom. Typeset everything in this tab instead.

TikZ, the tikzjax way

A <script type="text/tikz"> holding just a tikzpicture. It is wrapped in a standalone document automatically; libraries come from data-libraries.

A whole document

If the body contains \documentclass, it is compiled as is — any class, any package in the bundles, pgfplots included.

Custom elements

<tikz-diagram> and <metapost-diagram> work the same way and render when they enter the page (a MutationObserver catches later additions). Inside a custom element the content is HTML, so write &lt; for <. A data-gdlibraries attribute (or any use of graphdrawing or \directlua) switches that diagram to LuaTeX.

\begin{tikzpicture}[node distance=1.4cm] \node[circle,draw,fill=blue!15] (a) {$a$}; \node[diamond,draw,fill=red!15,right=of a] (b) {$b$}; \draw[-latex,thick] (a) -- node[above] {$f$} (b); \end{tikzpicture} \graph[layered layout, nodes={draw,circle,fill=green!15,font=\small}, sibling distance=7mm, level distance=7mm] { a -> {b -> {d, e}, c -> {f, g}}; e -> g; }; draw fullcircle scaled 60 withpen pencircle scaled 1.2 withcolor (0.1,0.3,0.8); for i = 0 upto 11: draw origin -- 30 dir (30i) withcolor (i/11)[blue,red]; endfor label.top(btex $\oint_\gamma f = 2\pi i\sum \mathrm{Res}$ etex, (0,32));

MetaPost script tags

<script type="text/metapost">: a body without beginfig becomes one figure; data-tex chooses the label engine.

Errors

A broken diagram shows its diagnostics instead of failing silently.

How to use it on your page

<script type="module" src="https://your-host/mp-tikz-wasm/dist/auto.js" data-figures="figures/"></script>
<script type="text/tikz" data-libraries="arrows.meta">
  \begin{tikzpicture} \draw[->] (0,0) -- (2,1); \end{tikzpicture}
</script>
<metapost-diagram>draw fullcircle scaled 50;</metapost-diagram>

Host the dist/ folder (the three .wasm files, the JS, and bundles/) anywhere static; the script finds them relative to itself. Rendered SVGs are cached in IndexedDB by content hash, so a revisit shows the figures without running TeX.

To spare first visits too, save the figures next to the page: npx mpost-wasm --prerender page.html writes figures/figure-HASH.svg for every diagram on the page (HASH is six characters of the hash of the element's source and attributes), or open the page and call mpTikzWasm.saveFigures() in the browser console, which writes the same files into a folder you pick (Chrome, Edge) or downloads them as a zip. With data-figures="figures/" on the loader, each element loads its file if it exists and the engines start only for the figures that are missing. The name is the content: a changed diagram gets a new file, and an old one is simply never requested.