Author diagrams
Inspect the circuit, not just the drawing
Extract nodes, nets, and edges from a validated document and check seven design rules against them.
- sheet
- 6 / 15
- rev
- v0.7
- sections
- 3
- compiled
- 3
Every other text-to-diagram tool stops at a picture. This one does not have to: the parser already resolves net topology and the layout pass already enumerates ports, so the source that renders can also be inspected. buildNetlist returns that connectivity, verifyNetlist runs design rules over it, and inspectSchematic does both in one call. All three are pure — no rendering, no geometry, no I/O.
01 / ModelWhat the compiler already knows
A netlist has three parts. nodes are the declared components with their stable port names. nets are the sets of terminals the document ties together, carrying the author's net name where one was given, the signal domains and bus widths observed on the net, and the source lines that contributed to it. edges are the declared connections themselves, kept so that a diagnostic can point at the line that caused it.
Terminals that share an exact node are one net, exactly as the renderer sees them:
source:V8 "DC" at (110, 150) #blue [type=voltage-dc]
resistor:R8 "1 k\Omega" at (390, 150) #amber
ground:GRT "return" at (680, 150) #slate
V8.positive -> R8.in #blue [line]
R8.out -> GRT.in #slate [line]
V8.negative -> GRT.in #slate [ortho]import { inspectSchematic, parseSchematic, parseSchematicFence } from '@schemd/core';
const fence = parseSchematicFence('schemd bounds="900x400" title="Supply"')!;
const { netlist, diagnostics } = inspectSchematic(parseSchematic(source, fence));
netlist.nodes[0].ports; // ['negative', 'positive']
netlist.nets.length; // 2
diagnostics; // []
02 / RulesSeven checks, each with a stable code
Diagnostics carry a code you can assert against, a severity, the subjects involved, and the source line wherever a declaration owns the fault. They arrive ordered by severity, then line, then code, so the output of a check is stable enough for a snapshot test or a CI log.
| Code | Severity | Fails when |
|---|---|---|
shorted-supply |
error |
Two supply rails — a source positive, a power rail, or a ground — share one net. |
width-mismatch |
error |
One net carries connections declaring different bus widths. |
domain-mismatch |
error |
One net mixes signal domains, such as quantum and digital. |
unconnected-component |
warning |
A declared component takes part in no connection. |
duplicate-connection |
warning |
The same pair of terminals is connected more than once. |
multiple-drivers |
warning |
Two digital outputs drive the same net. |
disconnected-subcircuit |
info |
The diagram contains more than one independent connected group. |
The diagram below ties the supply straight to ground through a shared net name. It renders — the geometry is legal — but it does not pass:
source:V8 "DC" at (110, 150) #blue [type=voltage-dc]
resistor:R8 "1 k\Omega" at (390, 150) #amber
ground:GRT "return" at (680, 150) #slate
V8.positive -> R8.in #blue [line net=rail]
R8.out -> GRT.in #slate [line net=rail]error shorted-supply line 5 Net rail ties supply rails V1, GND together.
03 / DisciplineWhy the rules stay narrow
A checker that cries wolf is worse than no checker, so each rule is deliberately conservative.
A source's negative terminal sharing a node with ground is the return path of nearly every circuit ever drawn — so only two rails on one net count as a short, never a rail and a return. Two analog terminals sharing a node is ordinary topology, not contention — so multiple-drivers applies to digital domains only. A component with unused ports is normal; only a component that takes part in no connection at all is worth mentioning.
The diagram below is contention, because the domain says so:
port:U "U" at (110, 150) #cyan
port:V "V" at (110, 330) #cyan
and:G8 "AND" at (470, 240) #purple
U.out -> G8.in1 #cyan [digital]
V.out -> G8.in1 #cyan [digital]warning multiple-drivers line 5 Net $1 is driven by A.out, B.out.SCHEMATIC_RULES publishes every code with its severity and one-line summary, so a host can render this table, filter by severity, or fail a build on errors alone without hard-coding strings.