drawlang 0.1.2

Precision diagrams as code — a DSL and renderer built for AI-agent authors
# drawlang

[![crates.io](https://img.shields.io/crates/v/drawlang.svg)](https://crates.io/crates/drawlang)
[![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/nitingupta910/drawlang/blob/main/LICENSE)

Precision diagrams as code — a DSL and Rust renderer built for AI-agent
authors.

Most diagram source is now written by coding agents, which iterate by
reading text, not by looking at pixels. drawlang closes that loop: **the
renderer is also a verifier.** Every render can emit machine-readable
geometry and visual lints, so an agent converges on a clean diagram the same
way it converges on a green test suite.

![GPU topology example](https://raw.githubusercontent.com/nitingupta910/drawlang/main/examples/renders/gpu-topology.svg)

The source for that diagram is [examples/gpu-topology.drawl](https://github.com/nitingupta910/drawlang/blob/main/examples/gpu-topology.drawl) —
a parameterized GPU component instantiated in a loop, ports with sides, an
NVLink ring via `(i + 1) % 4`, and two layout constraints. The PCIe lanes are
routed by an obstacle-avoiding orthogonal router that nests parallel runs.

## Why another diagram language

- **Layout is a gradient, not a binary.** Auto-layout by default → `row` /
  `column` / `grid` containers → constraints (`align`, `gap`, `below`) solved
  with Cassowary → absolute `pin` as the escape hatch. You pay only for the
  precision you need — the thing Mermaid can't do and Figma can't automate.
- **The feedback loop is machine-readable.** `render --report` emits every
  element's bbox and port positions plus lints: label overflow, box overlap,
  edges cutting through nodes, label collisions, crossing counts — each with
  a concrete `fix` field.
- **Rust-quality errors.** Full error recovery (every error in one pass),
  spans, did-you-mean suggestions, instantiation traces, stable codes with
  `drawlang explain E0214`.
- **Deterministic.** Same input → byte-identical SVG. Labels are measured
  with the bundled font (DejaVu Sans via ttf-parser), so boxes fit their text
  by construction and PNG output matches exactly.
- **Layout stability.** `drawlang freeze` locks solved positions into a
  `.lock` sidecar; later edits stop reshuffling a diagram you've approved.

## Quick start

```text
cargo install drawlang

drawlang check arch.drawl              # parse + semantic lints, all at once
drawlang render arch.drawl -o arch.svg --report
drawlang render arch.drawl -o arch.png --scale 2 --theme dark
drawlang query arch.drawl 'gpus[2]'    # one element's resolved geometry
drawlang fmt arch.drawl                # canonical formatting
drawlang freeze arch.drawl             # pin today's layout
drawlang explain W0410                 # what a diagnostic means + how to fix
drawlang cheatsheet                    # one-page guide to paste into an LLM
```

## The language in 30 seconds

```text
drawl 0.1
canvas { theme: paper; flow: right }

def gpu(i) {
  label: "GPU {i}"
  port nvlink { side: top }
  port pcie   { side: bottom }
}

group host "Host" { cpu { label: "EPYC 9754" } }
gpus: row { for i in 0..4 { gpu(i) } }

for i in 0..4 { host.cpu -> gpus[i].pcie : "PCIe 5.0 x16" { class: bus } }
for i in 0..4 { gpus[i].nvlink <-> gpus[(i + 1) % 4].nvlink : "NVLink" }

constrain {
  align(gpus[*], top)
  gap(host, gpus, 48)
}

class bus { stroke: 2; color: @accent; routing: orthogonal }
```

Structure, layout intent, and style are orthogonal layers: an edit to one
never disturbs the others, and diffs stay local. Everything is addressable by
a stable path (`host.cpu`, `gpus[2].pcie`) — in constraints, in `query`, in
every error message, and in the geometry report.

The full syntax reference is [docs/CHEATSHEET.md](https://github.com/nitingupta910/drawlang/blob/main/docs/CHEATSHEET.md) — the
same text `drawlang cheatsheet` prints, sized for an LLM context window.

More examples in [examples/](https://github.com/nitingupta910/drawlang/tree/main/examples), rendered output in
[examples/renders/](https://github.com/nitingupta910/drawlang/tree/main/examples/renders):
a [CPU die](https://github.com/nitingupta910/drawlang/blob/main/examples/cpu-arch.drawl) (grid containers, nested components,
`width: fill`) and an [inference pipeline](https://github.com/nitingupta910/drawlang/blob/main/examples/inference-pipeline.drawl)
(dark theme, bidirectional cache traffic, dashed orthogonal return path).

## Workspace

```text
crates/drawlang-syntax    lexer, parser (error recovery), AST, formatter
crates/drawlang-core      semantic model, layout, constraints, router, report
crates/drawlang-render    SVG writer, themes, PNG via resvg
crates/drawlang           the CLI
docs/DESIGN.md            design rationale + milestone history
```

Licensed under [Apache-2.0](https://github.com/nitingupta910/drawlang/blob/main/LICENSE). The bundled DejaVu fonts ship under
their own permissive license (see `crates/drawlang-core/assets`).