114 lines
3.0 KiB
Markdown
114 lines
3.0 KiB
Markdown
# 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.
|