# mermaid-compile Syntax-check every ` ```mermaid ` block across markdown files. Runs [mmdc][1] (the official Mermaid CLI) inside a transient podman container — no local Node install, no global package pollution. [1]: https://github.com/mermaid-js/mermaid-cli ## Prereqs - Python ≥ 3.9 - Podman (rootless works fine) - Network reachable to Docker Hub for the first `docker.io/minlag/mermaid-cli` pull ## Install ```fish git clone https://git.timemachine.center/Timemachine/mermaid-compile.git cd mermaid-compile chmod +x check-mermaid.py ``` Optionally symlink onto `$PATH`: ```fish ln -s "$PWD/check-mermaid.py" ~/.local/bin/check-mermaid ``` ## Usage ```fish # Walk current dir ./check-mermaid.py # Specific path(s) ./check-mermaid.py docs/ README.md # Skip the upfront podman pull (faster reruns) ./check-mermaid.py --no-pull docs/ # Override the image ./check-mermaid.py --image my-mirror.example.com/mermaid-cli:1.2.3 docs/ ``` Exit code: - `0` — every block parsed - `1` — at least one parse failure - `2` — environment problem (no podman, etc.) Suitable for `make check-docs`, pre-commit hooks, CI. ## Output ``` ✓ docs/architecture.md:4 ✓ docs/architecture.md:111 ✗ docs/auth-flow.md:6 1 of 3 block(s) FAILED: === docs/auth-flow.md:6 === Error: Parse error on line 3: ...D A --> B A -> C invalid edge ---------------------^ Expecting 'SEMI', 'NEWLINE', 'EOF', 'AMP', ..., got 'MINUS' ``` The reported line is the line of the offending statement *within the Mermaid block* (1 = the first line after the opening ` ```mermaid `). The script prints the markdown file's line of the fence + 1 as the block start, so jumping with `Ctrl+G` in most editors lands you on the diagram body. ## Why mmdc and not a pure parser? Mermaid's grammar is implemented in JavaScript (Jison). The simplest trustworthy way to validate is to invoke the same renderer the docs viewer will use. mmdc renders to SVG (which forces a full parse + layout); we ignore the SVG and only consume the exit code. `docker.io/minlag/mermaid-cli` packages Node + Puppeteer + Chromium already, so no host-side runtime needed. ~250 MB pull, one-time. ## Common parse errors and fixes ### flowchart node labels Wrap the label in `"..."` whenever the text contains any of `[`, `]`, `(`, `)`, `{`, `}`, `$`, `"`. The parser treats those as shape-delimiters mid-token. | Wrong | Right | |---|---| | `Box[/portal · waker (waking)/]` | `Box[/"portal · waker (waking)"/]` | | `Box[build []liteRoute]` | `Box["build []liteRoute"]` | | `Box[Templates ${VAR}]` | `Box["Templates ${VAR}"]` | | `Cond{state == "x"?}` | `Cond{"state == 'x' ?"}` | ### sequence-diagram messages Cannot contain `;` — Mermaid reads `Foo->>Bar: a; b` as a partial statement and misidentifies the next line. Replace with `then` or `,`, or use the HTML entity `#59;`. | Wrong | Right | |---|---| | `A->>A: mu.Lock(); set flag` | `A->>A: mu.Lock then set flag` | | `A->>A: x=true; y=false` | `A->>A: x=true, y=false` | ## License MIT. See LICENSE.