AI-driven TikZ circuit schematics
cictikz packages a circuit-schematic TikZ dialect — the ckt_lib
macro vocabulary from the aic2026
course, grid = 1.6, one transistor tall — together with everything an AI
assistant (or a human) needs to draw with it:
pdflatex with pinned
SOURCE_DATE_EPOCH and a source-hashed work directory, so identical
source rebuilds byte-identical PDFs,pip install -e ".[mcp]" # or: make dev-install
cat > amp.tex <<'EOF'
\draw (0,0) \vground \vresistor{$R_s$} \lvnmos{M1}{$v_i$};
\draw (M1.drain) \portOut{$v_o$};
EOF
cictikz render amp.tex --wrap --png # compile, look at amp.png
cictikz watch amp.tex # or: live-reload preview in the browser
Macros are path fragments that compose inside one \draw: each starts
at the current point, draws itself, and leaves the cursor at its exit
point. Transistor instance names become circuitikz nodes, so
(M1.drain) is addressable afterwards. The house rules — one line
width, one arrow tip, colour only when it means something — ship with
the package: cictikz style-guide.
src/cictikz/
render.py pdflatex/pdf2svg/pdftoppm wrappers, wrap_body
symbols.py SymbolRegistry over data/symbols/*.yaml
schematic.py the IR: Schematic/Instance/Wire/Port/Label, infer_nets
writers/tikz.py IR -> dialect TikZ
writers/xschem.py IR -> .sch (lab_pin connectivity, verified pin maps)
writers/xschem_sym.py .sym generation for cictikz-only symbols
readers/tikz.py dialect TikZ -> IR (rejects non-dialect loudly)
readers/xschem.py any .sch -> IR (aliases, .sym geometry, opaque blocks)
watch.py live-preview HTTP server
mcp_server.py FastMCP stdio server
data/tex/ the packaged preamble + 12 macro libraries
data/symbols/ one YAML per symbol (generated, see scripts/)
scripts/
gen_symbols.py regenerates data/symbols/*.yaml
gen_symbol_docs.py regenerates docs/symbols.md + docs/symbols/*.svg
Both data/symbols/ and docs/symbols* are generated — edit the
scripts, not the outputs.
cictikz.tikzplot is the pgfplots generator behind the course’s data
figures: a small Figure/Axes API (no dependencies) that renders
plots with the same preamble as the schematics, so both match on a
page. Scripts call Figure(...), ax.plot(...), fig.save(name);
the output lands in <root>/tikz/<name>.tex, where root is the repo
the symlinked module lives in, or TIKZPLOT_ROOT. The aic2026 course
repo symlinks py/tikzplot.py here, like the tikz/*.tex libraries.