Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Internal architecture

xaligo has one parser/layout/routing pipeline and two supported outputs: SVG and PPTX. Markdown support is a host workflow that embeds SVG artifacts.

.xal source
   -> version dispatch and parser
   -> validated generic concepts and parameters
   -> layout, text measurement, ports, and connector routing
   -> renderer-neutral document/draw plan
   -> SVG encoder
      or
   -> statically linked Rust PPTX exporter

Diagram source: internal-rendering-pipeline.xal

Controllers collect command options and persist returned bytes. They do not parse, lay out, route, or own a second format switch. RenderUsecase owns dispatch and accepts svg and pptx for V1/V2 plus terminal for V2; SVG is the default.

Markdown

xaligo render markdown scans fenced xal blocks, invokes the SVG artifact path for each block, writes one SVG per resolved frame, and replaces the block with image references. The preview server follows the same rule. Markdown does not introduce another geometry model or encoder.

Current V1 compatibility path

The existing V1 frontend still creates an Excalidraw-shaped internal presentation scene before building a draw plan. This is temporary compatibility data only:

  • it is not a supported output format;
  • it has no CLI or browser-WASM render entry point;
  • it is not persisted or edited by a public command; and
  • new public contracts must use renderer-neutral names and types.

The complete document is resolved before frame projection so cross-frame links, obstacles, routing, metadata bands, and source order remain consistent. An identified child frame maps to one SVG artifact or one PPTX slide. With --combine-frames, all frames share one SVG canvas or PPTX slide.

Diagram source: internal-routing-algorithm.xal

PPTX boundary

Go owns semantic interpretation and geometry. It serializes a resolved document plan and invokes the Rust PPTX C ABI in process. The exporter is compiled into the same static library as the Rust engine. The Rust pptx adapter translates plan operations into PPTX bytes; it does not parse .xal or recalculate layout and routing.

V2 engine boundary

The V2 generic calculation core lives in the single Rust staticlib crate at external/engine. Native Go calls its staticlib through C ABI v2 and cgo:

Go use case -> cgo -> C ABI -> Rust staticlib

The Rust source uses the same responsibility structure as ryo-arima/vem/src, adapted for an in-process library rather than a CLI executable:

external/engine/src
├── base.rs       composition root
├── cnf/          ABI constants, limits, and defaults
├── ent/          model, request, and response entities
├── usc/          flat operation, layout_*, routing, and SVG calculation files
├── rep.rs        reserved for future Rust-owned external encoders
├── ctl/          C ABI controller
└── util/         explicit codecs/traits, message codes, logger, and errors

lib.rs only assembles these modules and exports the static-library symbols. Layout, SVG, and FFI are cohesive responsibility files in one crate rather than separately versioned crates.

Requests currently travel ctl -> usc -> ctl; rep is not part of the active calculation path. A future Rust PPTX writer may use rep, but calculation stays in usc. The layer directories remain shallow and responsibility is expressed in filenames rather than deeper directory trees.

As in VEM, engine entities do not use derive or serde annotations to generate their implementations. Explicit standard-trait implementations and bounded little-endian ABI serialization/deserialization live under util. Rust message-code logging follows the Go logger’s XALIGO_LOG_* configuration while defaulting diagnostics to stderr and never terminating the embedding process.

Rust calculates only generic frames, groups, captures, items, ports, text, spacers, and lines. It now resolves nested vertical/horizontal/fixed/flex/grid and absolute layouts, ports, straight/orthogonal routes, and the matching SVG projection. Builtin, AWS, and UML profiles are declarative concept data, defaults, constraints, styles, aliases, icons, and attribution. Profiles cannot register calculation callbacks or output encoders.

The V2 response is an immutable, renderer-neutral ResolvedDocument. ABI input uses contiguous pre-order records and parent indexes rather than JSON or arbitrary maps, preserving unset values separately from explicit zero values. The native V2 and V1 compatibility frontends still need to lower .xal directly to this model; until then, the existing V1 public render path remains independent rather than using a partial conversion.

See V2 Generic Engine for the implemented calculation, validation, ABI, and compatibility contracts.

Project intelligence

RAG and LSP share the constructor-injected project use case. One .xal analysis pass produces diagnostics and generic Frame, Group, Capture, Item, Port, Line, Text, and Spacer symbols for editor and agent requests. Markdown headings and content are indexed in SQLite/FTS5 for durable search.

The initial RAG corpus is intentionally narrower than the analysis service: rag index and rag watch discover only Markdown below docs/. Open or saved .xal documents are explicit editor requests and do not broaden that discovery rule. LSP session state remains in memory; only durable search rows are shared between separately launched xaligo processes.

Assets

Generic icons are built in. AWS and UML icon data remain separable profiles. The SQLite registry owns SVG storage, search, aliases, tags, checksums, and license metadata. The Rust engine receives resolved icon metadata/content and does not access SQLite, repositories, filesystems, or the network.

Deliberately absent outputs

Excalidraw, PDF, Excel/XLSX, XYFlow, and Isoflow encoders, aliases, dependencies, generated assets, and browser globals are retired. Adding a new format requires an explicit product-scope decision; plugins cannot add one.