reladraw 0.21.0 → 0.22.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,209 @@
1
+ ---
2
+ name: reladraw
3
+ description: Write, render and edit diagrams in reladraw, a text diagram language where you say where things go, so the arrangement can be read back out of the source without looking at the picture. Use when asked to draw, diagram, sketch or visualize an architecture, a system, a data flow, a pipeline, a deployment, a directory layout, or the shape of a change or pull request; when reading or editing a .reladraw file; or when the user says "reladraw", "diagram this", "draw the architecture", "show me how these pieces fit". Use it in place of Mermaid, Graphviz, D2 or hand-drawn ASCII boxes whenever a node-and-line diagram is wanted and reladraw is installed. NOT for charts of data — bar, line, pie, scatter — and NOT for pictures that are not nodes and lines.
4
+ ---
5
+
6
+ # reladraw
7
+
8
+ A text language for diagrams. Source in, standalone SVG out, no runtime dependencies.
9
+
10
+ Every other diagram language hands the arrangement to a layout engine, so where things land is an output you can't predict from what you wrote. reladraw inverts that: the file states the arrangement in the terms a person would say out loud (`right of api`, `below worker (gap: tight)`, `even with queue`), and the tool draws exactly that. It never chooses an arrangement, never moves a box to make room, and never routes a line round anything.
11
+
12
+ That matters here specifically. You can't see the SVG you produced. With auto-layout that leaves you guessing; with reladraw the arrangement is in the sentences you just wrote, and where the picture may not read as meant, the tool tells you in words.
13
+
14
+ **Show every diagram as its page.** Whenever the user is to see a diagram, whether one you drew, one you changed, or an existing file they asked to look at, render it with `--page` and open it in the default browser, as step 7 of the loop says. The bare SVG is for putting into something else, such as a README or a document, not for showing.
15
+
16
+ ## Check it is installed, and the same version as this skill
17
+
18
+ This skill teaches reladraw 0.22.1. Once per session, before the first render, run:
19
+
20
+ ```
21
+ reladraw --version
22
+ ```
23
+
24
+ - **The same:** say nothing.
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 -g`, which 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
+
28
+ If `reladraw` isn't installed, `npx reladraw` works without installing, and `npm install -g reladraw` installs it.
29
+
30
+ ## The loop
31
+
32
+ 1. Write a `.reladraw` file.
33
+ 2. `reladraw render diagram.reladraw -o diagram.svg`. (`-o -` writes to stdout; the default is the input path with `.svg`.)
34
+ 3. If it fails, the **error** names the line and what to write instead. Fix and re-run.
35
+ 4. If it succeeds, read the **findings** it printed. Each is one line saying what may not read as meant, where, and how much:
36
+
37
+ ```
38
+ diagram.reladraw:12: warning(text-overlap): text "statements" covers the top-left corner of node resolver; the overlap is 3 units wide and 2 units tall
39
+ diagram.reladraw:9: warning(edge-node-overlap): line api -> db crosses node cache, in and out of its top
40
+ ```
41
+
42
+ 5. Fix each finding in the source, by placing something differently or saying where a line goes, and re-run until there are none. `reladraw check diagram.reladraw` prints the findings without writing the SVG.
43
+ 6. `reladraw format diagram.reladraw` before handing the file over. It lines statements up in columns and evens out spacing, by the project's `.reladraw-format` if there is one, and changes nothing about what the file draws. A file you wrote then reads like one the user's project already has.
44
+ 7. Finish by showing the user the picture. Give the diagram a title with `diagram title: "…"`, which heads the page, then run `reladraw render diagram.reladraw --page`. It writes `diagram.html`, a page in the diagram's own colors that pans, zooms, goes full screen and saves an SVG or PNG. Open it in the default browser: `xdg-open diagram.html` on Linux, `open diagram.html` on macOS, `start diagram.html` on Windows. Show the page rather than the bare SVG, and don't build a page of your own around it. Open it once per diagram; after later edits, render the page again and tell the user to reload it. Don't open it when there is no display to open it on, as in a remote or headless session, or when the user has said not to; give them the page's path instead.
45
+
46
+ A file with no errors and no findings has nothing on top of anything. That is still not the same as a good picture: re-read your source to confirm the arrangement says what you meant, and for a large diagram tell the user you have checked the findings but not seen the render.
47
+
48
+ ## The one idea
49
+
50
+ **The file says where things go, and the tool draws exactly that.** A gap is the distance you wrote. A box goes where its placements put it and nothing pushes it. A line is straight between its two boxes unless you say it is square or curved or name the places it passes. Anything that overlaps is drawn overlapping and reported.
51
+
52
+ So the fix for a problem is always more said in the source, never hoping the tool will sort it out. Two boxes on one spot: place one against the other. A line through a box: say where it passes with `via:`. A text crowding a box: widen the gap.
53
+
54
+ ## Writing a file
55
+
56
+ A statement starts at the beginning of a line. A long one continues onto following lines that are indented; a blank or unindented line ends it. Indentation never puts one thing inside another. `//` starts a comment and may trail a statement.
57
+
58
+ A statement is a positional head (the keyword, a name, then a text) followed by attributes and placements **in any order**. A word ending in a colon opens an attribute and nothing else does.
59
+
60
+ ### Nodes
61
+
62
+ ```
63
+ node <name> ["<text>" [(<text settings>)]] [<placement> | <attribute>] ...
64
+ ```
65
+
66
+ Leave the text out and the node shows its name (`node parser` reads "parser"). Write `""` for a deliberately blank node. Inside a text, ` / ` (a slash with a space on each side) is a line break; `TCP/IP` and URLs survive.
67
+
68
+ The body is `shape: rectangle | document | circle | diamond | pill | parallelogram | hexagon | trapezoid | triangle | cylinder | none` (`none` is bare text, for notes and captions; a flowchart shape with no geometric name is `flow-` and its meaning, such as `flow-subprocess` or `flow-delay`; settings follow in a bracket, `shape: triangle (aim: up)`) or `icon: disk | desktop | laptop | package | cubes | cube | database`, a picture with no box. `badge: <icon>` puts a picture beside the text as part of the label. A picture outside the set is declared with `icon <name>` and SVG between `"""` marks; prefer the built-ins.
69
+
70
+ ```
71
+ node dump "nightly dump" shape: document
72
+ node unit icon: cube right of dump
73
+ node drive "External HD" badge: disk below dump
74
+ node aside "a remark that folds" (wrap: 20) shape: none right of drive
75
+ ```
76
+
77
+ ### Placing
78
+
79
+ ```
80
+ above X below X left of X right of X
81
+ above-left of X above-right of X below-left of X below-right of X
82
+ even with X top even with X bottom even with X left even with X right even with X
83
+ ```
84
+
85
+ - **Exactly one node in the file is unplaced**, the anchor. Every other is placed against something, directly or through others.
86
+ - **A gap is exact**: `none`, `tight`, `normal` (the default) or `wide`, in the placement's bracket, `right of a (gap: tight)`, or a number of the file's unit in front, `2 right of a`. A normal box is about 4 units tall.
87
+ - **A lone direction also centers on its target.** `right of a` alone puts the box level with `a`. Another placement on that axis replaces the centering: `right of a even with b`.
88
+ - **Each axis is stated once.** Two placements on one axis are refused. The one exception: `right of a left of b` centers the box in the space between them, and then something must say how high.
89
+ - **Several targets are one region**: `below a and b` sits under the pair, centered between them.
90
+ - **Nothing moves a box.** Two boxes placed `right of a` both land on one spot and are reported. Chain them (`b right of a`, `c right of b`) or put them in a container with a layout.
91
+
92
+ ### Containers
93
+
94
+ A dotted name is a child: `server.api` is inside `server`, and the parent is declared first. A container is the box round its children. Arrange them one of two ways:
95
+
96
+ ```
97
+ node server "Server" layout: column (widths: match)
98
+ node server.api "API"
99
+ node server.worker "Worker"
100
+
101
+ node lab "Lab" right of server (gap: wide)
102
+ node lab.pc "PC"
103
+ node lab.nas "NAS" right of lab.pc (gap: tight)
104
+ ```
105
+
106
+ `layout: column` or `layout: row` puts the children in written order; its bracket takes `gap:`, `widths: match`, and `align-children: left | center | right`. Without a layout, exactly one child is unplaced and the rest are placed against it. `shape: none` on a container draws no box, which makes a group you can place things against as one shape.
107
+
108
+ A title goes `(inside top)` by default, centered along it; `(inside top, align: left)` puts it at the top left, and `(on top)` or `(outside top)` sit it on or above the border.
109
+
110
+ ### Text
111
+
112
+ Everything a text says about itself goes in brackets after it: `color`, `size` (`small | normal | large`), `wrap` (fold every n characters) and `align`.
113
+
114
+ ```
115
+ style dim text: (color: theme-muted)
116
+ node grinder "Grinder / [dim]medium-fine[/dim]"
117
+ node note "a longer remark that folds" (size: small, wrap: 30) shape: none below grinder (gap: tight)
118
+ ```
119
+
120
+ `[dim]…[/dim]` borrows a style's look for a stretch of text. 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
+
122
+ ### Lines
123
+
124
+ ```
125
+ edge [<name>] <from> -> <to> ["<text>" [(<placement>)]] [attributes]
126
+ ```
127
+
128
+ `<-`, `<->` and `--` work too, and each end may carry a mark: `a <|-- b`, `a *--o b`, `a diamond--> b`. `from:` and `to:` name the side of the first and second name written: `from: right to: left`.
129
+
130
+ - **Straight by default**, between the two boxes and through anything in between, which is reported. `line: (path: square)` or `line: (path: curved)` for a route read off the line's own two boxes and sides.
131
+ - **`via:` lists the places a line passes**: `via: cache top` runs just above `cache`; `via: between a and b` goes through the point between them; `via: proxy` goes through a box's center. This is how to take a line round something.
132
+ - **A text sits at the middle of its line.** Place it with `(at: start)`, `(at: 1/4)`, `(above edge)`, `(on: longest level)` or `(above some_box)`. Texts never move boxes, so give a labeled line room: a `normal` gap is too short for a word, so use `(gap: 12)` or so between boxes joined by a labeled line.
133
+ - `line: (pattern: dashed, thickness: thick, corners: rounded, color: #d2904e)`; `line: red` alone is the color.
134
+
135
+ ### Against a part of a box
136
+
137
+ ```
138
+ node bob "Bob the builder" (inside top) height: 7
139
+ node bob_role "builder" (size: small) inside bob bottom-center shape: none
140
+ node count "3" on bob top-right shape: circle
141
+ ```
142
+
143
+ A box's parts are its `text`, its sides `top`, `bottom`, `left`, `right`, and nine points (`top-left`, `top-center`, … `center` … `bottom-right`). `inside` tucks a node within the box against that part, `outside` puts it beyond, `on` centers it on the part.
144
+
145
+ A child `inside` its own parent's corner is placed against the finished box and never grows it, so it can land on the parent's text or other children. `stays above`, `stays below`, `stays left of` or `stays right of` a sibling (or `parent text`) keeps it clear, and the box makes room: `node laptop.mark icon: laptop inside laptop top-right stays above laptop.photos`. A picture beside a box's only text goes against the text instead: `1 right of drive text`.
146
+
147
+ ### Styles and colors
148
+
149
+ ```
150
+ style store fill: theme-primary-subtle border: theme-primary badge: database
151
+ node records "Records" style: store
152
+ ```
153
+
154
+ `fill` is a box's area, `border` its outline, `line` an edge's line, and a text's color goes in its bracket. `corners: sharp` squares a box's rounded corners, and `border: (color: theme-primary, thickness: thick)` thickens its outline, the box growing to keep its padding. Prefer theme colors, which read in light and dark themes alike: `theme-primary` and `theme-secondary` are the accents, `-subtle` is an accent softened toward the page (the one to fill a box with), `theme-muted` is quieter text. A hex or CSS color stays fixed in every theme.
155
+
156
+ ### Links
157
+
158
+ ```
159
+ node docs "Documentation" url: "https://example.com/docs"
160
+ edge api -> db "SQL" url: "https://example.com/schema"
161
+ ```
162
+
163
+ **A link goes on the thing it is about, never in a text of its own.** Give the node a `url:`, or give it to a line's text when the link is about the connection. The whole box, or the line's text, becomes clickable. When asked to add links to a diagram, put `url:` on the nodes and lines already there. Don't add nodes to hold links: no column of link texts beside the diagram, and no caption with an address under each box. Add one only when the user asks to see the addresses written out.
164
+
165
+ ```
166
+ // Wrong: a new text beside the thing the link belongs to
167
+ node api_link "github.com/acme/api" shape: none right of api
168
+
169
+ // Right: the link is on the thing itself
170
+ node api "API server" url: "https://github.com/acme/api"
171
+ ```
172
+
173
+ The address is never drawn; a reader follows it by clicking. A line with no text can't carry one, and neither can a style. Quote the value, since an unquoted `//` starts a comment.
174
+
175
+ **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
+
177
+ ## A complete small file
178
+
179
+ ```
180
+ // A request path, left to right.
181
+ style store fill: theme-primary-subtle border: theme-primary badge: database
182
+
183
+ node browser "Browser"
184
+ node api "API server" right of browser (gap: 10)
185
+ node db "Postgres" right of api (gap: 10) style: store
186
+ node worker "Worker" below api (gap: wide)
187
+
188
+ edge browser -> api "HTTP"
189
+ edge api -> db "SQL"
190
+ edge worker -> db "writes" to: bottom line: (path: square)
191
+
192
+ node aside "The worker shares the database / but takes no HTTP traffic." (wrap: 30) shape: none below worker (gap: tight)
193
+ ```
194
+
195
+ ## What will bite you
196
+
197
+ - **Two boxes placed the same way.** `node b right of a` and `node c right of a` put `b` and `c` on one spot. Place `c` against `b`, or use a container with `layout:`.
198
+ - **A labeled line between close boxes.** The text sits on the line and nothing widens the gap, so it covers the boxes and is reported. Give the placement a larger gap.
199
+ - **Two unplaced boxes.** Only one may be. The error names both.
200
+ - **Saying an axis twice.** `right of a even with a` is fine; `below a even with b` is two statements about height, and refused.
201
+ - **Old syntax.** `level with` is `even with`; `gap:` on a node goes in a placement's bracket; edge clauses like `below c` and `between a and b` are `via: c bottom` and `via: between a and b`; `contents:` is `layout: column (…)`; `at:` on a node's text is `(inside top, align: left)` and the like; `deck:` is a container, `layout: deck cards: "Drive 1" "Drive 2"`. Each is refused with what to write instead.
202
+ - **`note`, `box` or `link`.** Not statements: a note is `node … shape: none`, and the keywords are `node` and `edge`.
203
+ - **A coordinate.** None exist. Every position is relative to something in the diagram.
204
+ - **`#` as a comment.** It opens a hex color; comments are `//`.
205
+ - **Guessing from another language.** No braces, no semicolons, no subgraphs. If you want something not written here, check `reference/syntax.md` before inventing it.
206
+
207
+ ## Reference
208
+
209
+ [reference/syntax.md](reference/syntax.md) is the full syntax reference: every construct, points and regions, waypoints and named legs, bundles, sizes, guides, drawing order, the findings, what the language refuses and why, and what changed in each version. Read it when you need a construct this page doesn't cover, or when an error or a finding points at behavior you didn't expect.