figdown 0.1.8 → 0.3.0
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.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/figdown.js +971 -169
- package/dist/figdown.mjs +971 -169
- package/examples/evpn-fabric.svg +3 -4
- package/examples/showcase/arp-resolution.svg +1 -1
- package/examples/showcase/ethernet-frame.svg +1 -1
- package/examples/showcase/l2-forwarding-logic.svg +9 -9
- package/examples/showcase/tcp-handshake.svg +1 -1
- package/examples/showcase/tcp-header.svg +1 -1
- package/examples/showcase/tcp-state-machine.svg +77 -55
- package/guide/expressing.md +30 -18
- package/guide/layout.md +19 -19
- package/guide/showcase.md +62 -56
- package/package.json +2 -2
- package/skill/figdown/SKILL.md +30 -4
- package/skill/figdown/figdown.html +1030 -194
- package/skill/figdown/reference/experimental/block.md +60 -0
- package/skill/figdown/reference/experimental/chart.md +32 -0
- package/skill/figdown/reference/experimental/flowchart.md +148 -20
- package/skill/figdown/reference/experimental/statechart.md +138 -0
- package/skill/figdown/reference/experimental/timing.md +1 -1
- package/skill/figdown/reference/experimental/topology.md +148 -22
- package/skill/figdown/reference/reading.md +25 -1
- package/skill/figdown/reference/scene.md +78 -10
- package/skill/figdown/reference/experimental/constructs.md +0 -90
|
@@ -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,6 +83,15 @@ 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
|
|
|
86
|
+
**`statechart`** (EXPERIMENTAL, `figdown 0.2` and later). Nodes are **states** — modes
|
|
87
|
+
the machine is *in* — and edges are **transitions** on an event. This is the
|
|
88
|
+
one reading you may not derive from the drawing: a cyclic figure with a
|
|
89
|
+
self-loop is just as likely to be a polling `flowchart`, and the word "state
|
|
90
|
+
machine" in a `title` decides nothing. Only line 1 decides. What you may and
|
|
91
|
+
may not conclude is in `experimental/statechart.md`; the short version is that
|
|
92
|
+
there is no current state, no initial state and no final state in the
|
|
93
|
+
language, so reading any of the three out of a figure is invention.
|
|
94
|
+
|
|
74
95
|
## What you MUST NOT infer
|
|
75
96
|
|
|
76
97
|
- **Ignore the layout zone.** Everything from the `layout` keyword down is
|
|
@@ -96,7 +117,10 @@ the previous value, and cycles stay contiguous across a gap.
|
|
|
96
117
|
- **A keyword's meaning is relative to its genre.** Line 1 names the
|
|
97
118
|
namespace. Never carry a reading from one genre into another, and read a
|
|
98
119
|
nested region under **its** genre, not its host's. Multi-section files give
|
|
99
|
-
each section its own genre
|
|
120
|
+
each section its own genre — **and its own language version**; the two
|
|
121
|
+
numbers on a section's header line are that section's whole contract, and
|
|
122
|
+
one file may legitimately carry sections at different versions. The
|
|
123
|
+
permanent exceptions: `figdown`, `title`,
|
|
100
124
|
`layout` and `pin` mean the same thing everywhere — which is exactly what
|
|
101
125
|
lets you skip the layout zone without first knowing the genre.
|
|
102
126
|
- **A shared `class` is a shared category, not an identity.** The language
|
|
@@ -1,12 +1,37 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Genre `block` — things and the connections between them
|
|
2
2
|
|
|
3
|
-
Status:
|
|
4
|
-
the whole scene surface; `topology` and `flowchart` reuse them and add their
|
|
5
|
-
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
|
|
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
|
-
|
|
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
|
+
|
|
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` |
|
|
18
|
+
|
|
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.
|
|
27
|
+
|
|
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
|
|
10
35
|
|
|
11
36
|
```figdown
|
|
12
37
|
figdown 0.1 block
|
|
@@ -52,8 +77,8 @@ edge retry -> reject class=slow
|
|
|
52
77
|
`flow` takes `flow right|down|left|up` — one of the four, once per document.
|
|
53
78
|
|
|
54
79
|
Values from a fixed list are written **bare**, never quoted: `shape=box`,
|
|
55
|
-
`style=dashed`, `flow down`, `
|
|
56
|
-
|
|
80
|
+
`style=dashed`, `flow down`, `gap=0`. So are ids. Labels are the opposite
|
|
81
|
+
and always take quotes.
|
|
57
82
|
|
|
58
83
|
`shape=` is **pure geometry, no domain nouns** — `shape=box` (the default),
|
|
59
84
|
`shape=rounded`, `shape=circle`, `shape=ellipse`, `shape=diamond`,
|
|
@@ -67,6 +92,26 @@ inside a bracket label is ordinary text and needs no quotes —
|
|
|
67
92
|
`edge a -[hop #1]-> b` — because `[ ]` is a verbatim region, like a quoted
|
|
68
93
|
string, a comment and a pipe row.
|
|
69
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
|
+
|
|
70
115
|
## Field-tested pitfalls
|
|
71
116
|
|
|
72
117
|
**Containment is not an edge.** An edge from a node to its own container
|
|
@@ -114,5 +159,28 @@ a `node` styled to look like one.
|
|
|
114
159
|
## Where to go next
|
|
115
160
|
|
|
116
161
|
- The figure came out scrambled, or placement is the message → `layout.md`
|
|
117
|
-
- Marker lines
|
|
118
|
-
`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.
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# EXPERIMENTAL / EXPERIMENTAL constructs
|
|
2
|
-
|
|
3
|
-
Everything in this file is **outside the v0.1 conformance surface and outside
|
|
4
|
-
the compatibility promise**. The engine accepts it and your document keeps
|
|
5
|
-
working, but it may change or be withdrawn in a later `0.x`. The parser emits
|
|
6
|
-
no warning, so a line that parses tells you nothing.
|
|
7
|
-
|
|
8
|
-
Use these when the figure genuinely needs them. If the figure must be
|
|
9
|
-
portable, do not — and if you use one anyway, say so beside the figure.
|
|
10
|
-
|
|
11
|
-
## Markers and zones — `threshold`, `band`
|
|
12
|
-
|
|
13
|
-
```figdown
|
|
14
|
-
figdown 0.1 block
|
|
15
|
-
group pool "Storage pool"
|
|
16
|
-
node used "In use" in=pool
|
|
17
|
-
threshold "High watermark = stop writes" in=pool offset=80%
|
|
18
|
-
threshold "Low watermark = resume writes" in=pool offset=45%
|
|
19
|
-
band "Reserved" 15% in=pool fill=#fee2e2
|
|
20
|
-
band "Shared quota" 20..70% in=pool extend=down
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
- `threshold` needs a quoted label **and** `offset=<0..100>%`, both mandatory
|
|
24
|
-
— the `%` included. There is no `value=` and no `ref=`.
|
|
25
|
-
- `band` needs a quoted label **first**, then either one percentage (a size)
|
|
26
|
-
or an explicit `<a>..<b>%` range. `..` is the language's ONE range
|
|
27
|
-
separator; the hyphen form is a line error. `extend=up|down|left|right`, and `up`
|
|
28
|
-
is the default.
|
|
29
|
-
- The label is the knowledge in both cases. `offset=` is a fraction of the
|
|
30
|
-
target's rendered extent, **not a value of any quantity** — the target
|
|
31
|
-
declares no scale, so there is no conversion. Put the number in the label
|
|
32
|
-
or it is not in the document.
|
|
33
|
-
- Both attach to a node or a group via `in=`.
|
|
34
|
-
- **Attach at the scope the fact belongs to.** A limit shared by everything in
|
|
35
|
-
a group is one group-level marker; a fact true of one element attaches to
|
|
36
|
-
that element. The renderer may draw the two the same way — the difference is
|
|
37
|
-
in the text, and the text is the knowledge.
|
|
38
|
-
|
|
39
|
-
## Link bundles — `bundle`
|
|
40
|
-
|
|
41
|
-
```figdown
|
|
42
|
-
figdown 0.1 block
|
|
43
|
-
node leaf "Leaf"
|
|
44
|
-
node s1 "Spine 1"
|
|
45
|
-
node s2 "Spine 2"
|
|
46
|
-
edge leaf -- s1
|
|
47
|
-
edge leaf -- s2
|
|
48
|
-
bundle ecmp "ECMP uplink set (2 × 100G)" leaf--s1,leaf--s2
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Names a set of already-declared edges as one logical link. The dashed ring is
|
|
52
|
-
drawn for you, and the member list is one comma-delimited token. Each member
|
|
53
|
-
must name an edge that already exists and is unambiguous — v0.1 has no way to
|
|
54
|
-
address one of two parallel edges between the same pair, so a bundle over
|
|
55
|
-
parallel links cannot be spelled.
|
|
56
|
-
|
|
57
|
-
## Overlay planes — `plane`, `plane=`
|
|
58
|
-
|
|
59
|
-
```figdown
|
|
60
|
-
figdown 0.1 block
|
|
61
|
-
plane overlay "VXLAN tunnels" z-index=2
|
|
62
|
-
node l1 "Leaf 1"
|
|
63
|
-
node l2 "Leaf 2"
|
|
64
|
-
node s1 "Spine" plane=overlay
|
|
65
|
-
edge l1 <-> l2 plane=overlay
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
The **label is the knowledge** — "VXLAN tunnels" is what a reader keeps, not
|
|
69
|
-
the paint order. Every document has an implicit `base` plane at `z-index=0`,
|
|
70
|
-
and every element reports it unless it names another. An omitted `z-index=`
|
|
71
|
-
takes the plane's 1-based declaration index. `z-index=` reorders the
|
|
72
|
-
annotation pass only — edges, bundle rings, thresholds and bands. `plane=` is
|
|
73
|
-
legal on a node, group, external endpoint, edge, class, bundle, threshold and
|
|
74
|
-
band.
|
|
75
|
-
|
|
76
|
-
## Charts from a table — `chart`, `type=`
|
|
77
|
-
|
|
78
|
-
```figdown
|
|
79
|
-
figdown 0.1 table
|
|
80
|
-
table t "Throughput"
|
|
81
|
-
| Port | Gbps |
|
|
82
|
-
|------|------|
|
|
83
|
-
| 1 | 25 |
|
|
84
|
-
| 2 | 40 |
|
|
85
|
-
chart t type=bar3d
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Draws bars from a table's numeric cells. `type=` is the only option key and
|
|
89
|
-
`bar3d` is its only value. For anything a chart library would do better, keep
|
|
90
|
-
the raster and put the numbers in a table (`../transcribe.md`).
|