reladraw 0.23.1 → 0.25.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/skills/reladraw/SKILL.md +27 -4
- package/.claude/skills/reladraw/reference/syntax.md +106 -12
- package/README.md +6 -4
- package/SYNTAX.md +106 -12
- package/dist/ast.d.ts +47 -1
- package/dist/ast.js +12 -4
- package/dist/cli.js +108 -13
- package/dist/constants.d.ts +21 -1
- package/dist/constants.js +35 -2
- package/dist/format.js +5 -1
- package/dist/grammar.d.ts +1 -1
- package/dist/grammar.js +16 -3
- package/dist/linetexts.d.ts +4 -1
- package/dist/linetexts.js +13 -3
- package/dist/links.d.ts +4 -0
- package/dist/markdown.d.ts +14 -0
- package/dist/markdown.js +102 -0
- package/dist/model.d.ts +4 -3
- package/dist/page.js +21 -3
- package/dist/parser.d.ts +7 -0
- package/dist/parser.js +244 -27
- package/dist/place.js +3 -5
- package/dist/render.js +52 -28
- package/dist/resolve.js +207 -22
- package/dist/text.d.ts +15 -3
- package/dist/text.js +16 -7
- package/package.json +1 -2
|
@@ -15,7 +15,7 @@ That matters here specifically. You can't see the SVG you produced. With auto-la
|
|
|
15
15
|
|
|
16
16
|
## Check it is installed, and the same version as this skill
|
|
17
17
|
|
|
18
|
-
This skill teaches reladraw 0.
|
|
18
|
+
This skill teaches reladraw 0.25.0. Once per session, before the first render, run:
|
|
19
19
|
|
|
20
20
|
```
|
|
21
21
|
reladraw --version
|
|
@@ -23,7 +23,7 @@ reladraw --version
|
|
|
23
23
|
|
|
24
24
|
- **The same:** say nothing.
|
|
25
25
|
- **Older, or `--version` isn't recognized** (it arrived in 0.17.1): the tool is older than this page and will refuse some of what it teaches. Tell the user, and give them `npm install -g reladraw@latest`.
|
|
26
|
-
- **Newer:** this skill is out of date. Tell the user, and give them `reladraw install-skill
|
|
26
|
+
- **Newer:** this skill is out of date. Tell the user, and give them `reladraw install-skill`, which asks which agents to install for and replaces it with the skill that came with their reladraw. Carry on meanwhile; where an error names a replacement spelling, trust the error over this page.
|
|
27
27
|
|
|
28
28
|
If `reladraw` isn't installed, `npx reladraw` works without installing, and `npm install -g reladraw` installs it.
|
|
29
29
|
|
|
@@ -117,7 +117,7 @@ node grinder "Grinder / [dim]medium-fine[/dim]"
|
|
|
117
117
|
node note "a longer remark that folds" (size: small, wrap: 30) shape: none below grinder (gap: tight)
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
`[dim]…[/dim]` borrows a style's
|
|
120
|
+
`[dim]…[/dim]` borrows a style's text color and size for a stretch of text; a line that is all small is spaced as a small line. A style hangs the bracket off a key: `style aside text: (size: small, color: theme-muted)`. **Always give bare text a `(wrap: n)`**, or a sentence is one long line across whatever is beside it.
|
|
121
121
|
|
|
122
122
|
### Lines
|
|
123
123
|
|
|
@@ -170,7 +170,30 @@ node api_link "github.com/acme/api" shape: none right of api
|
|
|
170
170
|
node api "API server" url: "https://github.com/acme/api"
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
The address is never drawn; a reader follows it by clicking. A line with no text can
|
|
173
|
+
The address is never drawn; a reader follows it by clicking. A line with no text can carry one too, but a style can't. Quote the value, since an unquoted `//` starts a comment.
|
|
174
|
+
|
|
175
|
+
When addresses are long, or one is used on several things, declare each once with its name and badge and use it by name, so the statements stay readable. A declaration can also list several links for things that share them:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
url orders-docs "https://docs.example.com/orders/v2/reference" (name: "Docs")
|
|
179
|
+
url orders-code "https://github.com/example/orders/tree/main/services/api" (name: "Code")
|
|
180
|
+
url orders-links orders-docs orders-code
|
|
181
|
+
|
|
182
|
+
node api "Orders API" url: orders-links
|
|
183
|
+
node worker "Worker" url: orders-docs
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Descriptions
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
node proxy "Proxy" description: "Forwards each request by its path."
|
|
190
|
+
|
|
191
|
+
description for orders and to-orders """
|
|
192
|
+
Owns the order records. See [the docs](https://example.com/orders).
|
|
193
|
+
"""
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Notes about a thing go in its description, not in a box beside it.** A description is shown when the thing is selected on the `--page` page, and as hover text in an SVG; it is never drawn, so it can run to paragraphs and lists in Markdown. Write a short one on the statement, and a long one with `description for`, after the diagram's statements, so it doesn't crowd them. When several things share one text, name them all after `for`.
|
|
174
197
|
|
|
175
198
|
**Offer links; don't add them unasked.** When the things in a diagram have real web addresses, such as the files of a pull request on GitHub, end your reply with one line offering to link each node to its file. Never guess an address, and don't link to files on the local machine.
|
|
176
199
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Syntax reference — 0.
|
|
1
|
+
# Syntax reference — 0.25.0
|
|
2
2
|
|
|
3
3
|
What the language accepts. The changelog at the end lists what changed in each published version; 0.17.0's changes are large, and its entry has a table of every old spelling and what to write instead.
|
|
4
4
|
|
|
@@ -38,6 +38,7 @@ An indented line with nothing to continue, at the top of the file or after a bla
|
|
|
38
38
|
| `default` | appearance every thing of one kind wears ([Defaults](#defaults)) |
|
|
39
39
|
| `diagram` | settings for the whole drawing ([The diagram](#the-diagram)) |
|
|
40
40
|
| `icon` | a picture of your own ([Your own icons](#your-own-icons)) |
|
|
41
|
+
| `description` | text about a box or a line, for the page's panel ([Descriptions](#descriptions)) |
|
|
41
42
|
|
|
42
43
|
`box`, `link`, `note`, `deck`, `rect` and `arrow` at the start of a statement are refused by name, each quoting what to write instead.
|
|
43
44
|
|
|
@@ -71,7 +72,7 @@ A text is quoted. ` / `, a slash with whitespace on both sides, breaks the line,
|
|
|
71
72
|
|
|
72
73
|
A node with no text shows its name, and a dotted name shows only its last part: `node server.docker` reads "docker". The name is never prettified. `""` says a node deliberately has none. A node drawn as a picture shows no text unless one is written.
|
|
73
74
|
|
|
74
|
-
A `"""` string takes everything between its marks as written, quotes and line breaks included. It is accepted only for an icon's SVG.
|
|
75
|
+
A `"""` string takes everything between its marks as written, quotes and line breaks included. It is accepted only for an icon's SVG and a description's text ([Descriptions](#descriptions)).
|
|
75
76
|
|
|
76
77
|
### Numbers and the file's unit
|
|
77
78
|
|
|
@@ -258,7 +259,7 @@ node notes "notes" below resolver (gap: tight) shape: none
|
|
|
258
259
|
|
|
259
260
|
### Several targets at once
|
|
260
261
|
|
|
261
|
-
A placement may name several targets, joined by `and` or commas: `right of a, b and c`. It places against the box bounding them all, a region nobody had to declare. A lone direction centers on that region, which is how one row is offset against another:
|
|
262
|
+
A placement may name several targets, joined by `and` or commas: `right of a, b and c`. It places against the box bounding them all, a region nobody had to declare. A distance and a direction after the `and` or comma start another placement instead: `right of a and 2 above c top` is `right of a 2 above c top`. To place against a point and a box together, name the point first: `point p 2 above c top-center`, then `right of a and p`. A lone direction centers on that region, which is how one row is offset against another:
|
|
262
263
|
|
|
263
264
|
```
|
|
264
265
|
node a icon: cube
|
|
@@ -291,7 +292,7 @@ A fraction of the way across a box is written fraction first: `top even with 3/4
|
|
|
291
292
|
|
|
292
293
|
`center 12 right of a center` puts the two centers exactly 12 apart, the even steps of a timeline whose boxes differ in width. `top 3 below a bottom` is the same for edges. The direction means what it always means, so with nothing else said the box also sits level with `a`'s center. A placement naming parts must give its distance: `center right of a center` is refused ("say how far").
|
|
293
294
|
|
|
294
|
-
Two distances, one per axis, are accepted in any placement: `3 below and 2 right of a`, or `top-left 3 below and 2 right of a bottom-right`.
|
|
295
|
+
Two distances, one per axis, are accepted in any placement: `3 below and 2 right of a`, or `top-left 3 below and 2 right of a bottom-right`. A `left` or `right` that comes first may keep its `of`: `2 right of and 3 below a` is `2 right and 3 below a`.
|
|
295
296
|
|
|
296
297
|
**How far along the side it faces.** `right of server 3/4 down` puts the box the usual gap right of `server`, its middle level with a spot three quarters of the way down `server`'s right side. `down` and `up` run along a left or right side, `across` along a top or bottom one. A word that doesn't run along the side the direction faces is refused, listing the words that do.
|
|
297
298
|
|
|
@@ -684,14 +685,16 @@ node rack.b "web-2"
|
|
|
684
685
|
|
|
685
686
|
### Markup
|
|
686
687
|
|
|
687
|
-
A stretch of text can borrow a style's
|
|
688
|
+
A stretch of text can borrow a style's text color and size:
|
|
688
689
|
|
|
689
690
|
```
|
|
690
|
-
style dim text: (color: theme-muted)
|
|
691
|
+
style dim text: (color: theme-muted, size: small)
|
|
691
692
|
node files "shared folder / [dim]synced[/dim]"
|
|
692
693
|
```
|
|
693
694
|
|
|
694
|
-
The opener names a style, never a color, so the marked words borrow a meaning the file already has. A name no style answers to is refused, and so is a style that
|
|
695
|
+
The opener names a style, never a color, so the marked words borrow a meaning the file already has. A name no style answers to is refused, and so is a style that gives text neither a color nor a size.
|
|
696
|
+
|
|
697
|
+
**A line is as tall as its largest text.** A line that is all small is spaced as a small line, so the box is shorter. A small stretch mid-line, `"3 [dim]files[/dim] waiting"`, sits on the same baseline as the words around it, and the line keeps the normal spacing. With `wrap:`, a small character counts as less than a whole one, by the ratio of the two sizes. The closer repeats the name, so a mismatched close is refused by name. Marks don't nest, and a mark may cross a line break. A bare `[` is an error; write `\[` for a literal one.
|
|
695
698
|
|
|
696
699
|
## Lines
|
|
697
700
|
|
|
@@ -974,11 +977,19 @@ A line may carry several texts, one after another, each with its own bracket. **
|
|
|
974
977
|
|
|
975
978
|
**Beside the line:** `(right of edge)`, `(left of edge)`, `(above edge)`, `(below edge)` move the text out the stated way until it is clear of the part of the line it landed on.
|
|
976
979
|
|
|
980
|
+
How far it moves can be said in front:
|
|
981
|
+
|
|
982
|
+
- `(at: 4/5, 1 above edge)`: one unit up from where it would sit on the line. If that is short of clear, the text still crosses the line and hides it there.
|
|
983
|
+
- `(at: 4/5, 1/2 clear above edge)`: half of the move that would clear the line. Any fraction or number works, `3/4 clear` or `1.5 clear`.
|
|
984
|
+
- `(at: 4/5, clear above edge)`: all the way clear, the same as `above edge`.
|
|
985
|
+
|
|
986
|
+
A distance is a number, `0.5 above edge`; `1/2 above edge` is refused, naming both forms. `edge-gap:` beside a distance is refused as said twice.
|
|
987
|
+
|
|
977
988
|
**Lined up with a box on one axis:** `(left even with a right)` puts the left edge of the patch behind the text at `a`'s right side, and leaves its height where it would otherwise sit; `(x even with mid1)` centers the text across on `mid1`. Any `even with` a box takes works, one per axis, and the other axis comes from the line. On a level stretch it slides the text along the line; on an upright one, it moves the text off the line sideways. With a relation that already says the same axis, such as `right of edge`, it is refused. Separate it from the bracket's next item with a comma.
|
|
978
989
|
|
|
979
990
|
**Which way it reads:** `reads: up` and `reads: down` turn it a quarter turn; `reads: along` takes the line's angle where it sits, never upside down.
|
|
980
991
|
|
|
981
|
-
`gap:` is the distance from the box for `at: start`, `at: end` and the box relations; `edge-gap:` the distance
|
|
992
|
+
`gap:` is the distance from the box for `at: start`, `at: end` and the box relations; `edge-gap:` the distance past clear for a text beside it, and part of the move that `1/2 clear` takes a fraction of. Each defaults to half a unit, written in the text's own bracket.
|
|
982
993
|
|
|
983
994
|
```
|
|
984
995
|
node a
|
|
@@ -1052,7 +1063,7 @@ node nas "NAS" right of mirror
|
|
|
1052
1063
|
edge mirror -> nas style: backup
|
|
1053
1064
|
```
|
|
1054
1065
|
|
|
1055
|
-
A style is a named bundle of appearance, worn with `style:`. Color carries meaning through the style's name rather than being written per thing. A style takes `fill`, `border`, `line`, `text`, `badge`, `icon`, `shape`, `from-mark`, `to-mark`, `padding`, `corners` and a region's `opacity`, and a title's position inside `text: (…)`: `style zone text: (outside top, align: left)`. It never says where a thing goes, so it can't carry a placement, a `gap:`, a `depth:`, or a line's `from:` or `to:`, and it can't carry a `url:` or a deck's `cards:`.
|
|
1066
|
+
A style is a named bundle of appearance, worn with `style:`. Color carries meaning through the style's name rather than being written per thing. A style takes `fill`, `border`, `line`, `text`, `badge`, `icon`, `shape`, `from-mark`, `to-mark`, `padding`, `corners` and a region's `opacity`, and a title's position inside `text: (…)`: `style zone text: (outside top, align: left)`. It never says where a thing goes, so it can't carry a placement, a `gap:`, a `depth:`, or a line's `from:` or `to:`, and it can't carry a `url:`, a `description:` or a deck's `cards:`.
|
|
1056
1067
|
|
|
1057
1068
|
- **A style may span kinds.** It gives each thing only the keys that thing has, so the style above gives nodes their border and lines their color.
|
|
1058
1069
|
- **A style must give a thing at least one key it has.** A style that dresses a thing in nothing is on the wrong thing.
|
|
@@ -1118,7 +1129,7 @@ A default is a style every thing of one kind wears without naming it: `node`, `l
|
|
|
1118
1129
|
|
|
1119
1130
|
A container inside another container is filled a shade further from the page than the one it sits in, so the two read as two backdrops. An invisible container (`shape: none`) doesn't count, and a stated `fill:` wins as always.
|
|
1120
1131
|
|
|
1121
|
-
A default takes the words a style does and may wear a style of its own (`default edge style: quiet`), laid beneath its own words. It is strict about kind, since it names its kind: `default edge fill: red` is refused, pointing to `line:`. `icon:` is a leaf's alone. A default carries no `url:`. Each kind is written once, and `default leaf node` is refused, naming `default leaf`.
|
|
1132
|
+
A default takes the words a style does and may wear a style of its own (`default edge style: quiet`), laid beneath its own words. It is strict about kind, since it names its kind: `default edge fill: red` is refused, pointing to `line:`. `icon:` is a leaf's alone. A default carries no `url:` or `description:`. Each kind is written once, and `default leaf node` is refused, naming `default leaf`.
|
|
1122
1133
|
|
|
1123
1134
|
### The diagram
|
|
1124
1135
|
|
|
@@ -1156,6 +1167,70 @@ node api "Orders API"
|
|
|
1156
1167
|
|
|
1157
1168
|
The same address twice in one `url:` is refused.
|
|
1158
1169
|
|
|
1170
|
+
A link can be declared once, with its name and badge, and used by name. A quoted value after `url:` is an address and an unquoted one is a declared link, and the two mix in one list in the order written:
|
|
1171
|
+
|
|
1172
|
+
```
|
|
1173
|
+
url orders-docs "https://docs.example.com/orders/v2/reference" (name: "Docs", icon: "D" (fill: #3a6ea5, text: white))
|
|
1174
|
+
url orders-code "https://github.com/example/orders/tree/main/services/api" (name: "Code")
|
|
1175
|
+
|
|
1176
|
+
node api "Orders API" url: orders-docs orders-code
|
|
1177
|
+
node worker "Worker" url: orders-docs "https://example.com/runbooks/worker" (name: "Runbook")
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
A declaration may list several links, each a quoted address or another declared name, and a use gives all of them in order:
|
|
1181
|
+
|
|
1182
|
+
```
|
|
1183
|
+
url orders-links orders-docs orders-code "https://wiki.example.com/orders" (name: "Wiki")
|
|
1184
|
+
|
|
1185
|
+
node api "Orders API" url: orders-links
|
|
1186
|
+
```
|
|
1187
|
+
|
|
1188
|
+
A declared link's name and badge are its own, so a bracket after its name in a `url:` is refused; to show it differently, declare another. A declaration may come before or after its use. Refused, each with a message: a name used but never declared, a name declared twice, a declaration that reaches itself through its own list, and a name that starts a placement, such as `below`, since a placement may follow a `url:` on the same statement.
|
|
1189
|
+
|
|
1190
|
+
### Descriptions
|
|
1191
|
+
|
|
1192
|
+
A box or a line can carry a description: text a reader asks for, shown in the panel when it is selected on a page made with `--page`, and never drawn. It can be written three ways.
|
|
1193
|
+
|
|
1194
|
+
On the thing's own statement, quoted:
|
|
1195
|
+
|
|
1196
|
+
```
|
|
1197
|
+
node proxy "Proxy" description: "Forwards each request by its path."
|
|
1198
|
+
```
|
|
1199
|
+
|
|
1200
|
+
At a distance, for things already named, so a long text doesn't crowd the diagram's statements:
|
|
1201
|
+
|
|
1202
|
+
```
|
|
1203
|
+
node proxy "Proxy"
|
|
1204
|
+
node orders "Orders" right of proxy
|
|
1205
|
+
edge to-orders proxy -> orders
|
|
1206
|
+
|
|
1207
|
+
description for orders and to-orders """
|
|
1208
|
+
Owns the order records.
|
|
1209
|
+
|
|
1210
|
+
- `/orders` lands here
|
|
1211
|
+
- see [the docs](https://example.com/orders)
|
|
1212
|
+
"""
|
|
1213
|
+
```
|
|
1214
|
+
|
|
1215
|
+
Or named, for any box or line to take by that name:
|
|
1216
|
+
|
|
1217
|
+
```
|
|
1218
|
+
description replica """
|
|
1219
|
+
One of three identical replicas behind the proxy.
|
|
1220
|
+
"""
|
|
1221
|
+
|
|
1222
|
+
node r1 "Replica 1" description: replica
|
|
1223
|
+
node r2 "Replica 2" description: replica below r1
|
|
1224
|
+
```
|
|
1225
|
+
|
|
1226
|
+
`description:` takes the text quoted, or a description's name unquoted, as `icon:` takes letters quoted and a picture's name bare. `description for` names boxes and named lines, separated by commas or `and`; a name that is neither is refused. A long text goes between `"""` marks, where line breaks are kept and the indentation every line shares is taken off.
|
|
1227
|
+
|
|
1228
|
+
The text is Markdown, in part: paragraphs, lists (`-`, `*` or `1.`), `**bold**`, `*italic*` or `_italic_`, `` `code` `` and links, `[text](https://…)`. Anything else shows as written. A link goes to an `https:`, `http:` or `mailto:` address or a path; any other is refused.
|
|
1229
|
+
|
|
1230
|
+
**In an SVG**, the description is the thing's hover text, with the marks taken out and each link's address after its text. Writing one never moves anything in the drawing.
|
|
1231
|
+
|
|
1232
|
+
A thing has one description: two on one statement, or one there and another from `description for`, are refused. So is a name declared twice. A style and a default carry none.
|
|
1233
|
+
|
|
1159
1234
|
## Errors and findings
|
|
1160
1235
|
|
|
1161
1236
|
An **error** means the file can't be drawn: an unknown key, two placements on one axis, a cycle. Nothing is drawn, and the message names what to write instead. A **finding** is about a picture that was drawn and may not read as meant. A render with findings succeeds.
|
|
@@ -1203,7 +1278,7 @@ reladraw check diagram.reladraw
|
|
|
1203
1278
|
| `--no-checks` | print no findings; errors still print |
|
|
1204
1279
|
| `-v`, `--version` | print the version |
|
|
1205
1280
|
|
|
1206
|
-
`reladraw install-skill` installs the agent skill that came with this version of reladraw, by running `npx skills add` on it with `--copy`.
|
|
1281
|
+
`reladraw install-skill` installs the agent skill that came with this version of reladraw, for every project, by running `npx skills add` on it with `--copy`. `--claude` installs it in `~/.claude/skills`, `--agents` in `~/.agents/skills` (Codex and others), and both may be given; with neither, it asks, or, with no terminal to ask in, refuses and names them. For any other agent it prints the `skills` command to run.
|
|
1207
1282
|
|
|
1208
1283
|
The output is a standalone SVG: every picture is drawn into it as path data, never from a font or a linked file. A web page can draw a diagram in place with `<reladraw-diagram>`; see "In a web page" in the README.
|
|
1209
1284
|
|
|
@@ -1215,7 +1290,7 @@ reladraw render arch.reladraw --page
|
|
|
1215
1290
|
|
|
1216
1291
|
`--page` writes `arch.html`: one self-contained file, for opening in a browser, attaching or committing, that needs nothing running and fetches nothing. The page is in the diagram's own colors, so a dark diagram doesn't sit on a white page, and it is headed with `diagram title:`, or the file's name when there is none. Under the title it says which file it was drawn from and when, such as "drawn from arch.reladraw, 2026-11-05 14:32": the page is a snapshot of the file, and is behind it once the file is edited, until it is rendered again. Drag to pan; scroll, pinch or double-click to zoom; Fit shows the whole diagram and 100% returns it to its own scale. The zoom is always shown, with "Fit" beside it while the whole diagram is in view. There is a full-screen button. The Save menu saves the page itself, as it was written rather than at its current zoom; the `.reladraw` source it was drawn from; or the picture as an SVG or a PNG, as `render` would draw it; or copies the SVG. Each is named after the source file: `arch.html`, `arch.reladraw`, `arch.svg`, `arch.png`. In Chrome and Edge it asks where to save; other browsers put the file with their downloads. The findings are listed beside it in a panel that folds away, and clicking one lights up what its line drew. A box's or a line's name shows under the pointer.
|
|
1217
1292
|
|
|
1218
|
-
**A click on a box or a line selects it**, and never follows a link. The selection is amber; what feeds it is green and what it feeds is red, the lines dashed and moving the way they run; the rest dims. A line runs from the end without an arrowhead when only one end has one, and otherwise from the end written first. The panel beside the drawing names the selection and lists its links, each with its badge, and the boxes it comes from and goes to; a link opens in a new tab, and a box selects it. One line out lights by default, and the panel's button lights everything upstream and downstream. A box with links underlines its text under the pointer. A click on the background or Escape clears the selection.
|
|
1293
|
+
**A click on a box or a line selects it**, and never follows a link. The selection is amber; what feeds it is green and what it feeds is red, the lines dashed and moving the way they run; the rest dims. A line runs from the end without an arrowhead when only one end has one, and otherwise from the end written first. The panel beside the drawing names the selection and lists its links, each with its badge, and the boxes it comes from and goes to; a link opens in a new tab, and a box selects it. One line out lights by default, and the panel's button lights everything upstream and downstream. Its description, if it has one, comes last ([Descriptions](#descriptions)). A box with links underlines its text under the pointer. A click on the background or Escape clears the selection.
|
|
1219
1294
|
|
|
1220
1295
|
Keys: `+` and `-` zoom, `0` fits, `1` is actual size, `f` is full screen, Escape clears the selection.
|
|
1221
1296
|
|
|
@@ -1290,6 +1365,7 @@ Every attribute, and what takes one. A node's kind is what its body is: a box (`
|
|
|
1290
1365
|
| `gather-children` | ✓ | | ✓ | | where the children sit in spare room |
|
|
1291
1366
|
| `heading` | ✓ | | ✓ | | the child that is the title |
|
|
1292
1367
|
| `join-with` | ✓ | ✓ | ✓ | | the thing this moves with |
|
|
1368
|
+
| `description` | ✓ | ✓ | ✓ | ✓ | text for the page's panel ([Descriptions](#descriptions)) |
|
|
1293
1369
|
| `padding` | ✓ | | ✓ | | room inside the edge |
|
|
1294
1370
|
| `padding-top`, `-right`, `-bottom`, `-left` | ✓ | | ✓ | | one side's room, over `padding` |
|
|
1295
1371
|
| `width`, `height`, `min-…`, `max-…` | ✓ | | ✓ | | a stated size |
|
|
@@ -1338,6 +1414,24 @@ Designed and absent from the code.
|
|
|
1338
1414
|
|
|
1339
1415
|
Pre-1.0, so the minor number is where a breaking change goes. Every removal is refused by name with the replacement quoted, rather than dropped in silence: an older file stops with an error saying what to write instead.
|
|
1340
1416
|
|
|
1417
|
+
**0.25.0**
|
|
1418
|
+
|
|
1419
|
+
- **A link can be declared once and used by name**: `url orders-docs "https://…" (name: "Docs", icon: "D")`, then `url: orders-docs`, so long addresses stay out of the statements that link to them. A declaration may list several links, declared names among them, and a `url:` mixes names and quoted addresses. See [Destinations](#destinations).
|
|
1420
|
+
|
|
1421
|
+
- **Marked text takes its style's size**: with `style dim text: (size: small)`, `"Some Node / [dim]something[/dim]"` draws the second line small, and a line that is all small is spaced as one. Markup used to take only a style's color, and a style with only a size was refused as saying nothing about text. See [Markup](#markup).
|
|
1422
|
+
|
|
1423
|
+
- **`2 right of and 3 below a`** is accepted, the same as `2 right and 3 below a`. It used to be refused with a message that took `and` for the name of a box.
|
|
1424
|
+
|
|
1425
|
+
- **`right of a and 2 above c top` is two placements**: `b` right of `a`, and its bottom 2 above `c`'s top. A distance and a direction after `and` or a comma used to add a point to the targets, so `b` was placed right of the region round `a` and that point, with no warning, and the second half looked ignored. A point meant as a target is named first with `point`.
|
|
1426
|
+
|
|
1427
|
+
- **A box or a line can have a description**, shown in the panel when it is selected on a `--page` page, and as hover text in an SVG. It is written on the thing, `description: "Forwards each request by its path."`; at a distance, `description for orders and to-orders """…"""`; or named, `description replica """…"""`, and taken with `description: replica`. The text is a small part of Markdown: paragraphs, lists, bold, italic, code and links.
|
|
1428
|
+
|
|
1429
|
+
- **A line's text can rise a stated amount off its line, or part of the way clear.** `above edge` and its kin always moved a text all the way clear, which on a slanted line can be well away from it. `(1 above edge)` now raises it one unit from its spot on the line, still crossing the line if that is short of clear, and `(1/2 clear above edge)` moves it half the way. `(1 above edge)` used to be refused, pointing to `edge-gap:`.
|
|
1430
|
+
|
|
1431
|
+
**0.24.0**
|
|
1432
|
+
|
|
1433
|
+
- **`reladraw install-skill` installs for Claude Code, the `~/.agents` folder, or both, and asks which.** It used to pass everything on to `skills`, which, given no agent, put a copy in the folder of every agent it knows, more than fifty of them, and in the current project unless `-g` was written. It now always installs for every project, in the places `--claude` and `--agents` name; `-a` and the other `skills` options are refused with the `skills` command that does the same, and `-g` is still accepted.
|
|
1434
|
+
|
|
1341
1435
|
**0.23.1**
|
|
1342
1436
|
|
|
1343
1437
|
- **`reladraw format` no longer fails on a comment between a placement and its bracket**, such as `right of a`, then `// why wide`, then `(gap: wide)` on lines of their own. It stopped with "Cannot read properties of undefined"; it now keeps the comment where it was. Reported in #22.
|
package/README.md
CHANGED
|
@@ -77,22 +77,24 @@ Each `<reladraw-diagram>` is replaced by its SVG. Indent the source however suit
|
|
|
77
77
|
To install a skill to let your agent know how to use reladraw:
|
|
78
78
|
|
|
79
79
|
```
|
|
80
|
-
reladraw install-skill
|
|
80
|
+
reladraw install-skill
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
That installs the skill that came with your copy of reladraw, so it teaches what your reladraw accepts, for every
|
|
83
|
+
That installs the skill that came with your copy of reladraw, so it teaches what your reladraw accepts, for every project. It asks where: `~/.claude/skills` for Claude Code, `~/.agents/skills` for Codex and the other agents that read it, or both. To say so without being asked, as when an agent runs it, write `--claude`, `--agents`, or both:
|
|
84
84
|
|
|
85
85
|
```
|
|
86
|
-
reladraw install-skill
|
|
86
|
+
reladraw install-skill --claude --agents
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
For any other agent, it prints the [skills](https://www.npmjs.com/package/skills) command that installs this same skill there.
|
|
90
|
+
|
|
89
91
|
The skill is a copy, so after upgrading reladraw, run the command again to bring the skill up to date with it.
|
|
90
92
|
|
|
91
93
|
To install the skill from the main branch instead, which can run ahead of the release on npm, run `npx skills add reladraw/reladraw -g`.
|
|
92
94
|
|
|
93
95
|
## Status
|
|
94
96
|
|
|
95
|
-
Version 0.
|
|
97
|
+
Version 0.25.0. Early stage, but works. The parser, layout engine, and SVG renderer are written in TypeScript, with zero runtime dependencies. There is a command-line tool that turns a .reladraw text file into an SVG, and an element that does the same inside a web page.
|
|
96
98
|
|
|
97
99
|
## License
|
|
98
100
|
|
package/SYNTAX.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Syntax reference — 0.
|
|
1
|
+
# Syntax reference — 0.25.0
|
|
2
2
|
|
|
3
3
|
What the language accepts. The changelog at the end lists what changed in each published version; 0.17.0's changes are large, and its entry has a table of every old spelling and what to write instead.
|
|
4
4
|
|
|
@@ -38,6 +38,7 @@ An indented line with nothing to continue, at the top of the file or after a bla
|
|
|
38
38
|
| `default` | appearance every thing of one kind wears ([Defaults](#defaults)) |
|
|
39
39
|
| `diagram` | settings for the whole drawing ([The diagram](#the-diagram)) |
|
|
40
40
|
| `icon` | a picture of your own ([Your own icons](#your-own-icons)) |
|
|
41
|
+
| `description` | text about a box or a line, for the page's panel ([Descriptions](#descriptions)) |
|
|
41
42
|
|
|
42
43
|
`box`, `link`, `note`, `deck`, `rect` and `arrow` at the start of a statement are refused by name, each quoting what to write instead.
|
|
43
44
|
|
|
@@ -71,7 +72,7 @@ A text is quoted. ` / `, a slash with whitespace on both sides, breaks the line,
|
|
|
71
72
|
|
|
72
73
|
A node with no text shows its name, and a dotted name shows only its last part: `node server.docker` reads "docker". The name is never prettified. `""` says a node deliberately has none. A node drawn as a picture shows no text unless one is written.
|
|
73
74
|
|
|
74
|
-
A `"""` string takes everything between its marks as written, quotes and line breaks included. It is accepted only for an icon's SVG.
|
|
75
|
+
A `"""` string takes everything between its marks as written, quotes and line breaks included. It is accepted only for an icon's SVG and a description's text ([Descriptions](#descriptions)).
|
|
75
76
|
|
|
76
77
|
### Numbers and the file's unit
|
|
77
78
|
|
|
@@ -258,7 +259,7 @@ node notes "notes" below resolver (gap: tight) shape: none
|
|
|
258
259
|
|
|
259
260
|
### Several targets at once
|
|
260
261
|
|
|
261
|
-
A placement may name several targets, joined by `and` or commas: `right of a, b and c`. It places against the box bounding them all, a region nobody had to declare. A lone direction centers on that region, which is how one row is offset against another:
|
|
262
|
+
A placement may name several targets, joined by `and` or commas: `right of a, b and c`. It places against the box bounding them all, a region nobody had to declare. A distance and a direction after the `and` or comma start another placement instead: `right of a and 2 above c top` is `right of a 2 above c top`. To place against a point and a box together, name the point first: `point p 2 above c top-center`, then `right of a and p`. A lone direction centers on that region, which is how one row is offset against another:
|
|
262
263
|
|
|
263
264
|
```
|
|
264
265
|
node a icon: cube
|
|
@@ -291,7 +292,7 @@ A fraction of the way across a box is written fraction first: `top even with 3/4
|
|
|
291
292
|
|
|
292
293
|
`center 12 right of a center` puts the two centers exactly 12 apart, the even steps of a timeline whose boxes differ in width. `top 3 below a bottom` is the same for edges. The direction means what it always means, so with nothing else said the box also sits level with `a`'s center. A placement naming parts must give its distance: `center right of a center` is refused ("say how far").
|
|
293
294
|
|
|
294
|
-
Two distances, one per axis, are accepted in any placement: `3 below and 2 right of a`, or `top-left 3 below and 2 right of a bottom-right`.
|
|
295
|
+
Two distances, one per axis, are accepted in any placement: `3 below and 2 right of a`, or `top-left 3 below and 2 right of a bottom-right`. A `left` or `right` that comes first may keep its `of`: `2 right of and 3 below a` is `2 right and 3 below a`.
|
|
295
296
|
|
|
296
297
|
**How far along the side it faces.** `right of server 3/4 down` puts the box the usual gap right of `server`, its middle level with a spot three quarters of the way down `server`'s right side. `down` and `up` run along a left or right side, `across` along a top or bottom one. A word that doesn't run along the side the direction faces is refused, listing the words that do.
|
|
297
298
|
|
|
@@ -684,14 +685,16 @@ node rack.b "web-2"
|
|
|
684
685
|
|
|
685
686
|
### Markup
|
|
686
687
|
|
|
687
|
-
A stretch of text can borrow a style's
|
|
688
|
+
A stretch of text can borrow a style's text color and size:
|
|
688
689
|
|
|
689
690
|
```
|
|
690
|
-
style dim text: (color: theme-muted)
|
|
691
|
+
style dim text: (color: theme-muted, size: small)
|
|
691
692
|
node files "shared folder / [dim]synced[/dim]"
|
|
692
693
|
```
|
|
693
694
|
|
|
694
|
-
The opener names a style, never a color, so the marked words borrow a meaning the file already has. A name no style answers to is refused, and so is a style that
|
|
695
|
+
The opener names a style, never a color, so the marked words borrow a meaning the file already has. A name no style answers to is refused, and so is a style that gives text neither a color nor a size.
|
|
696
|
+
|
|
697
|
+
**A line is as tall as its largest text.** A line that is all small is spaced as a small line, so the box is shorter. A small stretch mid-line, `"3 [dim]files[/dim] waiting"`, sits on the same baseline as the words around it, and the line keeps the normal spacing. With `wrap:`, a small character counts as less than a whole one, by the ratio of the two sizes. The closer repeats the name, so a mismatched close is refused by name. Marks don't nest, and a mark may cross a line break. A bare `[` is an error; write `\[` for a literal one.
|
|
695
698
|
|
|
696
699
|
## Lines
|
|
697
700
|
|
|
@@ -974,11 +977,19 @@ A line may carry several texts, one after another, each with its own bracket. **
|
|
|
974
977
|
|
|
975
978
|
**Beside the line:** `(right of edge)`, `(left of edge)`, `(above edge)`, `(below edge)` move the text out the stated way until it is clear of the part of the line it landed on.
|
|
976
979
|
|
|
980
|
+
How far it moves can be said in front:
|
|
981
|
+
|
|
982
|
+
- `(at: 4/5, 1 above edge)`: one unit up from where it would sit on the line. If that is short of clear, the text still crosses the line and hides it there.
|
|
983
|
+
- `(at: 4/5, 1/2 clear above edge)`: half of the move that would clear the line. Any fraction or number works, `3/4 clear` or `1.5 clear`.
|
|
984
|
+
- `(at: 4/5, clear above edge)`: all the way clear, the same as `above edge`.
|
|
985
|
+
|
|
986
|
+
A distance is a number, `0.5 above edge`; `1/2 above edge` is refused, naming both forms. `edge-gap:` beside a distance is refused as said twice.
|
|
987
|
+
|
|
977
988
|
**Lined up with a box on one axis:** `(left even with a right)` puts the left edge of the patch behind the text at `a`'s right side, and leaves its height where it would otherwise sit; `(x even with mid1)` centers the text across on `mid1`. Any `even with` a box takes works, one per axis, and the other axis comes from the line. On a level stretch it slides the text along the line; on an upright one, it moves the text off the line sideways. With a relation that already says the same axis, such as `right of edge`, it is refused. Separate it from the bracket's next item with a comma.
|
|
978
989
|
|
|
979
990
|
**Which way it reads:** `reads: up` and `reads: down` turn it a quarter turn; `reads: along` takes the line's angle where it sits, never upside down.
|
|
980
991
|
|
|
981
|
-
`gap:` is the distance from the box for `at: start`, `at: end` and the box relations; `edge-gap:` the distance
|
|
992
|
+
`gap:` is the distance from the box for `at: start`, `at: end` and the box relations; `edge-gap:` the distance past clear for a text beside it, and part of the move that `1/2 clear` takes a fraction of. Each defaults to half a unit, written in the text's own bracket.
|
|
982
993
|
|
|
983
994
|
```
|
|
984
995
|
node a
|
|
@@ -1052,7 +1063,7 @@ node nas "NAS" right of mirror
|
|
|
1052
1063
|
edge mirror -> nas style: backup
|
|
1053
1064
|
```
|
|
1054
1065
|
|
|
1055
|
-
A style is a named bundle of appearance, worn with `style:`. Color carries meaning through the style's name rather than being written per thing. A style takes `fill`, `border`, `line`, `text`, `badge`, `icon`, `shape`, `from-mark`, `to-mark`, `padding`, `corners` and a region's `opacity`, and a title's position inside `text: (…)`: `style zone text: (outside top, align: left)`. It never says where a thing goes, so it can't carry a placement, a `gap:`, a `depth:`, or a line's `from:` or `to:`, and it can't carry a `url:` or a deck's `cards:`.
|
|
1066
|
+
A style is a named bundle of appearance, worn with `style:`. Color carries meaning through the style's name rather than being written per thing. A style takes `fill`, `border`, `line`, `text`, `badge`, `icon`, `shape`, `from-mark`, `to-mark`, `padding`, `corners` and a region's `opacity`, and a title's position inside `text: (…)`: `style zone text: (outside top, align: left)`. It never says where a thing goes, so it can't carry a placement, a `gap:`, a `depth:`, or a line's `from:` or `to:`, and it can't carry a `url:`, a `description:` or a deck's `cards:`.
|
|
1056
1067
|
|
|
1057
1068
|
- **A style may span kinds.** It gives each thing only the keys that thing has, so the style above gives nodes their border and lines their color.
|
|
1058
1069
|
- **A style must give a thing at least one key it has.** A style that dresses a thing in nothing is on the wrong thing.
|
|
@@ -1118,7 +1129,7 @@ A default is a style every thing of one kind wears without naming it: `node`, `l
|
|
|
1118
1129
|
|
|
1119
1130
|
A container inside another container is filled a shade further from the page than the one it sits in, so the two read as two backdrops. An invisible container (`shape: none`) doesn't count, and a stated `fill:` wins as always.
|
|
1120
1131
|
|
|
1121
|
-
A default takes the words a style does and may wear a style of its own (`default edge style: quiet`), laid beneath its own words. It is strict about kind, since it names its kind: `default edge fill: red` is refused, pointing to `line:`. `icon:` is a leaf's alone. A default carries no `url:`. Each kind is written once, and `default leaf node` is refused, naming `default leaf`.
|
|
1132
|
+
A default takes the words a style does and may wear a style of its own (`default edge style: quiet`), laid beneath its own words. It is strict about kind, since it names its kind: `default edge fill: red` is refused, pointing to `line:`. `icon:` is a leaf's alone. A default carries no `url:` or `description:`. Each kind is written once, and `default leaf node` is refused, naming `default leaf`.
|
|
1122
1133
|
|
|
1123
1134
|
### The diagram
|
|
1124
1135
|
|
|
@@ -1156,6 +1167,70 @@ node api "Orders API"
|
|
|
1156
1167
|
|
|
1157
1168
|
The same address twice in one `url:` is refused.
|
|
1158
1169
|
|
|
1170
|
+
A link can be declared once, with its name and badge, and used by name. A quoted value after `url:` is an address and an unquoted one is a declared link, and the two mix in one list in the order written:
|
|
1171
|
+
|
|
1172
|
+
```
|
|
1173
|
+
url orders-docs "https://docs.example.com/orders/v2/reference" (name: "Docs", icon: "D" (fill: #3a6ea5, text: white))
|
|
1174
|
+
url orders-code "https://github.com/example/orders/tree/main/services/api" (name: "Code")
|
|
1175
|
+
|
|
1176
|
+
node api "Orders API" url: orders-docs orders-code
|
|
1177
|
+
node worker "Worker" url: orders-docs "https://example.com/runbooks/worker" (name: "Runbook")
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
A declaration may list several links, each a quoted address or another declared name, and a use gives all of them in order:
|
|
1181
|
+
|
|
1182
|
+
```
|
|
1183
|
+
url orders-links orders-docs orders-code "https://wiki.example.com/orders" (name: "Wiki")
|
|
1184
|
+
|
|
1185
|
+
node api "Orders API" url: orders-links
|
|
1186
|
+
```
|
|
1187
|
+
|
|
1188
|
+
A declared link's name and badge are its own, so a bracket after its name in a `url:` is refused; to show it differently, declare another. A declaration may come before or after its use. Refused, each with a message: a name used but never declared, a name declared twice, a declaration that reaches itself through its own list, and a name that starts a placement, such as `below`, since a placement may follow a `url:` on the same statement.
|
|
1189
|
+
|
|
1190
|
+
### Descriptions
|
|
1191
|
+
|
|
1192
|
+
A box or a line can carry a description: text a reader asks for, shown in the panel when it is selected on a page made with `--page`, and never drawn. It can be written three ways.
|
|
1193
|
+
|
|
1194
|
+
On the thing's own statement, quoted:
|
|
1195
|
+
|
|
1196
|
+
```
|
|
1197
|
+
node proxy "Proxy" description: "Forwards each request by its path."
|
|
1198
|
+
```
|
|
1199
|
+
|
|
1200
|
+
At a distance, for things already named, so a long text doesn't crowd the diagram's statements:
|
|
1201
|
+
|
|
1202
|
+
```
|
|
1203
|
+
node proxy "Proxy"
|
|
1204
|
+
node orders "Orders" right of proxy
|
|
1205
|
+
edge to-orders proxy -> orders
|
|
1206
|
+
|
|
1207
|
+
description for orders and to-orders """
|
|
1208
|
+
Owns the order records.
|
|
1209
|
+
|
|
1210
|
+
- `/orders` lands here
|
|
1211
|
+
- see [the docs](https://example.com/orders)
|
|
1212
|
+
"""
|
|
1213
|
+
```
|
|
1214
|
+
|
|
1215
|
+
Or named, for any box or line to take by that name:
|
|
1216
|
+
|
|
1217
|
+
```
|
|
1218
|
+
description replica """
|
|
1219
|
+
One of three identical replicas behind the proxy.
|
|
1220
|
+
"""
|
|
1221
|
+
|
|
1222
|
+
node r1 "Replica 1" description: replica
|
|
1223
|
+
node r2 "Replica 2" description: replica below r1
|
|
1224
|
+
```
|
|
1225
|
+
|
|
1226
|
+
`description:` takes the text quoted, or a description's name unquoted, as `icon:` takes letters quoted and a picture's name bare. `description for` names boxes and named lines, separated by commas or `and`; a name that is neither is refused. A long text goes between `"""` marks, where line breaks are kept and the indentation every line shares is taken off.
|
|
1227
|
+
|
|
1228
|
+
The text is Markdown, in part: paragraphs, lists (`-`, `*` or `1.`), `**bold**`, `*italic*` or `_italic_`, `` `code` `` and links, `[text](https://…)`. Anything else shows as written. A link goes to an `https:`, `http:` or `mailto:` address or a path; any other is refused.
|
|
1229
|
+
|
|
1230
|
+
**In an SVG**, the description is the thing's hover text, with the marks taken out and each link's address after its text. Writing one never moves anything in the drawing.
|
|
1231
|
+
|
|
1232
|
+
A thing has one description: two on one statement, or one there and another from `description for`, are refused. So is a name declared twice. A style and a default carry none.
|
|
1233
|
+
|
|
1159
1234
|
## Errors and findings
|
|
1160
1235
|
|
|
1161
1236
|
An **error** means the file can't be drawn: an unknown key, two placements on one axis, a cycle. Nothing is drawn, and the message names what to write instead. A **finding** is about a picture that was drawn and may not read as meant. A render with findings succeeds.
|
|
@@ -1203,7 +1278,7 @@ reladraw check diagram.reladraw
|
|
|
1203
1278
|
| `--no-checks` | print no findings; errors still print |
|
|
1204
1279
|
| `-v`, `--version` | print the version |
|
|
1205
1280
|
|
|
1206
|
-
`reladraw install-skill` installs the agent skill that came with this version of reladraw, by running `npx skills add` on it with `--copy`.
|
|
1281
|
+
`reladraw install-skill` installs the agent skill that came with this version of reladraw, for every project, by running `npx skills add` on it with `--copy`. `--claude` installs it in `~/.claude/skills`, `--agents` in `~/.agents/skills` (Codex and others), and both may be given; with neither, it asks, or, with no terminal to ask in, refuses and names them. For any other agent it prints the `skills` command to run.
|
|
1207
1282
|
|
|
1208
1283
|
The output is a standalone SVG: every picture is drawn into it as path data, never from a font or a linked file. A web page can draw a diagram in place with `<reladraw-diagram>`; see "In a web page" in the README.
|
|
1209
1284
|
|
|
@@ -1215,7 +1290,7 @@ reladraw render arch.reladraw --page
|
|
|
1215
1290
|
|
|
1216
1291
|
`--page` writes `arch.html`: one self-contained file, for opening in a browser, attaching or committing, that needs nothing running and fetches nothing. The page is in the diagram's own colors, so a dark diagram doesn't sit on a white page, and it is headed with `diagram title:`, or the file's name when there is none. Under the title it says which file it was drawn from and when, such as "drawn from arch.reladraw, 2026-11-05 14:32": the page is a snapshot of the file, and is behind it once the file is edited, until it is rendered again. Drag to pan; scroll, pinch or double-click to zoom; Fit shows the whole diagram and 100% returns it to its own scale. The zoom is always shown, with "Fit" beside it while the whole diagram is in view. There is a full-screen button. The Save menu saves the page itself, as it was written rather than at its current zoom; the `.reladraw` source it was drawn from; or the picture as an SVG or a PNG, as `render` would draw it; or copies the SVG. Each is named after the source file: `arch.html`, `arch.reladraw`, `arch.svg`, `arch.png`. In Chrome and Edge it asks where to save; other browsers put the file with their downloads. The findings are listed beside it in a panel that folds away, and clicking one lights up what its line drew. A box's or a line's name shows under the pointer.
|
|
1217
1292
|
|
|
1218
|
-
**A click on a box or a line selects it**, and never follows a link. The selection is amber; what feeds it is green and what it feeds is red, the lines dashed and moving the way they run; the rest dims. A line runs from the end without an arrowhead when only one end has one, and otherwise from the end written first. The panel beside the drawing names the selection and lists its links, each with its badge, and the boxes it comes from and goes to; a link opens in a new tab, and a box selects it. One line out lights by default, and the panel's button lights everything upstream and downstream. A box with links underlines its text under the pointer. A click on the background or Escape clears the selection.
|
|
1293
|
+
**A click on a box or a line selects it**, and never follows a link. The selection is amber; what feeds it is green and what it feeds is red, the lines dashed and moving the way they run; the rest dims. A line runs from the end without an arrowhead when only one end has one, and otherwise from the end written first. The panel beside the drawing names the selection and lists its links, each with its badge, and the boxes it comes from and goes to; a link opens in a new tab, and a box selects it. One line out lights by default, and the panel's button lights everything upstream and downstream. Its description, if it has one, comes last ([Descriptions](#descriptions)). A box with links underlines its text under the pointer. A click on the background or Escape clears the selection.
|
|
1219
1294
|
|
|
1220
1295
|
Keys: `+` and `-` zoom, `0` fits, `1` is actual size, `f` is full screen, Escape clears the selection.
|
|
1221
1296
|
|
|
@@ -1290,6 +1365,7 @@ Every attribute, and what takes one. A node's kind is what its body is: a box (`
|
|
|
1290
1365
|
| `gather-children` | ✓ | | ✓ | | where the children sit in spare room |
|
|
1291
1366
|
| `heading` | ✓ | | ✓ | | the child that is the title |
|
|
1292
1367
|
| `join-with` | ✓ | ✓ | ✓ | | the thing this moves with |
|
|
1368
|
+
| `description` | ✓ | ✓ | ✓ | ✓ | text for the page's panel ([Descriptions](#descriptions)) |
|
|
1293
1369
|
| `padding` | ✓ | | ✓ | | room inside the edge |
|
|
1294
1370
|
| `padding-top`, `-right`, `-bottom`, `-left` | ✓ | | ✓ | | one side's room, over `padding` |
|
|
1295
1371
|
| `width`, `height`, `min-…`, `max-…` | ✓ | | ✓ | | a stated size |
|
|
@@ -1338,6 +1414,24 @@ Designed and absent from the code.
|
|
|
1338
1414
|
|
|
1339
1415
|
Pre-1.0, so the minor number is where a breaking change goes. Every removal is refused by name with the replacement quoted, rather than dropped in silence: an older file stops with an error saying what to write instead.
|
|
1340
1416
|
|
|
1417
|
+
**0.25.0**
|
|
1418
|
+
|
|
1419
|
+
- **A link can be declared once and used by name**: `url orders-docs "https://…" (name: "Docs", icon: "D")`, then `url: orders-docs`, so long addresses stay out of the statements that link to them. A declaration may list several links, declared names among them, and a `url:` mixes names and quoted addresses. See [Destinations](#destinations).
|
|
1420
|
+
|
|
1421
|
+
- **Marked text takes its style's size**: with `style dim text: (size: small)`, `"Some Node / [dim]something[/dim]"` draws the second line small, and a line that is all small is spaced as one. Markup used to take only a style's color, and a style with only a size was refused as saying nothing about text. See [Markup](#markup).
|
|
1422
|
+
|
|
1423
|
+
- **`2 right of and 3 below a`** is accepted, the same as `2 right and 3 below a`. It used to be refused with a message that took `and` for the name of a box.
|
|
1424
|
+
|
|
1425
|
+
- **`right of a and 2 above c top` is two placements**: `b` right of `a`, and its bottom 2 above `c`'s top. A distance and a direction after `and` or a comma used to add a point to the targets, so `b` was placed right of the region round `a` and that point, with no warning, and the second half looked ignored. A point meant as a target is named first with `point`.
|
|
1426
|
+
|
|
1427
|
+
- **A box or a line can have a description**, shown in the panel when it is selected on a `--page` page, and as hover text in an SVG. It is written on the thing, `description: "Forwards each request by its path."`; at a distance, `description for orders and to-orders """…"""`; or named, `description replica """…"""`, and taken with `description: replica`. The text is a small part of Markdown: paragraphs, lists, bold, italic, code and links.
|
|
1428
|
+
|
|
1429
|
+
- **A line's text can rise a stated amount off its line, or part of the way clear.** `above edge` and its kin always moved a text all the way clear, which on a slanted line can be well away from it. `(1 above edge)` now raises it one unit from its spot on the line, still crossing the line if that is short of clear, and `(1/2 clear above edge)` moves it half the way. `(1 above edge)` used to be refused, pointing to `edge-gap:`.
|
|
1430
|
+
|
|
1431
|
+
**0.24.0**
|
|
1432
|
+
|
|
1433
|
+
- **`reladraw install-skill` installs for Claude Code, the `~/.agents` folder, or both, and asks which.** It used to pass everything on to `skills`, which, given no agent, put a copy in the folder of every agent it knows, more than fifty of them, and in the current project unless `-g` was written. It now always installs for every project, in the places `--claude` and `--agents` name; `-a` and the other `skills` options are refused with the `skills` command that does the same, and `-g` is still accepted.
|
|
1434
|
+
|
|
1341
1435
|
**0.23.1**
|
|
1342
1436
|
|
|
1343
1437
|
- **`reladraw format` no longer fails on a comment between a placement and its bracket**, such as `right of a`, then `// why wide`, then `(gap: wide)` on lines of their own. It stopped with "Cannot read properties of undefined"; it now keeps the comment where it was. Reported in #22.
|
package/dist/ast.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* The shape a source file parses into. Nothing here knows about geometry —
|
|
3
3
|
* these types are a faithful record of what the author wrote, and no more.
|
|
4
4
|
*/
|
|
5
|
+
import type { LinkEntry } from './links.js';
|
|
5
6
|
export declare const DIRECTIONS: readonly ["above", "below", "left", "right", "above-left", "above-right", "below-left", "below-right"];
|
|
6
7
|
export type Direction = (typeof DIRECTIONS)[number];
|
|
7
8
|
export declare function isDirection(word: string): word is Direction;
|
|
@@ -443,6 +444,17 @@ export interface EdgeTextPlace {
|
|
|
443
444
|
onLine?: boolean;
|
|
444
445
|
/** `right of edge`: moved clear of the part of the line it landed on. */
|
|
445
446
|
beside?: TextSide;
|
|
447
|
+
/**
|
|
448
|
+
* How far a text beside its line moves, from its spot on the line, the stated way:
|
|
449
|
+
* `2 above edge` a distance; `clear above edge` (1) or `1/2 clear above edge` a
|
|
450
|
+
* fraction of the move that clears the line, `edge-gap:` included. Unstated, it is
|
|
451
|
+
* `clear`. Either may leave the text across its line, and that is meant.
|
|
452
|
+
*/
|
|
453
|
+
rise?: {
|
|
454
|
+
distance?: string;
|
|
455
|
+
clear?: number;
|
|
456
|
+
written: string;
|
|
457
|
+
};
|
|
446
458
|
/**
|
|
447
459
|
* `left even with x right`: one axis set by a box, at most one per axis; the
|
|
448
460
|
* other stays where the text would otherwise sit (design.org 7.3).
|
|
@@ -812,7 +824,41 @@ export interface IconStmt {
|
|
|
812
824
|
};
|
|
813
825
|
line: number;
|
|
814
826
|
}
|
|
815
|
-
|
|
827
|
+
/** Where `description: notes` keeps the name until `resolve` swaps in the text. */
|
|
828
|
+
export declare const DESCRIPTION_NAME_KEY = "description.name";
|
|
829
|
+
/**
|
|
830
|
+
* `description for proxy, cache """…"""` attaches one text to things already
|
|
831
|
+
* named; `description notes """…"""` declares a named one, which a box or a
|
|
832
|
+
* line takes with `description: notes`. The text is a small Markdown subset,
|
|
833
|
+
* shown in the page's panel and, marks stripped, as an SVG's hover text.
|
|
834
|
+
*/
|
|
835
|
+
export interface DescriptionStmt {
|
|
836
|
+
kind: 'description';
|
|
837
|
+
/** The declared name, for the named form. */
|
|
838
|
+
name?: string;
|
|
839
|
+
/** The boxes and lines named after `for`, for the at-a-distance form. */
|
|
840
|
+
targets?: string[];
|
|
841
|
+
text: string;
|
|
842
|
+
line: number;
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Where a `url:` that names declared links keeps its list, declared names and
|
|
846
|
+
* quoted addresses in the order written, until `resolve` swaps each name for
|
|
847
|
+
* the links it declares.
|
|
848
|
+
*/
|
|
849
|
+
export declare const LINK_NAMES_KEY = "url.names";
|
|
850
|
+
/**
|
|
851
|
+
* `url orders-docs "https://…" (name: "Docs", icon: "D")` declares a link once,
|
|
852
|
+
* with its name and badge, for `url: orders-docs`. A declaration may hold
|
|
853
|
+
* several links, each a quoted address or another declared name: a bundle.
|
|
854
|
+
*/
|
|
855
|
+
export interface UrlStmt {
|
|
856
|
+
kind: 'url';
|
|
857
|
+
name: string;
|
|
858
|
+
entries: LinkEntry[];
|
|
859
|
+
line: number;
|
|
860
|
+
}
|
|
861
|
+
export type Stmt = NodeStmt | EdgeStmt | StyleStmt | DiagramStmt | DefaultStmt | IconStmt | PointStmt | RegionStmt | BundleStmt | DescriptionStmt | UrlStmt;
|
|
816
862
|
export interface Document {
|
|
817
863
|
statements: Stmt[];
|
|
818
864
|
}
|