Add an optional ownership-scoped Tectonic environment with secure installation, native compile verification, and topology-preserving repair support. Harden CircuitikZ generation and preview routing, fix the history drawer scroll model, and synchronize bilingual architecture, user guidance, and localized README documentation.
19 KiB
| date | topic |
|---|---|
| 2026-07-05 | circuitikz-figure-generation-roadmap |
circuitikz Figure Generation Roadmap
Language: English | 简体中文
This document records the circuit-diagram extension direction after the Cloudy-style editable figure work and the Drawnix export spike.
The short version: circuit diagrams should not enter Notemd as "LLM writes arbitrary TikZ." The useful target is a constrained CircuitSpec -> circuitikz adapter with golden-reference templates, compile feedback, and screenshot review. That is the only path likely to produce readable CMOS, analog, and digital-circuit figures reliably.
Current Figure Stack
The current diagram work has already moved Notemd away from renderer-specific prompt strings:
| Area | Current state |
|---|---|
| Semantic input | DiagramSpec remains the model-facing boundary for general diagrams. |
| Internal figure model | SemanticFigureModel powers editable HTML/SVG, Draw.io XML, and Drawnix JSON artifact export. |
| Obsidian UI control | Developer settings and the sidebar expose preferredDiagramIntent and preferredDiagramRenderTarget; artifact/preview commands can explicitly select Mermaid, JSON Canvas, Vega-Lite, HTML, or editable HTML/SVG. |
| CLI artifact export | npm run diagram:export-artifact exports editable-html-svg, drawio, and drawnix without Obsidian runtime. |
| Verification | Tests check semantic annotations, visible-label parity, stable IDs, Drawnix subset validity, and CLI file output. |
The render-target override is intentionally scoped to artifact and preview commands. The legacy Mermaid command stays pinned to Mermaid-compatible output, while Draw.io and Drawnix stay CLI/export-boundary targets until plugin-runtime rendering and editing contracts are proven.
This architecture is the right precedent for circuit diagrams: the model should produce structured intent, not raw final syntax, and the UI should select a renderer only after the semantic spec is stable.
Why circuitikz Is Different
circuitikz is the right syntax family for electrical circuits in Obsidian TikZJax, especially when notes need MOSFETs, resistors, supplies, grounds, voltage probes, or analog/digital teaching diagrams.
The hard problem is not syntax availability. The hard problem is layout quality under constraints:
- LLMs can produce a topologically correct circuit that is visually unreadable.
- Anchors such as
M1.G,M1.D, andM1.Sare easy to misuse if the model invents geometry late. - Complex circuits need routing lanes, not ad hoc wire segments.
- TikZJax/LaTeX failures are often compile-log failures, while readability failures require rendered-image inspection.
- A working small example does not generalize to larger CMOS blocks unless the generator owns placement and routing rules.
Recommended Architecture
source note / prompt
-> CircuitSpec
-> topology validation
-> layout projection
-> circuitikz template adapter
-> TikZJax or LaTeX render
-> compile-log + screenshot feedback
-> constrained repair pass
CircuitSpec
CircuitSpec should be separate from DiagramSpec at first. Do not widen DiagramSpec until two or more non-circuit targets need the same fields.
Minimum useful shape:
| Field | Purpose |
|---|---|
circuitKind |
cmos-inverter, common-source, logic-gate, rc-network, etc. |
nodes |
named electrical nets such as VDD, GND, vin, vout, drain, source |
components |
typed parts with ids, terminals, labels, and optional model metadata |
connections |
topology edges between terminals/nets |
layoutHints |
grid positions, orientation, input/output side, routing lanes |
style |
american voltages, label policy, voltage/current marker convention |
goldenReferenceId |
template family used as the visual and syntax baseline |
Golden Reference First
A golden reference is mandatory for reliable circuit generation. It should define:
- the package preamble;
- coordinate scale;
- anchor style;
- component orientation;
- input/output side conventions;
- wire routing pattern;
- label placement rules.
For example, the common-source amplifier reference should keep the working pattern:
\documentclass[border=8pt]{standalone}
\usepackage{circuitikz}
\begin{document}
\begin{circuitikz}[american voltages, line width=0.5pt, font=\small]
\draw
(3,5) node[vcc]{$V_{DD}$}
to [R, l=$R_D$] (3,3);
\draw
(3,3) to [short, *-o] (5,3) node[right]{$v_{out}$};
\draw
(3,3) to [short] (3,2.2)
node[nmos, anchor=D] (M1) {$M_1$};
\draw
(M1.S) to [short] (3,0.5)
node[ground]{};
\draw
(M1.G) to [short, -o] (0.8,2.2)
node[left]{$v_{in}$};
\end{circuitikz}
\end{document}
A CMOS inverter template should then constrain the model explicitly:
pmosabovenmos;VDDabove,GNDbelow;- common input gate routed from the left;
- common drain output routed to the right;
- no diagonal wires;
- named anchors for each transistor terminal.
Validation Strategy
Do not accept "it compiled" as enough.
| Gate | What it catches |
|---|---|
| Spec validation | missing nets, disconnected terminals, impossible terminal references |
| Template validation | missing package preamble, invalid circuit kind, unsupported component |
| Compile-log parsing | LaTeX/TikZJax syntax and package failures |
| Screenshot inspection | overlaps, unreadable labels, bad routing, excessive whitespace |
| Golden-reference diff | drift from known-good orientation and routing conventions |
Screenshot feedback can be manual first. Automated screenshot checks should start with simple rules: nonblank render, bounded canvas, expected labels visible, and no obvious label overlap boxes.
Implementation Phases
| Phase | Scope | Exit criteria |
|---|---|---|
| A. Prompt/runbook | Document constrained circuit prompts and golden references | website and maintainer docs explain circuitikz limits and usage |
B. CircuitSpec prototype |
Add parser/types/tests for simple MOS circuits | common-source and CMOS inverter specs validate without rendering |
| C. circuitikz adapter | Emit deterministic LaTeX for golden templates | generated LaTeX matches stable snapshots and contains required anchors |
| D. render feedback | Add optional local TikZJax/LaTeX smoke path | compile failures return actionable diagnostics |
| E. visual repair loop | Feed rendered image or overlap report back into repair prompt | repeated layout errors are corrected without changing topology |
| F. managed desktop environment | Discover safe local compilers and offer an explicit managed Tectonic install | UI probe/install/remove works, golden fixtures compile, and dependency-free export remains intact |
Implementation Status
Phase A is documented. Phase B/C now have a constrained repository prototype:
src/diagram/adapters/circuitikz/circuitSpec.tsdefines the separate circuit-only spec boundary.src/diagram/adapters/circuitikz/circuitikzExporter.tsvalidates topology and emits deterministiccircuitikzLaTeX forcommon-source-amplifier,cmos-inverter,cmos-buffer/cmos-buffer-v1,cmos-transmission-gate/cmos-transmission-gate-v1,cmos-nand2/cmos-nand2-v1, andcmos-nor2/cmos-nor2-v1. It now projectslayoutHints.inputSideandlayoutHints.outputSideinto constrained port placement for those golden templates, so layout-only repair candidates can move input/output ports without changing topology. The CMOS buffer template locks two cascaded inverter stages through intermediate nodevmid; the CMOS transmission gate template locks parallel PMOS/NMOS pass devices betweenvinandvoutwith complementaryphib/phicontrols; the CMOS NAND template locks the parallel PMOS pull-up network, the series NMOS pull-down stack, and dual input netsva/vbbefore export; the CMOS NOR template locks the complementary series PMOS pull-up stack and parallel NMOS pull-down network before export.src/diagram/adapters/circuitikz/circuitikzExporter.tsnow also exposescreateCircuitTopologySignatureandassertCircuitTopologyUnchangedso topology-preserving repair can reject electrical drift while allowing label and layout changes.scripts/export-circuitikz.jsandnpm run diagram:export-circuitikzprovide the offline export command, including--topology-referencefor repair candidates.src/diagram/adapters/circuitikz/circuitikzRepairBrief.ts,--repair-brief-output, and--repair-briefproduce and consume schemanotemd.circuitikz.repair-brief.v1, a topology-preserving repair handoff that carries the sourceCircuitSpec, topology signature, compile/render diagnostics, allowed changes, prohibited topology changes, next verification steps, and a structuredrepairPrompt. The prompt role istopology-preserving-circuitikz-repair; it includesdiagnosticFocusitems derived from diagnostics andacceptanceCriteriathat require candidate validation plus fresh compile and render-smoke checks. Candidate specs can be checked against the brief signature before output is written, and--repair-briefnow returnsrepairAcceptanceevidence with schemanotemd.circuitikz.repair-acceptance.v1,readyForVisualAcceptance, gate-level status, blocking diagnostics, andremainingChecks.--repair-acceptance-outputcan persist the same evidence as a JSON file for CI or release records.src/diagram/adapters/circuitikz/circuitikzDiagnostics.tsparses existing LaTeX/TikZJax compile logs into actionable diagnostics without spawning a compiler or depending on shell command resolution.src/diagram/adapters/circuitikz/circuitikzCompileRunner.tscan run an explicitly configured local renderer withshell: false, placeholder-expanded arguments, structured executable diagnostics for empty, missing, or invalid renderer commands, generated-log diagnostics, and optional--expected-artifactrender-smoke checks.scripts/run-circuitikz-smoke-fixtures.jsandnpm run diagram:smoke-circuitikznow also produce explicit renderer availability evidence when no renderer is configured. The missing-configuration path still exports the deterministic fixture.texartifacts, returnsok: false, and recordsrendererAvailability.status: "missing-configuration"with acompile-executable-invaliddiagnostic instead of relying on platform shell discovery or silently skipping smoke evidence.src/diagram/adapters/circuitikz/circuitikzRenderSmoke.tsinspects expected render artifacts. PDF and other opaque artifacts are checked for existence/non-empty output; SVG artifacts are additionally checked for an<svg>root, positive dimensions orviewBox, visible drawing elements after hidden/transparent element exclusion, optional repeated--expected-svg-texttokens,render-svg-text-path-only/pathOnlyGlyphUseCountclassification for path-only labels, path-only glyph placement through resolved<use href="#...">geometry, definition-local transforms on reusable glyph paths, path-only glyph overlap diagnostics throughrender-svg-path-glyph-overlap, close-path current-point resets for relative commands afterZ/z, exact arc bounds for A/a arc extrema, exact Bezier curve bounds for C/S/Q/T curve extrema, stroke-width-aware SVG bounds and label overlap checks,polyline/polygondrawing geometry, positionedtspanlabel geometry, bounded-canvas/text-overlap diagnostics, label-vs-drawing overlap diagnostics throughrender-svg-label-overlap, and transform-aware geometry for common group and element transforms; PNG screenshot artifacts are decoded for positive dimensions, non-background pixels, 1/2/4/8-bit indexed-color packed samples with PLTE/tRNS palette data, grayscale/RGB tRNS transparent samples, 1/2/4/8/16-bit grayscale samples, 8/16-bit grayscale-alpha/RGB/RGBA direct samples, foreground bounds,foregroundDensity, edge-touching clipped content throughrender-png-content-clipped, unusually dense foreground blocks throughrender-png-foreground-dense, and format-specificrender-png-unsupportedguidance for Adam7 interlaced PNGs and unsupported indexed-color bit depths.- SVG expected-text smoke now also searches decoded accessibility metadata from
aria-label,<title>, and<desc>. This can prove semantic label identity when a renderer preserves metadata, but it still does not prove path-only visual label legibility without the later OCR/screenshot gate. - SVG positioned text geometry now respects
text-anchorvaluesstart,middle, andendfrom attributes or inline style, so centered and right-aligned labels can trigger text/text and label-vs-drawing overlap diagnostics. - Grouped and
symbolpath-only glyph definitions inside<defs>are now resolved before<use>placement, so wrapped glyph paths still participate inpathOnlyGlyphUseCount, bounded-canvas checks, andrender-svg-path-glyph-overlap. src/rendering/diagnostics.tssummarizesRenderArtifact.diagnosticsinto error/warning/info counts, andsrc/ui/DiagramPreviewModal.tsuses that summary in both the artifact diagnostics panel and preview history entries. Any render target can attach diagnostics toRenderArtifact.diagnostics; the preview UI shows the summary, severity, kind, message, and advice without requiring TikZJax or LaTeX in the plugin runtime.src/tests/circuitikzExporter.test.ts,src/tests/circuitikzRepairBrief.test.ts,src/tests/circuitikzCompileDiagnostics.test.ts,src/tests/circuitikzRenderSmoke.test.ts,src/tests/circuitikzCompileRunner.test.ts, andsrc/tests/circuitikzExportCli.test.tsverify deterministic output, topology rejection, topology-preserving repair brief generation and candidate validation, package-script exposure, UTF-8 BOM handling, diagnostic parsing, shell-free compile execution, structuredcompile-executable-invalid/compile-executable-not-founddiagnostics, diagnostics JSON output, render artifact existence/non-empty smoke checks, SVG structure checks, path-only SVG label classification, path-only glyph placement checks, definition-local glyph transform checks, path-only glyph overlap diagnostics, exact arc bounds for A/a arc extrema, exact Bezier curve bounds for C/S/Q/T curve extrema, stroke-width-aware SVG bounds and label overlap checks,polyline/polygondrawing geometry checks, positionedtspanlabel geometry checks, transform-aware SVG geometry checks, SVG label-vs-drawing overlap checks, PNG blank screenshot checks, indexed-color and grayscale PNG packed sample decoding, indexed-color PNG palette decoding, grayscale/RGB PNG tRNS transparent sample handling, format-specific unsupported PNG diagnostics, 16-bit direct PNG sample normalization, PNG foreground-bound and foreground-density reporting, PNG clipped-content diagnostics, dense-foreground diagnostics, and nonzero CLI exit for logs or smoke reports with errors.src/tests/diagramPreviewModal.test.tsverifies that artifact diagnostics are visible in the diagram preview modal and that preview history does not collapse entries with different diagnostics.src/diagram/adapters/circuitikz/circuitikzRepairLoop.tsnow provides the opt-in Phase E execution boundary. It creates the dedicated repair prompt, accepts only oneCircuitSpecJSON candidate, rejects topology drift before export, evaluates the generated TeX with caller-supplied compile/render evidence, and adopts the candidate only when every acceptance gate passes. The loop is deliberately capped at one attempt and remains disabled when a renderer is unavailable.- The common-source golden template now uses separate terminated draw paths, a lighter
0.5ptstroke, a smaller body font, and no redundant source-terminal annotation. This removes the earlier path crowding and label collision without changing electrical topology. src/tests/circuitikzRepairLoop.test.tscovers successful repair, topology drift, non-JSON output, failed second-pass visual acceptance, and renderer-unavailable fail-closed behavior.src/latexEnvironment/andsrc/platform/desktopProcess.tsimplement Phase F without enlarging the plugin bundle with a TeX distribution. Desktop users can reuse a custom/system compiler or explicitly install pinned Tectonic0.16.9; downloads are HTTPS-host allowlisted, size-bounded, SHA-256 verified, extracted through traversal/link guards, smoke-tested in staging against six deterministic fixtures, and atomically activated with rollback and cancellation cleanup.src/ui/CircuitikzEnvironmentModal.tsexposes probe, install/repair, cancel, remove, capability, progress, and bounded-log states. The module loads desktop execution code lazily; mobile retains dependency-free preview and SVG/PNG/preview-PDF export.- The diagram-history drawer now establishes the Grid minimum-size invariant with
min-height: 0; its body ownsoverflow: autoand contains overscroll, so long Vault histories remain reachable without scrolling the preview behind the drawer.
Phase D now provides actionable compile and artifact diagnostics, including SVG geometry/overlap and PNG nonblank/clipping/density checks. Phase E has a bounded topology-preserving execution loop and still refuses candidates without fresh compile and render-smoke evidence. Phase F adds optional desktop discovery and user-initiated managed installation while keeping the ordinary preview/export path dependency-free. Notemd still does not embed TeX Live, MiKTeX, TinyTeX, or Tectonic archives in main.js. OCR for path-only glyph text, precise pixel-level overlap detection, complete SVG path coverage, and browser-grade text layout remain future evidence improvements.
The SVG geometry smoke also covers SVG number grammar for leading-dot decimals and explicit plus signs. This is a small but important renderer-compatibility gate because dvisvgm can emit compact decimals that should remain fractional during bounds checks.
Best Current Practice
For supported circuit families, use the structured CircuitSpec path:
- Provide a renderable golden reference.
- Ask for a named circuit family, not a vague "draw circuit."
- Lock orientation, anchors, and input/output sides.
- Let the deterministic adapter own LaTeX rather than asking the model for raw TikZ.
- When a local renderer is configured, use compile/render diagnostics for the single guarded repair attempt.
This will outperform unconstrained ChatGPT/Gemini TikZ generation because it limits the model's freedom to the parts that matter: choosing components and topology, not inventing every coordinate and route from scratch.
Risks
- Pulling TikZJax into the plugin runtime would create a hard dependency on another Obsidian plugin. Keep integration optional.
- A generic "TikZ renderer" would be too broad. Start with circuitikz and only a small set of circuit families.
- Visual feedback without topology locking can repair layout by accidentally changing the circuit. The repair prompt must treat topology as invariant.
- circuitikz package versions can vary. Golden references must record the expected package behavior and renderer environment.