universelabSCI · CLI · BIO

ES

Diagrams

texforge build intercepts embedded diagram environments before compilation and replaces them with rendered figures. Your original .tex files are never modified — rendering happens in the build/ copies.

All three renderers are pure Rust: no browser, no Node.js, no dot binary required.

Diagrams are embedded as vector PDF, so they stay sharp at any zoom level and their label text remains selectable and searchable in the final PDF. If a diagram’s SVG can’t be converted to PDF, texforge falls back to a rasterized PNG for that one diagram, prints a warning naming it, and the build still succeeds.

Mermaid

% Default: width=\linewidth, pos=H, no caption
\begin{mermaid}
flowchart LR
  A[Input] --> B[Process] --> C[Output]
\end{mermaid}

% With options
\begin{mermaid}[width=0.6\linewidth, caption=System flow, pos=t]
flowchart TD
  X --> Y --> Z
\end{mermaid}

Graphviz / DOT

\begin{graphviz}[caption=Pipeline]
digraph G {
  rankdir=LR
  A -> B -> C
  B -> D
}
\end{graphviz}

Options

Option Default Description
width \linewidth Image width
pos H Figure placement (H, t, b, h, p)
caption (none) Figure caption
style default Editorial style preset — see below

When a caption is given the diagram is wrapped in a figure environment at the requested position; without it the image is embedded inline.

If an option value contains a comma, wrap it in braces — the same convention LaTeX packages already use for this:

\begin{mermaid}[caption={Preset \texttt{editorial}: paleta restringida, un solo acento}]
flowchart LR
  A --> B
\end{mermaid}

Without the braces, the diagram intercepts commas as option separators, so un solo acento would be parsed as a second, unrecognized option and the caption would end at restringida. An unrecognized option prints a warning naming it and the environment, but the build continues; an unterminated { fails the build.

Style presets

By default, each renderer draws diagrams with whatever it ships as its own look — which means a Mermaid figure and a D2 figure in the same document can look like they came from different tools. style= applies one of four named presets consistently across all three renderers:

\begin{mermaid}[style=editorial, caption=System flow]
flowchart LR
  A --> B --> C
\end{mermaid}
Preset Effect
default Each renderer’s own untouched default. Omitting style= always renders this — no existing document changes appearance.
editorial Restrained palette, one accent colour, no drop shadows, thin strokes, generous whitespace.
monochrome Greyscale only — for documents printed in black and white.
technical Drafting register: uniform stroke weight, no fills, labels in a monospaced face where the renderer allows it.

An unrecognised style name (e.g. style=editoral) fails the build with a message naming the value and listing the valid ones — it never silently falls back to default.

Presets are named, not parameterised: there is no style=editorial,accent=#ff0000. Opening them to arbitrary colours would make them themes, a different and larger feature.

Project-wide default

Set a document-wide default in project.toml:

[diagrams]
style = "editorial"

The environment’s own style= attribute overrides this; omitting both falls back to default.

Fidelity varies by renderer

The three renderers expose very different styling surfaces, so the same preset degrades differently depending on which one draws it — a diagram still renders and the build still succeeds even where a renderer can’t express part of a preset.

  • Mermaid has the richest surface (a full theme: colours, font, layout spacing), so every preset is expressed almost exactly.
  • D2 has native theming (a named colour palette), so presets map onto it with good fidelity. technical’s monospaced labels come from D2’s own mono theme rule, which also adds minor drafting-style ornamentation (double borders, container dots) to nested/grouped diagrams as a side effect — not a colour or fidelity gap, just a quirk of the one lever D2 exposes for a monospaced face.
  • Graphviz has no theme concept at all — styling is per-node and per-edge only. Node fill/border colour and edge colour carry over, but a document-wide background is not expressible, and neither is a monospaced label face (technical’s font rule has no effect here).