SPICE netlist in, placed schematic out: devices at integer points with an orientation, every pin's point, wires as polylines per net, junction dots, net labels and no-connect marks laid out the way textbooks draw circuits (supply at the top, ground at the bottom, signal left to right).
The library draws nothing and knows no device. The application says what each
device class looks like (terminal anchors and body strokes) and reads the
result to write its own format. Its public boundaries follow cktImg's; see
docs/API.md.
const np = @import("NetlistParser");
var lib = np.Library.init(gpa); // your symbols
defer lib.deinit();
try lib.loadZon(arena, symbols_zon, &diags); // e.g. tests/symbols.zon
var placed = try np.place(gpa, &np.Config.default, &lib, &.{spice_text}, &diag);
defer placed.deinit();
// placed.dev_pos, .dev_orient, .pin_xy, .segments(net), .junctions, .labels, …Drawn by the library, untouched, with the tests' symbol set
(zig build gallery -- --svgs out/ makes all of them).
Bandgap reference. Three mirrored PMOS branches and an op-amp between
the first two. The shared gate line g is labelled, because wiring it
would have to cross the branches.
Telescopic cascode OTA. Two stacked columns of five transistors that stay level, with bias lines as labels.
Two-stage Miller op-amp. Mirror load, tail source, second stage and the compensation capacitor across it.
Five-transistor OTA.
Sallen-Key low-pass with a unity-gain buffer. The feedback capacitor's
far end is named out rather than routed around the op-amp.
Differential pair with resistive loads.
A .subckt as a block. It's the op-amp below, drawn with its ports
placed as the *@ comments say.
An X instance of a .subckt in the netlist is one block, drawn with your
class of that name or a generated box. Comments in the definition steer it:
.subckt opamp inp inn out vdd vss
*@ left inp inn (also right / top / bottom)
*@ right out
...
.ends
*@ expand draws the body instead, flattened with ngspice names (r.x1.r1).
Zig 0.16.0.
zig build # libcktimg.a + include/cktimg.h + the gallery tool
zig build test # library, algorithm, API and C ABI tests
zig build -Dlatex_renderer=true # also cktimg-tex and the TikZ emitter
zig build gallery -- --svgs out/ # the textbook circuits as SVG
zig build gallery -- --config lint.zon in.cir out.svg
zig build fuzz # 4000 random netlists; smallest example per rare casesrc/— the library:netlist.zig(parser),schematic.zigandlayout.zig(the algorithm, specified inALGORITHM.md),placed.zig(the result),library.zig(device classes),config.zig(lint.zon),lint.zig,geom.zig,latex.zig,json.zig,abi.zig(the C ABI).include/cktimg.h— the C header.tests/— the tests, the tests' symbol set (symbols.zon), an SVG renderer and the gallery, all on the public API.tools/tex.zig—cktimg-tex, which writes CircuiTikZ;latex/cktimg.sty— the LaTeX package (loadscircuitikz).tools/xschem/— the xschem target:cktimg-xschem in.cir out.sch, its symbol set and mapping (symbols.zon,xschem.zon, regenerated from xschem's library bygen_symbols.py), androundtrip.py, which checks that xschem netlists the drawing back to the input's nets.lint.zon— every setting, with its default.