figdown 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,60 @@
1
+ # Genre `block` — markers and zones (EXPERIMENTAL)
2
+
3
+ `threshold` and `band` are **outside the v0.1 conformance surface and outside
4
+ the compatibility promise**. The engine accepts them and your document keeps
5
+ working, but they may change or be withdrawn in a later `0.x`. The parser
6
+ emits no warning, so a line that parses tells you nothing. Use them when the
7
+ figure genuinely needs them; if the figure must be portable, do not, and if
8
+ you use one anyway, say so beside the figure.
9
+
10
+ **Both belong to `block` alone.** They are declared by this genre and by no
11
+ other: writing either under `topology`, `flowchart` or `statechart` is a line
12
+ error that says so and gives the ground. `block` earns them because it is the
13
+ genre those figures are actually authored in; a state's box, a flowchart
14
+ stage's box and a device's box have no extent that means anything, so a line
15
+ drawn 60% down one asserts nothing a reader can read.
16
+
17
+ Load `../scene.md` first — this file adds two words to `block`'s vocabulary
18
+ and changes none of it.
19
+
20
+ ```figdown
21
+ figdown 0.1 block
22
+ group pool "Storage pool"
23
+ node used "In use" in=pool
24
+ threshold "High watermark = stop writes" in=pool offset=80%
25
+ threshold "Low watermark = resume writes" in=pool offset=45%
26
+ band "Reserved" 15% in=pool fill=#fee2e2
27
+ band "Shared quota" 20..70% in=pool extend=down
28
+ ```
29
+
30
+ - `threshold` needs a quoted label **and** `offset=<0..100>%`, both mandatory
31
+ — the `%` included. There is no `value=` and no `ref=`.
32
+ - `band` needs a quoted label **first**, then either one percentage (a size)
33
+ or an explicit `<a>..<b>%` range. `..` is the language's ONE range
34
+ separator; the hyphen form is a line error. `extend=up|down|left|right`, and `up`
35
+ is the default.
36
+ - Both attach to a node or a group via `in=`.
37
+ - **Attach at the scope the fact belongs to.** A limit shared by everything in
38
+ a group is one group-level marker; a fact true of one element attaches to
39
+ that element. The renderer may draw the two the same way — the difference is
40
+ in the text, and the text is the knowledge.
41
+
42
+ ## The label is the knowledge, and `offset=` is not a value
43
+
44
+ `offset=` is a fraction of the target's **rendered extent** — where to paint
45
+ the line — **not a value of any quantity**. The target declares no scale, so
46
+ there is no conversion and nothing to convert. Put the number in the label or
47
+ it is not in the document.
48
+
49
+ **This is the trap, and it is worth naming.** In the domain these figures
50
+ usually come from, a threshold is a queue depth **with a numeric value**: an
51
+ active-queue-management minimum and maximum threshold (RFC 2309, RFC 7567)
52
+ is a number of packets or bytes. FigDown borrowed the word from exactly that
53
+ domain and did **not** borrow the attribute the domain defines it by. So
54
+ `threshold "Max cap" in=q offset=80%` invites a reader to take 80% as the
55
+ threshold value. It is a paint position. Write
56
+ `threshold "Max cap = 800 KB" in=q offset=80%` and the figure says what you
57
+ mean.
58
+
59
+ The same holds for `band`: a band is a range over that same scale-free
60
+ extent. Its label is the whole of what it asserts.
@@ -0,0 +1,32 @@
1
+ # Charts from a table — `chart`, `type=` (EXPERIMENTAL)
2
+
3
+ Outside the v0.1 conformance surface and outside the compatibility promise:
4
+ the engine accepts it, but it may change or be withdrawn in a later `0.x`,
5
+ and the parser emits no warning. If the figure must be portable, keep the
6
+ table and drop the chart.
7
+
8
+ **`chart` is composition, not subject vocabulary.** It says nothing about
9
+ what the figure is *of*, so it is not one of the words a genre declares for
10
+ its own domain — it is legal wherever a `table` region is legal, which is the
11
+ `table` genre and every scene genre, and it means the same thing in all of
12
+ them.
13
+
14
+ ```figdown
15
+ figdown 0.1 table
16
+ table t "Throughput"
17
+ | Port | Gbps |
18
+ |------|------|
19
+ | 1 | 25 |
20
+ | 2 | 40 |
21
+ chart t type=bar3d
22
+ ```
23
+
24
+ - `chart <table-id>` is the whole grammar. It draws from a `table` declared
25
+ in the same document and is defined by that reference, so the id must
26
+ already exist.
27
+ - `type=` is the only option key and `bar3d` is its only value.
28
+ - A scene document can carry both halves: open a `table` region inside it for
29
+ the numbers, then `chart` that id.
30
+
31
+ For anything a chart library would do better, keep the raster and put the
32
+ numbers in a table (`../transcribe.md`).
@@ -1,15 +1,27 @@
1
- # Genre `flowchart` — EXPERIMENTAL / EXPERIMENTAL
1
+ # Genre `flowchart` — EXPERIMENTAL
2
2
 
3
3
  The genre itself is outside the v0.1 conformance surface: it may change or be
4
- withdrawn in a later `0.x`. A portable figure uses `block` instead.
5
-
6
- Load `../scene.md` first — `flowchart` reuses the scene vocabulary
7
- (`node`, `group`, `external`, `flow`, `rank`) with the same meanings, and adds
8
- the three role keywords below. `flow down` is the default here.
9
-
10
- **Under `figdown 0.2` the connector is `flowline`, not `edge`** — ISO 5807's
11
- own word for a flowchart's connecting line. Same operators, same labels, same
12
- option keys, same model; only the word changed.
4
+ withdrawn in a later `0.x` without a migration entry. A portable figure uses
5
+ `block` instead.
6
+
7
+ Use `flowchart` when the figure is a **procedure**: stages performed in
8
+ order, with branches. `flow down` is the default here.
9
+
10
+ **This file is `flowchart`'s whole vocabulary.** Load it and `../layout.md`
11
+ and you can author in this genre; do not load another genre's file, because
12
+ another genre's declaration of a word is not authority for this one. In
13
+ particular this genre declares **no container**: there is no `group`, and
14
+ `in=` and `gap=` are **not this genre's option keys** — `in=` named a `group`
15
+ id and nothing else, so it went out with `group` rather than stay accepted with
16
+ no value that could resolve. Writing either is a line error that names the
17
+ withdrawal. Say what a container would have said with a `class`
18
+ whose label states it — it earns a legend entry and applies to every member at
19
+ once — or split the procedure into two figures joined by `external` endpoints.
20
+
21
+ **Under `figdown 0.2` the connector is `flowline`, not `edge`** — the word the
22
+ flowchart domain commonly uses for the symbol ISO 5807 §9.3.1 names *Line*.
23
+ Same operators, same labels, same option keys, same model; only the word
24
+ changed.
13
25
 
14
26
  **The spelling is gated by the version you declare.** Under
15
27
  `figdown 0.1 flowchart`, `edge` is still the word and `flowline` is a line
@@ -95,3 +107,78 @@ spelling, and only you know which one you did.
95
107
  figure the reader has to guess at.
96
108
 
97
109
  **There is no loop keyword.** A plain back-edge *is* the loop.
110
+
111
+ ## `external` — the boundary, which is not the `terminator`
112
+
113
+ ```figdown
114
+ figdown 0.2 flowchart
115
+ flow down
116
+ external ingress "Frame arrives on a port"
117
+ terminator start "Begin lookup"
118
+ process lookup "Look up destination"
119
+ external egress "Frame leaves the switch"
120
+ flowline ingress -> start
121
+ flowline start -> lookup
122
+ flowline lookup -> egress
123
+ ```
124
+
125
+ `external` is an **out-of-figure endpoint**: the procedure connects to it and
126
+ this figure does not describe it. It is **never drawn** — the flowline simply
127
+ ends open — and it takes **no option key at all**. `terminator` is the
128
+ opposite: a drawn stage of this procedure, its start or its end.
129
+
130
+ So the question to ask is *whose* start it is. The first box of **this**
131
+ procedure is a `terminator`. A step that belongs to some other procedure, or
132
+ to the world outside the figure, is an `external`.
133
+
134
+ ISO 5807 §9.4.2 names this concept — its **Terminator** symbol is "an exit
135
+ to, or an entry from, the outside world" — and this genre already spells that
136
+ word `terminator` for the drawn start/end symbol, so the ISO term is taken
137
+ and `external` keeps FigDown's own spelling. Note what follows: ISO has no
138
+ word at all for a boundary that is *never drawn*, which is what `external`
139
+ is. The spelling is FigDown's, not ISO's, and this file is the only place
140
+ that says so.
141
+
142
+ ## Presentation, layout intent and quoting
143
+
144
+ `flow` takes `flow right|down|left|up` — one of the four, once per document,
145
+ before the stages. `flow down` is this genre's default. `rank a,b,c` pulls
146
+ peers onto one row or column: ONE comma-delimited token, no spaces.
147
+
148
+ Values from a fixed list are written **bare**, never quoted: `shape=box`,
149
+ `style=dashed`, `flow down`. So are ids. Labels always take quotes.
150
+
151
+ `shape=` is pure geometry — `shape=box` (the default), `shape=rounded`,
152
+ `shape=circle`, `shape=ellipse`, `shape=diamond`, `shape=cylinder`, and
153
+ nothing else. `style=` takes `style=solid`, `style=dashed` or `style=dotted`.
154
+
155
+ `class` declares what a colour **means**, and colour that means something
156
+ must be a `class`:
157
+
158
+ ```figdown
159
+ figdown 0.2 flowchart
160
+ class yes "Yes path" stroke=#16a34a
161
+ class no "No path" stroke=#dc2626
162
+ decision check "Valid?"
163
+ process accept "Accept"
164
+ process reject "Reject"
165
+ flowline check -> accept class=yes
166
+ flowline check -> reject class=no
167
+ ```
168
+
169
+ A class a flowline joins MUST declare `stroke=` or `style=`; a `fill=`-only
170
+ class joined by one is an error naming `stroke=`. `fill=` and `stroke=` are
171
+ legal on any drawn element, but a flowline has no interior, so `fill=` on one
172
+ is an error.
173
+
174
+ The connector's operators are `->`, `<-`, `--` and `<->`. In a procedure you
175
+ almost always want `->`: a step follows another step in one direction, and an
176
+ undirected or two-way flowline asserts an order the reader cannot recover.
177
+
178
+ Endpoint labels nest (`flowline a [retry 1] -- b`); quote them when they hold
179
+ a line break or an unbalanced bracket. A `#` inside a bracket label is
180
+ ordinary text and needs no quotes, because `[ ]` is a verbatim region.
181
+
182
+ Under `figdown 0.3` any of these lines may carry `note=`, a drawn aside in
183
+ prose: `process parse "Parse body" note="…"`. It is never parsable and never
184
+ where a structural fact lives.
@@ -1,4 +1,4 @@
1
- # Genre `statechart` — EXPERIMENTAL / EXPERIMENTAL
1
+ # Genre `statechart` — EXPERIMENTAL
2
2
 
3
3
  The genre itself is outside the conformance surface: it may change or be
4
4
  **withdrawn** in a later `0.x` without a migration. A portable figure uses
@@ -9,12 +9,45 @@ The genre itself is outside the conformance surface: it may change or be
9
9
  error, and a deliberately named one: `genre "statechart" requires figdown 0.2`.
10
10
  An engine may not read a `0.1` document as though it were `0.2`.
11
11
 
12
- Load `../scene.md` first `statechart` reuses the scene vocabulary
13
- (`group`, `external`, `class`, `flow`, `rank`) with the same meanings, and
14
- **renames the other two**: a node is a **`state`** and a connector is a
15
- **`transition`**, both taken from OMG UML 2.5.1 §14. Nothing else changes
16
- same option keys, same id space, same operators, same model and `node` or
17
- `edge` here is a **line error** naming the word to write instead.
12
+ ## The vocabulary, which is two words
13
+
14
+ **This file is `statechart`'s whole vocabulary.** Load it and `../layout.md`
15
+ and you can author in this genre; do not load another genre's file, because
16
+ another genre's declaration of a word is not authority for this one.
17
+
18
+ This genre declares **two** words of its own — a node is a **`state`** and a
19
+ connector is a **`transition`**, both taken from OMG UML 2.5.1 §14 — and
20
+ **that is the entire list**. It names no container, no boundary, no marker,
21
+ no band and no bundle. Writing one of those here is a line error that states
22
+ the ground rather than guessing at a spelling, and `node` or `edge` here is a
23
+ line error naming the word to write instead.
24
+
25
+ Three more words are legal because they are not about states at all:
26
+ `class` (what a colour means), `flow` and `rank` (layout intent). Nothing in
27
+ UML competes for them.
28
+
29
+ Two consequences worth stating, because an author arriving from another genre
30
+ will reach for both:
31
+
32
+ - **There is no grouping construct.** `in=` and `gap=` are **not this genre's
33
+ option keys** — writing either is a line error that names the withdrawal.
34
+ A composite state, a region and a history are things this genre cannot
35
+ express; a `class` can say two states share a mode, and that is a different
36
+ and weaker claim. Do not fake a superstate. **`in=`'s spelling is RESERVED
37
+ here**: if composite states are ever earned, they arrive as nesting on
38
+ `state` through this exact key, with a `state` id as its value (UML 2.5.1
39
+ §14.2.3.4) — which is why the key was withdrawn rather than left pointing at
40
+ a container.
41
+ - **There is no out-of-figure endpoint.** A transition to something the
42
+ figure does not describe has no spelling. Draw the state, or leave the
43
+ transition out and say so in the prose beside the figure.
44
+
45
+ **`external` in particular is not available, and it is reserved.** UML 2.5.1
46
+ §14 already defines `TransitionKind` as `external | internal | local`, where
47
+ an *external* transition is one that exits and re-enters its source state,
48
+ firing its exit and entry behaviours. That is a defined term of art in this
49
+ genre's own source standard. If `external` ever appears in `statechart` it
50
+ will mean what UML means by it, never "an endpoint outside the figure".
18
51
 
19
52
  `flow right` is the default, as in `block`; `flowchart`'s `down` default does
20
53
  **not** apply here.
@@ -38,6 +71,19 @@ transition locked -[push]-> locked # self-transition: the event happens
38
71
  flow right
39
72
  ```
40
73
 
74
+ `flow` takes `flow right|down|left|up` — one of the four, once per document.
75
+ `rank a,b` pulls peers onto one row or column: ONE comma-delimited token, no
76
+ spaces. Values from a fixed list are bare (`shape=box`, `style=dashed`,
77
+ `flow right`); labels always take quotes.
78
+
79
+ `shape=` is pure geometry and changes only the drawing — `shape=box` (the
80
+ default), `shape=rounded`, `shape=circle`, `shape=ellipse`, `shape=diamond`,
81
+ `shape=cylinder`. `style=` takes `style=solid`, `style=dashed` or
82
+ `style=dotted`. A class a transition joins MUST declare `stroke=` or
83
+ `style=`; `fill=` on a transition is an error, because a line has no
84
+ interior. Under `figdown 0.3` a line may carry `note=`, a drawn aside in
85
+ prose — never parsable, never where a structural fact lives.
86
+
41
87
  ## What the genre adds, which is a reading and not a syntax
42
88
 
43
89
  Everything above parses identically under `block`. The genre earns its
@@ -74,8 +120,8 @@ existence in what you are entitled to conclude from it.
74
120
  as initial is inventing a fact.
75
121
  - **No ordering among transitions.** Peer edges have no sequence, and an
76
122
  ordinal in a label is naming, not order.
77
- - **No hierarchy, no regions, no history.** A `group` groups; it does not
78
- make a superstate.
123
+ - **No hierarchy, no regions, no history.** There is no grouping construct to
124
+ misuse for one.
79
125
  - **Nothing from the layout zone.** `pin` is arrangement for humans; skip it.
80
126
 
81
127
  **Reclassifying costs more than one line now.** Changing `flowchart` to
@@ -1,4 +1,4 @@
1
- # Genre `timing` — EXPERIMENTAL / EXPERIMENTAL
1
+ # Genre `timing` — EXPERIMENTAL
2
2
 
3
3
  The genre itself is outside the v0.1 conformance surface: it may change or be
4
4
  withdrawn in a later `0.x`. There is no portable alternative — a waveform
@@ -1,38 +1,164 @@
1
- # Genre `topology` — EXPERIMENTAL / EXPERIMENTAL
1
+ # Genre `topology` — EXPERIMENTAL
2
2
 
3
3
  The genre itself is outside the v0.1 conformance surface: it may change or be
4
- withdrawn in a later `0.x`. A portable figure uses `block` instead — the
5
- vocabulary is identical, the defaults are identical, and `block` is inside
6
- the compatibility promise.
4
+ withdrawn in a later `0.x` without a migration entry. A portable figure uses
5
+ `block` instead, which is inside the compatibility promise.
7
6
 
8
- Load `../scene.md` first. `topology` adds **no keyword of its own and changes
9
- no default**: it is the scene vocabulary under a name that says the figure is
10
- a network of peers rather than a pipeline of stages. What it carries is the
11
- intent which matters to a reader and to nothing else.
7
+ Use `topology` when the figure is a **network of devices and the links
8
+ between them** fabrics, overlays, access layers, peering diagrams. The
9
+ nodes are devices or endpoints and the edges are physical or logical links,
10
+ not dataflow steps. That intent is what the genre carries; it matters to a
11
+ reader and to nothing else.
12
+
13
+ **This file is `topology`'s whole vocabulary.** Load it and `../layout.md`
14
+ and you can author in this genre; do not load another genre's file, because
15
+ another genre's declaration of a word is not authority for this one. Words
16
+ `topology` does **not** declare — and there are several a `block` author
17
+ would reach for — are line errors that say so and give the ground.
18
+
19
+ ## The vocabulary, in one figure
12
20
 
13
21
  ```figdown
14
22
  figdown 0.1 topology
15
23
  title "Leaf-spine fabric"
16
- flow right
24
+
25
+ flow right # reading direction; ONE per document,
26
+ # before the nodes
27
+
17
28
  node s1 "Spine 1"
18
29
  node s2 "Spine 2"
19
- group pod "Pod A"
20
- node l1 "Leaf 1" in=pod
21
- node l2 "Leaf 2" in=pod
22
- external wan "To WAN"
23
- edge l1 -- s1
30
+
31
+ group pod "Pod A" gap=0 # a container; gap=0 packs its members
32
+ node l1 "Leaf 1" in=pod # flush against each other. The id is
33
+ node l2 "Leaf 2" in=pod # required and exists only so other lines
34
+ # can name it
35
+
36
+ node fw "Firewall" shape=rounded
37
+ node store "Config store" shape=cylinder style=solid
38
+
39
+ external wan "To WAN" # outside the figure. NEVER drawn as a
40
+ # shape — the link simply ends open there
41
+
42
+ edge l1 -- s1 # ops: -> <- -- <->
24
43
  edge l1 -- s2
25
44
  edge l2 -- s1
26
45
  edge l2 -- s2
27
- edge s1 -- wan
28
- class uplink "40G uplink" stroke=#0284c7
46
+ edge s1 -> wan # arrow points at `wan`
47
+ edge wan <- s2
48
+ edge fw <-> store
49
+ edge l1 -[lacp]-> fw # on-line label splits the operator
50
+ edge l2 [ge-0/0/1] -- [xe-0/0/0] fw # endpoint labels: ports, roles
51
+ edge s1 -- s2 style=dotted # spines not cabled to each other
52
+
53
+ rank l1,l2 # pull peers onto one row/column. ONE
54
+ # comma-delimited token, no spaces
55
+
56
+ class uplink "Uplink, 40G" stroke=#0284c7
29
57
  edge l2 -- s2 class=uplink
58
+
59
+ bundle lag1 "LAG to the leaf pair" l1--s1,l2--s1
60
+ ```
61
+
62
+ `flow` takes `flow right|down|left|up` — one of the four, once per document.
63
+
64
+ Values from a fixed list are written **bare**, never quoted: `shape=box`,
65
+ `style=dashed`, `flow down`, `gap=0`. So are ids. Labels are the opposite
66
+ and always take quotes.
67
+
68
+ `shape=` is **pure geometry, no domain nouns** — `shape=box` (the default),
69
+ `shape=rounded`, `shape=circle`, `shape=ellipse`, `shape=diamond`,
70
+ `shape=cylinder`, and nothing else. There is no router symbol, no switch
71
+ symbol and no cloud: a cloud in a source drawing is an ellipse or a group,
72
+ with what it *is* — "the internet", "the transit provider" — written in the
73
+ label. `style=` takes `style=solid`, `style=dashed` or `style=dotted`.
74
+
75
+ `class` declares what a colour **means** and is the only way to make colour
76
+ carry meaning; a class an edge joins MUST declare `stroke=` or `style=`, and
77
+ a `fill=`-only class joined by an edge is an error naming `stroke=`. `fill=`
78
+ and `stroke=` are legal on any element, but an `edge` has no interior, so
79
+ `fill=` on one is an error.
80
+
81
+ Endpoint labels nest (`edge a [xe-0/0/0:1] -- b`); quote them when they hold
82
+ a line break or an unbalanced bracket (`edge a ["slot\n1/1"] -- b`). A `#`
83
+ inside a bracket label is ordinary text and needs no quotes —
84
+ `edge a -[hop #1]-> b` — because `[ ]` is a verbatim region.
85
+
86
+ Under `figdown 0.3` any of these lines may carry `note=`, a drawn aside in
87
+ prose: `node s1 "Spine 1" note="…"`, `edge l1 -- s1 note="…"`,
88
+ `title "Fabric" note="…"`. It is never parsable and never where a structural
89
+ fact lives.
90
+
91
+ ## `group` is not a multicast group
92
+
93
+ `group` here is a **container**: a box drawn round its members, one nesting
94
+ level deep — a pod, a rack, a site, a tenant. It is not IGMP or MLD
95
+ membership, and `group g "224.0.0.5"` does not say what a reader of that
96
+ address expects.
97
+
98
+ The spelling stays anyway, because in this domain every synonym is more
99
+ taken than the word is: `zone` belongs to DNS and to firewalls, `cluster` to
100
+ route reflection (RFC 4456), `domain` to inter-domain traffic engineering
101
+ (RFC 7926), `area` to OSPF, `site` to EVPN. Trading a soft collision for a
102
+ hard one is a bad trade — and this collision **is** soft, because the drawing
103
+ contradicts the wrong reading: a multicast group is never drawn as a box
104
+ round its members.
105
+
106
+ ## `external` is not an external route
107
+
108
+ `external` is an **out-of-figure endpoint**: something this figure talks to
109
+ but does not describe. It is never drawn, it takes **no option key at all**,
110
+ and the link to it simply ends open.
111
+
112
+ It is not an external route — not an OSPF Type 5 or Type 7 LSA, not an eBGP
113
+ peer, not "the external interface". Same soft collision, same reason for
114
+ keeping the spelling: an `external` is never drawn at all, so a reader who
115
+ starts with the routing sense finds nothing on the page to sustain it. Where
116
+ the figure means *the router that faces outside*, that router is a `node`
117
+ with a label saying so; `external` is for what the figure leaves out.
118
+
119
+ ## `bundle` — a LAG, an ECMP set, an Ethernet Segment
120
+
121
+ ```figdown
122
+ figdown 0.1 topology
123
+ node leaf "Leaf"
124
+ node s1 "Spine 1"
125
+ node s2 "Spine 2"
126
+ edge leaf -- s1
127
+ edge leaf -- s2
128
+ bundle ecmp "ECMP uplink set, 2 × 100G" leaf--s1,leaf--s2
30
129
  ```
31
130
 
32
- The constructs most topology figures reach for next link bundles for LAGs
33
- and ECMP sets, overlay planes for tunnels, markers and zone bands are in
34
- `constructs.md`, and every one of them is EXPERIMENTAL too.
131
+ A **link bundle**: a set of parallel links between the same pair of devices
132
+ operated as one logical link. Its referents are the ones this domain already
133
+ names a link aggregation group (IEEE 802.1AX), an equal-cost multipath
134
+ set, an EVPN Ethernet Segment — and the ring drawn round the member links is
135
+ the same thing the domain means. The domain reading and the drawn reading
136
+ are one reading; this is the cell where the word and the referent agree, and
137
+ it is why `topology` declares `bundle` and the general-purpose genre has no
138
+ use for it.
139
+
140
+ `bundle` is EXPERIMENTAL even inside this experimental genre. It is spelled
141
+ `bundle` and not after the standard's own noun deliberately: *aggregation*
142
+ is right for a link aggregation group and false for an equal-cost multipath
143
+ set and for an Ethernet Segment, so the standard's word cannot be taken
144
+ whole and an umbrella spelling is the honest one.
145
+
146
+ - The member list is ONE comma-delimited token, no spaces.
147
+ - Each member must name an edge that **already exists** and is unambiguous.
148
+ There is no way to address one of two parallel edges between the same
149
+ pair, so a bundle over parallel links cannot be spelled — declare the
150
+ members as distinct edges to distinct peers, as above.
151
+ - `bundle` takes `fill=`, `stroke=` and `style=`; the dashed ring is drawn
152
+ for you.
153
+
154
+ ## Two mistakes this genre invites
155
+
156
+ **A shared medium is not a star.** Flattening a bus, a broadcast segment, a
157
+ shared VLAN or a fabric's underlay into point-to-point links changes what the
158
+ figure asserts: the shared thing reaches every participant at once. Model it
159
+ as one intermediate `node` that fans out.
35
160
 
36
- The two mistakes this genre invites are both covered where they are owned:
37
- a shared medium modelled as a mesh (`../scene.md`, "A shared bus is not a
38
- star") and geography carried by the layout zone alone (`../layout.md`).
161
+ **Geography is not carried by the layout zone.** If where a device sits is
162
+ part of the claim a site, a rack, a country say it with a `group` and a
163
+ label. Delete every `pin` and the figure must still be the same figure
164
+ (`../layout.md`).
@@ -25,6 +25,18 @@ syntax detail in the other files beside it.
25
25
  - **Authored prose** in a `description=` is quotable and displayable, and
26
26
  **never parsable**. Quote it, attribute it to its field, and stop. It
27
27
  carries no structure, no relation and no condition.
28
+ - **A `note=` is authored prose too, on the same terms** (`figdown 0.3`).
29
+ It is quotable and displayable and **never parsable**. It is an **aside**:
30
+ its content is not a fact about the figure's structure. You MAY attribute
31
+ it to the element that carries it — attachment is by syntactic position, so
32
+ there is never a question of which element is meant — and you MUST NOT
33
+ infer a participant, an edge or a category from it. A `note=` on `title`
34
+ (`doc.note`) belongs to the **figure**, not to any element.
35
+ - **`description=` and `note=` are not the same channel and neither replaces
36
+ the other.** They divide by AUDIENCE: `description=` is written **for you**
37
+ and puts no ink on the page; `note=` is written for the **human** and always
38
+ draws. Both may appear in one document, and an element carrying both is
39
+ making two statements to two readers, not saying one thing twice.
28
40
 
29
41
  ## Genre-specific readings
30
42
 
@@ -71,7 +83,7 @@ Widths, colours and alignment never change it.
71
83
  **`timing`.** Cycle *t* is the *t*-th character of the lane. `.` continues
72
84
  the previous value, and cycles stay contiguous across a gap.
73
85
 
74
- **`statechart`** (EXPERIMENTAL, `figdown 0.2` only). Nodes are **states** — modes
86
+ **`statechart`** (EXPERIMENTAL, `figdown 0.2` and later). Nodes are **states** — modes
75
87
  the machine is *in* — and edges are **transitions** on an event. This is the
76
88
  one reading you may not derive from the drawing: a cyclic figure with a
77
89
  self-loop is just as likely to be a polling `flowchart`, and the word "state
@@ -1,27 +1,37 @@
1
- # Scene genres`block`, and the vocabulary `topology` / `flowchart` / `statechart` share
1
+ # Genre `block`things and the connections between them
2
2
 
3
- Status: `block` is NORMATIVE and portable. The same seven keywords are
4
- the whole scene surface; `topology`, `flowchart` and `statechart` reuse them
5
- and add — or **rename** — their own, in their own files.
3
+ Status: NORMATIVE and portable.
6
4
 
7
- Load this for any figure made of **things and the connections between them**.
5
+ Load this for any figure made of **things and the connections between
6
+ them** whose line 1 says `block`. Everything below is `block`'s own
7
+ vocabulary; nothing below is authority for any other genre.
8
8
 
9
- **Two of the seven are spelled differently by genre.** Read
10
- this file for what they *mean*; write the word your genre uses:
9
+ **Every scene genre declares its own words.** There are four, and each one's
10
+ vocabulary is declared once, in its own file:
11
11
 
12
- | genre | the thing | the line |
13
- |---|---|---|
14
- | `block`, `topology` | `node` | `edge` |
15
- | `flowchart` | `node` | **`flowline`** |
16
- | `statechart` | **`state`** | **`transition`** |
12
+ | genre on line 1 | where its vocabulary is declared |
13
+ |---|---|
14
+ | `block` | this file |
15
+ | `topology` | `experimental/topology.md` |
16
+ | `flowchart` | `experimental/flowchart.md` |
17
+ | `statechart` | `experimental/statechart.md` |
17
18
 
18
- Each genre takes the term its own domain actually uses ISO 5807 calls a
19
- flowchart's connector a *flowline*; UML calls a state machine's arc a
20
- *transition*. The wrong one is a **line error naming the right one**, never a
21
- silent acceptance, so you cannot get this wrong without being told. Everything
22
- else about them operators, labels, option keys, the model is identical.
19
+ A word two of them spell the same is **two declarations that happen to agree
20
+ today**, never one inherited each genre may withdraw, rename or constrain
21
+ its own without touching the others, and each carries its own reading advice
22
+ because the same word can be safe in one domain and misleading in another.
23
+ So do not carry a word from this file into another genre and do not go
24
+ looking here for a word another genre's file did not give you: a word the
25
+ genre on line 1 does not declare is a **line error that states the ground**,
26
+ not a spellcheck.
23
27
 
24
- ## The seven keywords
28
+ Three words are spelled the same in all four and are not subject vocabulary
29
+ at all — `class` says what a colour *means*, `flow` and `rank` state layout
30
+ intent. None of them names a thing in the world, so no domain holds a rival
31
+ meaning for one, and each genre's file repeats them rather than sending you
32
+ here.
33
+
34
+ ## The vocabulary, in one figure
25
35
 
26
36
  ```figdown
27
37
  figdown 0.1 block
@@ -67,8 +77,8 @@ edge retry -> reject class=slow
67
77
  `flow` takes `flow right|down|left|up` — one of the four, once per document.
68
78
 
69
79
  Values from a fixed list are written **bare**, never quoted: `shape=box`,
70
- `style=dashed`, `flow down`, `plane=over`. So are ids. Labels are the
71
- opposite and always take quotes.
80
+ `style=dashed`, `flow down`, `gap=0`. So are ids. Labels are the opposite
81
+ and always take quotes.
72
82
 
73
83
  `shape=` is **pure geometry, no domain nouns** — `shape=box` (the default),
74
84
  `shape=rounded`, `shape=circle`, `shape=ellipse`, `shape=diamond`,
@@ -82,6 +92,26 @@ inside a bracket label is ordinary text and needs no quotes —
82
92
  `edge a -[hop #1]-> b` — because `[ ]` is a verbatim region, like a quoted
83
93
  string, a comment and a pipe row.
84
94
 
95
+ ## What `group` and `external` claim here, and what they do not
96
+
97
+ `block` is the **general-purpose** genre: it has no single domain, and that
98
+ is what general-purpose means. So its two container-and-boundary words carry
99
+ no domain caveat, and you should not supply one.
100
+
101
+ - **`group`** is a container and nothing more — a box drawn round its
102
+ members, one nesting level deep. It asserts no ownership, no lifecycle, no
103
+ address space and no failure domain. Whatever the grouping *means* goes in
104
+ the label.
105
+ - **`external`** is an out-of-figure endpoint: something the figure talks to
106
+ but does not describe. It is **never drawn** — the edge simply ends open —
107
+ it takes **no option key at all**, and there is no source standard behind
108
+ the spelling. It is FigDown's own word for FigDown's own boundary.
109
+
110
+ A genre with one domain cannot be this quiet. `topology`'s file has to warn
111
+ its reader off a rival reading of both words before it can use either; this
112
+ file has nothing to warn about, and that asymmetry is why the two
113
+ declarations are separate.
114
+
85
115
  ## Field-tested pitfalls
86
116
 
87
117
  **Containment is not an edge.** An edge from a node to its own container
@@ -129,5 +159,28 @@ a `node` styled to look like one.
129
159
  ## Where to go next
130
160
 
131
161
  - The figure came out scrambled, or placement is the message → `layout.md`
132
- - Marker lines, zone bands, link bundles, overlay planes, charts
133
- `experimental/constructs.md` (EXPERIMENTAL)
162
+ - Marker lines and zone bands over a `block` figure
163
+ `experimental/block.md` (EXPERIMENTAL)
164
+ - Bars drawn from a `table` region → `experimental/chart.md` (EXPERIMENTAL)
165
+
166
+ ## The drawn annotation — `note=` (`figdown 0.3`)
167
+
168
+ `note=` is an **attribute on the annotated element's own line**, and the
169
+ element it is about is the element it is written on: `node a "A" note="…"`,
170
+ `group g "G" note="…"`, `edge a -> b note="…"`, `title "T" note="…"`.
171
+ There is no id, no target key and no locator, so there is never a question
172
+ of which of several identically-labelled elements is meant.
173
+
174
+ **What you may conclude.** The text is authored prose — quotable,
175
+ displayable, **never parsable**. It is an aside about the element, not a
176
+ fact about the figure's structure. Attribute it to its carrier and stop;
177
+ do not infer a participant, an edge or a category from it. A `note=` on
178
+ `title` is about the **figure** and about no element.
179
+
180
+ **What it is not.** It is not `description=`. The two divide by AUDIENCE:
181
+ `description=` is machine-facing and draws nothing beyond an SVG `<title>`;
182
+ `note=` is human-facing and always draws. And **where a typed slot exists,
183
+ a note is never where the fact lives** — a category is a `class` meaning, a
184
+ containment is `in=`, a direction is the operator. If a note's text looks
185
+ like structure, it is still prose: read the structure off the construct that
186
+ states it.