EXAMPLES
Recipes
A page for the question "I have this in front of me — how do I write it". Several entries print the cable schedule and the parts list under the drawing, because for those the tables *are* the answer, and the distinction being drawn is invisible without them.
01Plug a camera into a switcher
Declare the sockets, connect them. The smallest complete drawing is this.
Give a device its sockets, then join socket to socket. out SDI : sdi means "there is one output called SDI, and what goes through it is an SDI signal".
device cam "Camera" as camera { out SDI : sdi }
device sw "Switcher" as switcher { in 1 : sdi }
cam.SDI -> sw.1 : sdicam, sw, SDI and 1 are names you choose. camera, switcher and sdi come from a fixed list. Which is which is set out under "Words you choose, words you pick" below.
Cable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| — | Camera | Switcher | SDI | — | — | — |
No length and no cable number were written, so those columns are blank. Saying nothing and saying "not measured yet" are different, and that difference is under "A length nobody has measured yet".
02Write a length, a cable number and a jacket colour
They follow the signal, in that order.
What a run can carry comes in a fixed order: length, "number", [color=…]. Any of them can be left out.
device cam "Camera" as camera { out SDI : sdi }
device sw "Switcher" as switcher { in 1 : sdi out PGM : sdi }
device rec "Recorder" as recorder { in SDI : sdi }
cam.SDI -> sw.1 : sdi 30m "V-01" [color=blue]
sw.PGM -> rec.SDI : sdi 2m "V-10"Cable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| V-01 | Camera | Switcher | SDI | 30m | — | — |
| V-10 | Switcher | Recorder | SDI | 2m | — | — |
The number is what gets read aloud on site, so it is the first column of the schedule. The colour becomes the colour of the line — and theme: mono for printing, which draws the difference with line styles instead.
03A length nobody has measured yet
Write ?m. It means something different from leaving it blank.
Leaving the length off already worked, and the blank it produced meant two things at once: "not measured" and "nobody thought about it". On a list somebody packs a van from, only one of those is a job still to do.
device dk "Desk" as mixer { out L, R, SUB : xlr }
device sp1 "SP1" as speaker { in IN : xlr }
device sp2 "SP2" as speaker { in IN : xlr }
device sub "Sub" as speaker { in IN : xlr }
dk.L -> sp1.IN : xlr 15m "A-01" # 測った
dk.R -> sp2.IN : xlr ?m "A-02" # ケーブルは要る。長さはこれから
dk.SUB -> sub.IN : xlr "A-03" # 長さについて何も言っていないCable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| A-01 | Desk | SP1 | XLR | 15m | — | — |
| A-02 | Desk | SP2 | XLR | ?m | — | — |
| A-03 | Desk | Sub | XLR | — | — | — |
?m prints as ?m. The unit is still written, because which unit it will be measured in is not the open question. ?m, ?ft, and any other unit the language knows.
?m is still a length, and is treated as one. A radio path refuses it, and on an adapter it makes that end a socket (see "A lead, and a thing beside a cable").
04Write many identical runs at once
1..4 in a declaration, (1, 2, 3, 4) in a connection.
Sockets can be declared as a range. in 1..4 : sdi is four inputs. in CH[1..16] : xlr does the same with a prefix.
device sw "Switcher" as switcher { out 1..4 : sdi }
device rec "Recorder" as recorder { in 1..4 : sdi }
sw.(1, 2, 3, 4) -> rec.(1, 2, 3, 4) : sdi 5mCable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| — | Switcher | Recorder | SDI | 5m | — | — |
| — | Switcher | Recorder | SDI | 5m | — | — |
| — | Switcher | Recorder | SDI | 5m | — | — |
| — | Switcher | Recorder | SDI | 5m | — | — |
A connection lists them in brackets. Matching counts pair up in order, and the result is four separate runs — four rows.
A connection will not take sw.(1..4), and that is deliberate. Sockets usually are numbered in a row, so a range earns its place in a declaration. A range in a *connection* means one socket out of step silently wires everything one out of step: the drawing comes out right, the schedules come out right, and nobody finds out until they are plugging it in. Listed out, a count that does not match is visible where it is written.
05One conversion lead does the job (HDMI-DVI and friends)
via on the run. It is one cable, so it is one row.
An HDMI-DVI cable is one unbroken run. Nothing stops in the middle of it. So it is something the run carries, and it is written with via.
device pc "PC" as computer { out HDMI : hdmi }
device mon "Monitor" as display { in DVI : dvi }
pc.HDMI -> mon.DVI : hdmi 2m "V-01" via "HDMI-DVI cable"Cable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| V-01 | PC | Monitor | HDMI | 2m | — | — |
Parts list
(empty)
One cable row, an empty parts list. One object, one row. Written as an adapter it would put a box in the middle of the drawing and turn one cable into what looks like two.
06A lead, and a thing beside a cable (USB-HDMI and friends)
Not the number of ends — which ends are sockets.
A USB-HDMI adapter has two ends and is a junction: the USB tail is moulded on, the HDMI side is a socket, and the cable reaching it is one somebody has to bring. The HDMI-DVI lead above also has two ends, and is one cable. The count cannot tell them apart.
A run is captive unless it carries a length or a cable number. That one rule decides the schedules.
device pc "Laptop" as computer { out USB : usb }
adapter dg "USB-HDMI adapter" { in USB : usb
out HDMI : hdmi }
device pj "Projector" as projector { in HDMI : hdmi }
pc.USB -> dg.USB : usb # 一体。ケーブル表に出ない
dg.HDMI -> pj.HDMI : hdmi 5m "V-01" # ソケット。持っていくケーブル1本Cable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| V-01 | USB-HDMI adapter | Projector | HDMI | 5m | — | — |
Parts list
| Part | Qty | Between |
|---|---|---|
| USB-HDMI adapter | 1 | Laptop / Projector |
Nothing is written on the USB side, so it reads as moulded on and produces no cable row. The HDMI side carries 5m "V-01", so it reads as a socket and produces one cable to bring. The adapter itself is one part. Exactly what has to be in the case, and nothing else.
07A distribution panel, where every socket is a socket
One cable per thing plugged into it.
The same adapter, with sockets all round, needs one cable per socket. The difference from the previous recipe is not how it is written — it is whether each run carries a length and a number.
device dk "Desk" as mixer { out MAIN : xlr }
adapter pp "Distribution panel" { in IN : xlr
out A : xlr
out B : xlr }
device sp1 "SP1" as speaker { in IN : xlr }
device sp2 "SP2" as speaker { in IN : xlr }
dk.MAIN -> pp.IN : xlr 10m "A-01"
pp.A -> sp1.IN : xlr 5m "A-02"
pp.B -> sp2.IN : xlr 5m "A-03"Cable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| A-01 | Desk | Distribution panel | XLR | 10m | — | — |
| A-02 | Distribution panel | SP1 | XLR | 5m | — | — |
| A-03 | Distribution panel | SP2 | XLR | 5m | — | — |
Parts list
| Part | Qty | Between |
|---|---|---|
| Distribution panel | 1 | Desk / SP1 / SP2 |
Three cables and one panel. The rule holds at any number of ends.
08A moulded fan-out lead
Add as cable and it goes on the cable schedule instead of the parts list.
A fan-out whose tails are all moulded is a part and a cable at once. It goes in the van, it gets a number, and the person loading reads the cable schedule. On the parts list alone it is missing from the sheet they read.
device dk "Desk" as mixer { out MAIN : xlr }
adapter fan "XLR 4-way lead" as cable 5m "C-01" {
in IN : xlr
out A : xlr
out B : xlr
}
device sp1 "SP1" as speaker { in IN : xlr }
device sp2 "SP2" as speaker { in IN : xlr }
dk.MAIN -> fan.IN : xlr
fan.A -> sp1.IN : xlr
fan.B -> sp2.IN : xlrCable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| C-01 | XLR 4-way lead | Desk / SP1 / SP2 | XLR | 5m | — | — |
Parts list
(empty)
One object, one row — not one per plug. The far ends are listed together. It leaves the parts list, so it is not counted twice.
as cable takes a length and a cable number, the same ones a run takes. They describe the same thing: a cable somebody has to find, measure and label.
09Split a TRRS into two TRS
Two objects of the same shape. What separates them is whether the runs carry a length.
First as one cable — a headset splitter, where two tails come off the TRRS plug.
device pc "Laptop" as computer { io HS : trrs35 }
adapter sp "TRRS to 2× TRS splitter lead" as cable 0.2m "A-01" {
io IN : trrs35
out MIC : trs35
out HP : trs35
}
device mic "Mic" as microphone { in PLUG : trs35 }
device hp "Headphones" as speaker { in PLUG : trs35 }
pc.HS -> sp.IN : trrs35 # 生えている
sp.MIC -> mic.PLUG : trs35 # 生えている
sp.HP -> hp.PLUG : trs35 # 生えているCable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| A-01 | TRRS to 2× TRS splitter lead | Laptop / Mic / Headphones | TRRS 3.5mm | 0.2m | — | — |
Parts list
(empty)
The runs carry nothing — just : trrs35 and : trs35. No length, no cable number. Writing one makes that end a socket, which means "and a separate cable to reach it". This is one object, so nothing is written. The length and the number go after as cable, once, for the object.
Now the same shape as a splitter with sockets. The declaration is almost identical.
device pc "Laptop" as computer { io HS : trrs35 }
adapter sp "TRRS splitter" {
io IN : trrs35
out MIC : trs35
out HP : trs35
}
device mic "Condenser mic" as microphone { in IN : trs35 }
device amp "Amp" as amplifier { in IN : trs35 }
pc.HS -> sp.IN : trrs35 # 生えている
sp.MIC -> mic.IN : trs35 2m "A-01" # ソケット
sp.HP -> amp.IN : trs35 3m "A-02" # ソケットCable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| A-01 | TRRS splitter | Condenser mic | TRS 3.5mm | 2m | — | — |
| A-02 | TRRS splitter | Amp | TRS 3.5mm | 3m | — | — |
Parts list
| Part | Qty | Between |
|---|---|---|
| TRRS splitter | 1 | Laptop / Condenser mic / Amp |
| One cable | A splitter | |
|---|---|---|
as cable "A-01" | yes | no |
| Length/number on each run | no | yes |
| Cable schedule | 1 row | 2 rows |
| Parts list | empty | 1 |
Two changes, and that is all. Neither writes anything on the PC side, so in both readings the TRRS plug is moulded on — which is why the laptop appears among what the splitter reaches on the parts list.
The decision on site is only this: does something plug into that end. If it does, give the run a length or a number. If it does not, write neither.
10A radio mic
A wireless signal type draws as a wave, not a line.
A wireless type such as uhf has no connector, and takes no length. It takes a channel instead, written [ch=…].
device mic "Wireless mic" as microphone { out RF : uhf }
device rx "Receiver" as interface {
in RF : uhf
out CH1 : xlr
}
device desk "Desk" as mixer { in CH1 : xlr }
mic.RF -> rx.RF : uhf [ch=38]
rx.CH1 -> desk.CH1 : xlr 3m "A-01"Cable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| A-01 | Receiver | Desk | XLR | 3m | — | — |
Wireless schedule
| No. | From | To | Signal | Over | Channel |
|---|---|---|---|---|---|
| — | Wireless mic | Receiver | Wireless (UHF) | — | ch 38 |
Two sheets. The cable schedule has only the XLR from receiver to desk; the hop through the air is on the wireless one. A row with no length, no connector and nothing to coil, sitting among the cables, reads as a cable nobody measured.
The two are read by different people looking for different things: enough cable to reach, against two paths on one channel.
11A signal riding on something else — NDI over Wi-Fi
over separates the payload from what carries it.
NDI is video, but what flows is Ethernet — or, over Wi-Fi, radio. The drawing is about the NDI; the physics belongs to the Ethernet or the Wi-Fi. over keeps the two apart.
device cam "Roving camera" as camera { out WIFI : ndi }
device ap "Access point" as router { io WIFI : ndi
out LAN : ndi }
device pc "Recording PC" as recorder { in LAN : ndi }
cam.WIFI -> ap.WIFI : ndi over wifi [ch=36]
ap.LAN -> pc.LAN : ndi over lan 20m "N-01"Cable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| N-01 | Access point | Recording PC | NDI | 20m | — | — |
Wireless schedule
| No. | From | To | Signal | Over | Channel |
|---|---|---|---|---|---|
| — | Roving camera | Access point | NDI | Wi-Fi | ch 36 |
The carrier decides the physics — and here the same NDI has landed on two different sheets. The over wifi hop is on the wireless one, with no connector and a channel. The over lan run is on the cable one, RJ45 with a length and a number. One payload, sorted by what carries it, which is over working exactly as it says.
The over column reads Wi-Fi: the name belongs to the payload and the frequency to the carrier, which is why they are separate columns. In the radio mic above that column was empty — uhf is its own carrier, and "riding on itself" is not worth writing down.
Without over, a signal is its own carrier and everything behaves exactly as before.
12Dante and NDI sharing one network
Same carrier, different payloads, different lines.
What rides on a given Cat cable is a separate concern on site. Written with over, the same RJ45 reads as two distinct systems on the drawing.
device dk "Desk" as mixer { io DANTE : dante }
device sw "L2 switch" as router { io 1 : dante io 2 : ndi }
device pc "Streaming PC" as computer { io LAN : ndi }
dk.DANTE -> sw.1 : dante over lan 15m "N-01"
sw.2 -> pc.LAN : ndi over lan 10m "N-02"Cable schedule
| No. | From | To | Signal | Length | Source end | Far end |
|---|---|---|---|---|---|---|
| N-01 | Desk | L2 switch | Dante | 15m | — | — |
| N-02 | L2 switch | Streaming PC | NDI | 10m | — | — |
13Group things by where they are
group boxes them, and the drawing boxes them too.
Stage, rack, control room. Things kept in different places should be drawn in different places, which is what group is for.
diagram "House" { direction: LR }
group stage "Stage" {
device cam1 "FX3" as camera { out SDI : sdi }
device mic1 "SM58" as microphone { out OUT : xlr }
}
group rack "Rack" {
device sw "ATEM" as switcher { in 1..2 : sdi out PGM : sdi }
device mixer "DM3" as mixer { in CH[1..2] : xlr out L, R : xlr }
}
cam1.SDI -> sw.1 : sdi 30m "V-01"
mic1.OUT -> mixer.CH1 : xlr 20m "A-01"Equipment list
| Device | Kind | Location | Ports |
|---|---|---|---|
| FX3 | camera | Stage | 1 |
| SM58 | microphone | Stage | 1 |
| ATEM | switcher | Rack | 3 |
| DM3 | mixer | Rack | 4 |
The group becomes a column on the equipment list. diagram "House" { direction: LR } turns the drawing.
14Break up a row of sockets
gap is the blank space on the real panel.
Real panels have breaks in them. A drawing laid out differently makes the person holding it miscount. gap is that blank space; gap 2 leaves two.
device sw "ATEM Mini Extreme" as switcher {
in 1..4 : hdmi
gap
in 5..8 : sdi
gap 2
in AUDIO_L, AUDIO_R : trs
out PGM : sdi
gap
out STREAM : lan
}15Several of the same device
Write it once as a model, call it with from.
Two identical desks do not need their socket lists written twice. Put it in a model and call it with device … from …. Only the name has to change.
model dm3 "Yamaha DM3" as mixer {
in CH[1..16] : xlr
out L, R : xlr
@vendor "Yamaha"
}
device foh from dm3
device mon from dm3 "Monitor desk"Notes like @vendor "Yamaha" come along with it, and appear on the equipment list.
16Have the wrong pairings found for you
Things that fit and still do not work.
Fitting and working are different. HDBaseT uses Cat cable and RJ45 but is not Ethernet, so it does not go into a switch. SDI and a reference input share BNC, but video will not lock a genlock.
device ext "HDBaseT receiver" as interface { out CAT : hdbaset }
device netsw "L2 switch" as router { in 1 : lan }
device cam "Camera" as camera { out SDI : sdi }
device fs "Frame synchroniser" as generic { in REF : genlock }
ext.CAT -> netsw.1 : hdbaset 20m "N-01"
cam.SDI -> fs.REF : sdi 5m "V-90"- warning
signal-mismatchext.CAT → netsw.1: HDBaseT uses Cat cable and RJ45 but is not Ethernet. It does not go into a switch - warning
signal-mismatchcam.SDI → fs.REF: They only share BNC. A reference input will not lock to video
That is what building this page actually printed. Warnings do not fail a build by default; --strict makes them.
17Print it in black and white
theme: mono draws the difference with line styles.
The copy that goes on site is often monochrome. A drawing that separates its runs by colour alone stops being readable the moment it is printed.
diagram "For monochrome printing" { theme: mono }
device cam "Camera" as camera { out SDI : sdi }
device sw "Switcher" as switcher { in 1 : sdi out PGM : sdi }
device rec "Recorder" as recorder { in SDI : sdi }
cam.SDI -> sw.1 : sdi 30m "V-01" [color=blue]
sw.PGM -> rec.SDI : sdi 2m "V-10"[color=blue] can stay exactly where it is. Under mono it becomes a line style instead. The themes are:
lightdarkmonoblueprint18Words you choose, words you pick
Names are yours; kinds and signal types come from a list.
Which words are free and which are fixed is a fair thing to find unclear. There is one dividing line. A word that names something in your show is yours; a word the language has to understand comes from a list.
| Where it goes | Which | For example |
|---|---|---|
Device id (after device) | Yours | cam1 foh sw |
Display name ("…") | Yours | "FX3" "Monitor desk" |
| Port names | Yours | SDI 1..4 CH[1..16] |
Cable number ("…") | Yours | "V-01" "A-12" |
Notes (@…) | Yours | @vendor "Yamaha" |
Device kind (as …) | From a list | camera mixer router |
Signal type (: …) | From a list | sdi xlr dante |
| Units | From a list | m cm ft |
Colours ([color=…]) | From a list | blue 青 |
| Themes | From a list | light mono |
A signal type that is not on the list can be defined with signal. The list is not closed. Everything below is read out of the published package rather than copied by hand.
Device kinds — what follows as.
cameraswitchermixerrecorderplayerdisplayprojectorspeakermicrophoneamplifiercomputerconvertertransmitterreceivermatrixpatchbayrouterinterfacegenericUnits
mmcmminftColours — either spelling works.
red赤blue青green緑yellow黄orange橙purple紫black黒white白graygrey灰brown茶pink桃Signal types — what follows :, with their connectors. No connector means it is a radio path.
Video
componentComponentBNC / RCAcompositeCompositeBNC / RCAdpDisplayPortDisplayPort / DisplayPort MinidviDVIDVI-D / DVI-IfiberFiberLC / SC / OpticalCONhdbasetHDBaseTRJ45hdmiHDMIHDMI / HDMI Mini / HDMI MicrondiNDIRJ45sdiSDIBNC / DIN 1.0/2.3st2110ST 2110RJ45 / SFPvgaVGAD-sub 15wireless-videoWireless videono connectorAudio
adatADATTOSLINKaesAES/EBUXLR / BNCdanteDanteRJ45iemIEMno connectormadiMADIBNC / SCopticalOpticalTOSLINKrcaRCARCAspdifS/PDIFRCA / TOSLINKspeakonSpeakonNL4 / NL8trrsTRRS 1/4"TRRS 1/4"trrs35TRRS 3.5mmTRRS 3.5mmtrsTRS 1/4"TRS 1/4"trs35TRS 3.5mmTRS 3.5mmuhfWireless (UHF)no connectorxlrXLRXLR-M / XLR-F / Mini XLR-M / Mini XLR-F / Mini XLR-4M / Mini XLR-4FControl
dmxDMXXLR-5 / XLR-3gpioGPIOTerminal / D-subirIRno connectormidiMIDIDIN-5 / TRS 3.5mmrs232RS-232D-sub 9rs422RS-422D-sub 9rs485RS-485D-sub 9 / XLRwireless-dmxWireless DMXno connectorNetwork
bluetoothBluetoothno connectorlanLANRJ45usbUSBUSB-A / USB-B / USB-C / USB Micro-B / USB Mini-BwifiWi-Fino connectorPower
acACIEC C13 / IEC C14 / NEMAdcDCBarrel / XLR-4poePoERJ45usbpdUSB PDUSB-CSync
genlockGenlockBNCtimecodeTimecodeBNC / XLRwordclockWord ClockBNCGeneric
generic