Author diagrams

Learn the small Schemd grammar

Place nodes, connect named ports, and choose a route or UML relationship.

sheet
2 / 11
rev
v0.2
sections
3
compiled
3

01 / NodesPlace a component on a bounded canvas

Every fence opens with a promise about space: bounds="WIDTHxHEIGHT", both integers from 64 to 4096. The compiler reserves that canvas before reading a single declaration, which is why a schemd diagram never reflows the page it lands on.

A node has one predictable shape:

kind:ID "label" at (x, y) color [options]

IDs are case-sensitive, coordinates live in the viewBox we just declared, and the [options] depend entirely on the kind we chose. The colour is a built-in token such as #blue, a safe CSS colour, or a theme alias we resolve ourselves.

port:VIN "Signal" at (60, 160) #blue
resistor:R1 "10 k\Omega" at (250, 160) #amber
capacitor:C1 "100 nF" at (470, 160) #cyan
port:VOUT "Filtered" at (700, 160) #emerald

VIN.out -> R1.in #blue [line]
R1.out -> C1.in #amber [ortho]
C1.out -> VOUT.in #emerald [line marker-end=arrow]
compiled by @schemd/core → shown in the rail

02 / ConnectionsConnect named ports

A connection is just as small — two named ports and an arrow:

ID.port -> ID.port color [options]

Then choose how the wire travels: line for a straight segment, bezier for a curve, ortho for the obstacle-aware route. An orthogonal connection escapes each component through a short stub, clears every other node's bounds, and — this is the part that matters — fails loudly when no clear path exists rather than drawing a junction that lies about the circuit.

Markers are optional on either end: marker-start=... and marker-end=... accept none, arrow, open-arrow, dot, triangle, diamond, or diamond-filled.

port:A "A" at (60, 90) #blue
port:B "B" at (60, 250) #slate
xor:G1 "Parity" at (390, 170) #cyan [inputs=2 outputs=1]
port:Y "Result" at (720, 170) #emerald

A.out -> G1.in1 #blue [bezier]
B.out -> G1.in2 #slate [ortho]
G1.out -> Y.in #emerald [line marker-end=arrow]
compiled by @schemd/core → shown in the rail

03 / UMLUse relationship names instead of hand-built markers

A UML relationship is nothing more exotic than a connection option: name the relationship and schemd supplies the marker and dash pattern the notation already expects. Disagree with a default and an explicit marker — or a plain solid/dashed flag — overrides it.

Relation Default style
association Solid line
dependency Dashed, open arrow
generalization Hollow triangle at the target
realization Dashed, hollow triangle at the target
aggregation Hollow diamond at the source
composition Filled diamond at the source
message, transition Open arrow
include, extend Dashed, open arrow, automatic label

Add label="text" whenever the connector needs a name of its own.

class:Account "Account" at (220, 150) #slate [attributes="- id: UUID" operations="+ close(): void"]
class:Admin "Admin" at (620, 120) #blue [operations="+ suspend(): void"]
class:Session "Session" at (620, 310) #emerald [attributes="- token: string"]

Admin.left -> Account.right #blue [ortho generalization]
Account.right -> Session.left #emerald [ortho composition label="owns"]
compiled by @schemd/core → shown in the rail