@meltemi/diagrams-cli 1.9.0 → 1.11.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.
- package/agent-setup/prompt.md +83 -0
- package/dist/assets-command.d.ts.map +1 -1
- package/dist/assets-command.js +15 -0
- package/dist/assets-command.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +11 -1
- package/dist/cli.js.map +1 -1
- package/dist/export-command.d.ts.map +1 -1
- package/dist/export-command.js +16 -3
- package/dist/export-command.js.map +1 -1
- package/dist/init-command.d.ts.map +1 -1
- package/dist/init-command.js +6 -3
- package/dist/init-command.js.map +1 -1
- package/dist/messages/en.d.ts +45 -7
- package/dist/messages/en.d.ts.map +1 -1
- package/dist/messages/en.js +82 -9
- package/dist/messages/en.js.map +1 -1
- package/dist/messages/es.d.ts.map +1 -1
- package/dist/messages/es.js +79 -8
- package/dist/messages/es.js.map +1 -1
- package/dist/messages/index.d.ts +41 -6
- package/dist/messages/index.d.ts.map +1 -1
- package/dist/skill-command.d.ts +48 -0
- package/dist/skill-command.d.ts.map +1 -0
- package/dist/skill-command.js +148 -0
- package/dist/skill-command.js.map +1 -0
- package/package.json +25 -18
- package/skills/.skills-sync.json +5 -0
- package/skills/meltemi-diagrams/SKILL.md +232 -0
- package/skills/meltemi-diagrams/examples/architecture.meltemi +73 -0
- package/skills/meltemi-diagrams/examples/platform.meltemi +139 -0
- package/skills/meltemi-diagrams/examples/sequence.meltemi +52 -0
- package/skills/meltemi-diagrams/examples/slide.meltemi +60 -0
- package/skills/meltemi-diagrams/examples/story.meltemi +53 -0
- package/skills/meltemi-diagrams/reference/c4.md +92 -0
- package/skills/meltemi-diagrams/reference/cloud.md +19 -0
- package/skills/meltemi-diagrams/reference/converting.md +101 -0
- package/skills/meltemi-diagrams/reference/free.md +327 -0
- package/skills/meltemi-diagrams/reference/language.md +245 -0
- package/skills/meltemi-diagrams/reference/layout.md +165 -0
- package/skills/meltemi-diagrams/reference/sequence.md +143 -0
- package/skills/meltemi-diagrams/reference/stories.md +94 -0
- package/skills/meltemi-diagrams/reference/themes.md +148 -0
- package/templates/kanban/diagrams/board.meltemi +57 -0
- package/templates/whiteboard/diagrams/whiteboard.meltemi +59 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# Free compositions
|
|
2
|
+
|
|
3
|
+
Use `diagram <id>: free { }` for a slide, an executive picture, a whiteboard, a kanban board or an
|
|
4
|
+
explanation that does not fit a flow notation. Objects are placed by hand (`layout manual` is the
|
|
5
|
+
default); relations, `placement`, constraints, `style`, `class`, `rule`, `animate`, themes,
|
|
6
|
+
`preset` and `canvas` work as in flow diagrams. A whiteboard writes `preset board`: the canvas
|
|
7
|
+
grows with its content and never reports `layout.too-large`.
|
|
8
|
+
|
|
9
|
+
## Objects
|
|
10
|
+
|
|
11
|
+
| Declaration | Object | Default size |
|
|
12
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------- |
|
|
13
|
+
| `box <id> "Label"`, `id["L"]` | a shape with a label and an optional `description` | its shape's size, widened to its text |
|
|
14
|
+
| `id[("Label")]` | a box with the `cylinder` shape | 160 × 64 |
|
|
15
|
+
| `text <id> "Text\nmore"` | measured text without a frame | its extent |
|
|
16
|
+
| `icon <id> "tabler:server"` | an icon of the packs; find names with `pnpm mdg assets icons <w>` | 48 × 48 |
|
|
17
|
+
| `image <id> "img/logo.png"` | a PNG, JPEG, GIF, WebP or SVG file of the project, relative to the file | its pixel size, at most 640 wide |
|
|
18
|
+
| `note <id> "Text" [on <element>]` | an annotation: text with no frame until styled, and a dotted leader to the element it is attached to (below) | its text's extent |
|
|
19
|
+
| `sticky <id> "Text"` | a sticky note: a square card whose text wraps and shrinks to fit (below) | 160 × 160, never grown |
|
|
20
|
+
| `group <id> "Label" { ... }` | a band holding objects and relations; `group <id> "" { }` is plain; `layout column` makes it a list (below) | written, or fitted to children |
|
|
21
|
+
| `line <id> from (x, y) to (x, y)` | a line that joins no element: a divider, a bracket, an underline (below) | the bounding box of its points |
|
|
22
|
+
| `pen <id> [(x, y), (x, y), ...]` | a freehand stroke: handwriting, a drawn arrow, a highlighter mark (below) | its points' box plus half its width |
|
|
23
|
+
|
|
24
|
+
`node`, `decision`, `data` and `tag` are flow kinds and are refused here; `note`, `sticky` and
|
|
25
|
+
`pen` are free kinds. Relations take the lines without heads `a -- b` and `a --- b` too.
|
|
26
|
+
|
|
27
|
+
## Notes
|
|
28
|
+
|
|
29
|
+
`note remark "Checked at the gateway" on gateway { layer front }` is text at the theme's note size in
|
|
30
|
+
the muted colour, left-aligned and without a frame. `style remark { fill "#fff7d6"; stroke warning;
|
|
31
|
+
line dashed }` gives it an outline (any of `fill`, `stroke` or `pattern` does); `font`, `fontSize`,
|
|
32
|
+
`fontWeight`, `textAlign`, `radius`, `color`, `icon` and `rotation` apply, `shape` does not. The
|
|
33
|
+
block takes `description`, `class`, `layer`, `link` and `url`. `on <element>` attaches the note to
|
|
34
|
+
any other element of the diagram: a dotted leader joins them, `layout auto` keeps them near each
|
|
35
|
+
other, renaming the element rewrites the clause, and deleting the element leaves the note. An
|
|
36
|
+
unknown target is `ref.unknown-element`; a note on itself, `prop.invalid-value`. A note with an
|
|
37
|
+
outline can take `animate remark { effect dash }`; without one, only a pulse.
|
|
38
|
+
|
|
39
|
+
## Stickies
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
sticky cache "Cache the catalogue at the edge before the sale"
|
|
43
|
+
sticky retry "Retry payments\nonce"
|
|
44
|
+
style retry { fill "#f8bbd0"; rotation 4 }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- A 160 × 160 card (scaled with the theme's `labelSize`, or its `size`) that never grows: the
|
|
48
|
+
text wraps at spaces inside the theme's `padding`, at `fontSize` or 1.2 × the label size
|
|
49
|
+
(15.6 px), and shrinks 1 px at a time down to 8 px until it fits. Text that still does not fit
|
|
50
|
+
is `layout.text-overflow` (warning) and clipped: shorten it or use the `size` in the hint.
|
|
51
|
+
- Colours: the theme's `sticky` card (`#fff59d` on light themes) and `stickyText` text; `fill`
|
|
52
|
+
and `color` override them. Common fills: yellow `#fff59d`, pink `#f8bbd0`, green `#c8e6c9`,
|
|
53
|
+
blue `#bbdefb`, orange `#ffe0b2`, purple `#e1bee7`. A soft shadow, `radius` 2, an outline only
|
|
54
|
+
with `stroke`. Text is centred (`textAlign`, `verticalAlign`); an `icon` sits top left.
|
|
55
|
+
- Takes `fill`, `stroke`, `color`, `line`, `width`, `fontSize`, `fontWeight`, `textAlign`,
|
|
56
|
+
`verticalAlign`, `radius`, `rotation`, `opacity`, `icon`, `iconColor`, `iconSize`; `shape`,
|
|
57
|
+
`pattern`, `iconPosition` and `labelPosition` are `prop.invalid-value`. `rule sticky { }` styles
|
|
58
|
+
them all.
|
|
59
|
+
- A sticky is a box for everything else: `place`, `size`, ports, constraints, relation endpoints
|
|
60
|
+
(`cache -> retry`), stories and effects. `sticky s` without text is `prop.invalid-value`.
|
|
61
|
+
|
|
62
|
+
## Shapes and corners
|
|
63
|
+
|
|
64
|
+
`style a { shape hexagon }` draws a box (or a flow `node`) as one of twenty-four shapes. Each has a
|
|
65
|
+
default size (technical themes; it scales with the label size), keeps its text inside its outline
|
|
66
|
+
and grows until the text fits, and connectors end on its outline:
|
|
67
|
+
|
|
68
|
+
| Size | Shapes |
|
|
69
|
+
| --------- | ------------------------------------------------------------------------------------ |
|
|
70
|
+
| 160 × 56 | `rounded` (default), `rectangle`, `pill`, `parallelogram`, `arrow`, `framed`, `flag` |
|
|
71
|
+
| 160 × 64 | `cylinder`, `trapezoid`, `hexagon` |
|
|
72
|
+
| 160 × 72 | `ellipse`, `octagon`, `document`, `callout` |
|
|
73
|
+
| 160 × 80 | `diamond` |
|
|
74
|
+
| 160 × 96 | `triangle`, `pentagon` |
|
|
75
|
+
| 160 × 104 | `person` |
|
|
76
|
+
| 160 × 120 | `agent` |
|
|
77
|
+
| 120 × 120 | `square`, `circle`, `star` |
|
|
78
|
+
| 180 × 100 | `cloud` |
|
|
79
|
+
| 64 × 64 | `icon` (or its `iconSize`), the label outside (below) |
|
|
80
|
+
|
|
81
|
+
- `square` and `circle` are a rectangle and an ellipse with a square default size; `arrow` points
|
|
82
|
+
right; `framed` has two inner lines (a subroutine); `callout` has a tail at the bottom left.
|
|
83
|
+
- `person` is a round head over a body; `agent` is an AI agent, a robot head (eyes, mouth and an
|
|
84
|
+
antenna) over a body. Both keep the text in the body; an end on the north side meets the head.
|
|
85
|
+
- `\n` breaks a box's or a node's label into lines, as in a `text`.
|
|
86
|
+
- A `size` too narrow for the text inside a shape is `layout.text-overflow`; use the hint's width.
|
|
87
|
+
- A pinned end (`route r from a.east to d.north 30%`) is drawn where the side's normal meets the
|
|
88
|
+
outline, so arrows touch diamonds, ellipses and stars.
|
|
89
|
+
- `radius 0..64` sets the corner radius of boxes, nodes, notes and groups (`radius 0` squares
|
|
90
|
+
them); `rectangle`, `square` and `framed` are always square, the other shapes ignore it. The
|
|
91
|
+
theme's `radius` (8) and `groupRadius` (14) are the defaults.
|
|
92
|
+
- Decisions, data stores, notes, tags, groups, texts, icons and images refuse `shape`, in `style`
|
|
93
|
+
statements as in rules: their kind is their drawing. Only `rule box` and `rule node` may set it.
|
|
94
|
+
|
|
95
|
+
Text in every profile: `font "<Family>"`, `fontSize 6..160` and `fontWeight 400|500|600|700` on
|
|
96
|
+
whatever draws text (text defaults to 1.6 × the label size, stickies to 1.2 × at 400). Free-only
|
|
97
|
+
text properties (refused in flow diagrams):
|
|
98
|
+
|
|
99
|
+
- `textAlign left|center|right` on boxes, stickies and text (text is left aligned by default);
|
|
100
|
+
- `verticalAlign top|middle|bottom` on boxes (`middle` by default) moves the label, description
|
|
101
|
+
and icon to the top or bottom of the shape's text band, the theme's padding from its edge:
|
|
102
|
+
`style card { shape rectangle; textAlign left; verticalAlign top }` is draw.io's top-left text.
|
|
103
|
+
Ellipses and other narrowing shapes move a wide block back towards the middle until it fits;
|
|
104
|
+
cylinders keep it between the rims, documents above the wave, callouts above the tail. On
|
|
105
|
+
`triangle`, `pentagon`, `star`, `person`, `agent` and `icon` shapes, with `iconPosition center`,
|
|
106
|
+
and on texts, icons, images, groups and lines it moves nothing (`layout.vertical-align-ignored`);
|
|
107
|
+
- `opacity 0..1` fades an element, a group, a line or a pen (`style draft { opacity 0.5 }`);
|
|
108
|
+
relations refuse it;
|
|
109
|
+
- a text, icon or image with `fill`, `stroke` or `pattern` gets a frame.
|
|
110
|
+
|
|
111
|
+
## Lines
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
line divider "Phase 2" from (40, 160) to (520, 160) // a labelled divider
|
|
115
|
+
line bracket from (40, 220) to (520, 280) via [(280, 220)] // bends in a via list
|
|
116
|
+
group notes "Notes" {
|
|
117
|
+
text remark "Read first"
|
|
118
|
+
line underline from (0, 22) to (120, 22) // in the group's interior
|
|
119
|
+
}
|
|
120
|
+
style divider { line dashed; stroke muted }
|
|
121
|
+
style bracket { routing orthogonal; corners rounded; arrowhead triangle }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- A `line` joins nothing: use it for dividers, brackets, underlines and strokes; between two
|
|
125
|
+
boxes write a relation (`a -- b`) so it follows them.
|
|
126
|
+
- Its points are written in the statement, in the parent group's interior like `place`; it takes
|
|
127
|
+
no `place`, `size` or `rotation` (`prop.invalid-value`).
|
|
128
|
+
- It takes a relation's styles: `stroke`, `width`, `line`, `arrowhead` and `arrowtail` (none by
|
|
129
|
+
default), `routing` (`polyline` by default, `orthogonal`, `bezier`), `corners`, and `color`,
|
|
130
|
+
`fill`, `icon` for its label pill; a box's properties (`shape`, `radius`, the text properties)
|
|
131
|
+
are `prop.invalid-value`. `rule line { }` styles every line.
|
|
132
|
+
- The label is the optional second argument, on a pill at 50 %;
|
|
133
|
+
`label divider at 20% offset (0, -14)` in `placement` moves it. `flow`, `dash`, `pulse` and
|
|
134
|
+
`trace` run along a line.
|
|
135
|
+
- A line whose points coincide is drawn as a dot: `layout.degenerate-line`. Flow, sequence and C4
|
|
136
|
+
diagrams refuse `line` (`prop.unknown`).
|
|
137
|
+
|
|
138
|
+
## Pen strokes
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
pen marker [(40, 70), (280, 70)] // declared first: under the text
|
|
142
|
+
text heading "Why the cache helps"
|
|
143
|
+
pen arrow [(216, 140), (250, 128.5), (290, 130), (336, 140)]
|
|
144
|
+
pen dot [(400, 60)] // one point is a dot
|
|
145
|
+
style marker { stroke highlight; width 20; opacity 0.35 } // a highlighter mark
|
|
146
|
+
style arrow { width 4; arrowhead triangle }
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- A freehand stroke: one smooth path through the midpoints of its points (round caps and joins).
|
|
150
|
+
Use it for handwriting, drawn arrows, circles and underlines; use a `line` for a straight
|
|
151
|
+
divider and a relation between two boxes.
|
|
152
|
+
- `pen <id> [(x, y), ...]`: at least one tuple of plain numbers, decimals kept, in the parent
|
|
153
|
+
group's interior like `place`; no label, no `place`, `size` or `rotation`
|
|
154
|
+
(`prop.invalid-value`). `pen p [10, 20]`, `pen p []` and `pen p` are `prop.invalid-value` with
|
|
155
|
+
the form `pen <id> [(x, y), (x, y), ...]` in the hint.
|
|
156
|
+
- Styles: `stroke` (the theme's `ink`), `width` 1..64 (3; `width 0` is refused), `line`,
|
|
157
|
+
`opacity`, `arrowhead`, `arrowtail` (none). Anything else (`fill`, `shape`, `routing`, text
|
|
158
|
+
properties) is `prop.invalid-value`. `rule pen { }` styles every pen.
|
|
159
|
+
- The highlighter is `stroke highlight; width 20; opacity 0.35`; declare it before the text it
|
|
160
|
+
marks so the text is painted over it.
|
|
161
|
+
- Pens take no part in `layout.overlap` or the label checks, are never moved by the engine or a
|
|
162
|
+
list, are not jittered by sketch themes, and run `flow`, `dash`, `pulse` and `trace` like a line.
|
|
163
|
+
A story's `draw a, b over 2s` replays them ([stories.md](stories.md)).
|
|
164
|
+
- `pnpm mdg format` prints a long point list filled to 100 columns, not one point per line.
|
|
165
|
+
|
|
166
|
+
## Icons in boxes and as shapes
|
|
167
|
+
|
|
168
|
+
Flow diagrams take these too. The `icon` of a node, decision, data store or box goes beside the
|
|
169
|
+
text (`iconPosition left`, the default, or `right`), above or below it (`top`, `bottom`), or at the
|
|
170
|
+
centre as the picture of the box (`center`), with the label in a band at the `labelPosition` edge
|
|
171
|
+
inside (`bottom` by default). `shape icon` draws the element as its icon alone, with the label
|
|
172
|
+
outside at `labelPosition`, as provider icons are drawn in architecture diagrams:
|
|
173
|
+
|
|
174
|
+
```text
|
|
175
|
+
box gateway "API Gateway"
|
|
176
|
+
box fn "Checkout"
|
|
177
|
+
box orders "Orders"
|
|
178
|
+
box tile "Orders DB"
|
|
179
|
+
gateway -> fn
|
|
180
|
+
fn -> orders
|
|
181
|
+
|
|
182
|
+
style gateway { icon "aws:api-gateway"; shape icon } // label below the icon
|
|
183
|
+
style fn { icon "aws:lambda"; shape icon; labelPosition top } // label above
|
|
184
|
+
style orders { icon "aws:dynamodb"; shape icon; fill surface; stroke line } // framed
|
|
185
|
+
style tile { icon "tabler:database"; iconPosition center } // 120 × 120 tile
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
- `iconSize` is the icon's side: 8 to 128 (px or unitless) or `auto`. Beside the text the theme's
|
|
189
|
+
18 px is the default; a number grows a box without `size`, and is clamped (never cut) in a box
|
|
190
|
+
with a written `size`, where `auto` fills the room. A centred icon is as large as fits; a
|
|
191
|
+
written `size` without room for an 8 px icon beside the label band is `layout.text-overflow`.
|
|
192
|
+
- An icon shape is a 64 × 64 square (or `iconSize`; a written `size` wins, the icon fitted
|
|
193
|
+
inside), with nothing behind the icon unless `fill`, `stroke` or `pattern` frames it; a frame
|
|
194
|
+
adds half the padding on each side (an 80 × 80 square around a 64 px icon). Arrows, ports and
|
|
195
|
+
anchors end on the square (`to fn.south` is the icon's bottom edge); groups and the canvas
|
|
196
|
+
count the label too, and a box over the label is `layout.overlap`, so leave room for it. A
|
|
197
|
+
connector on the label's side is drawn from beyond the label; other routes go around it.
|
|
198
|
+
- `labelPosition` does nothing unless the icon is the centre piece: `layout.label-position-ignored`.
|
|
199
|
+
`shape icon` without an `icon` is `layout.icon-missing` and draws a dashed placeholder.
|
|
200
|
+
- A free `icon <id> "pack:name"` object is an icon without text; for a labelled icon use a box
|
|
201
|
+
with `shape icon`.
|
|
202
|
+
|
|
203
|
+
## Coordinates
|
|
204
|
+
|
|
205
|
+
- `place` is the centre, as in flow diagrams.
|
|
206
|
+
- **Inside a group, `place` is relative to the group's interior**: its top-left corner plus
|
|
207
|
+
`groupPadding` (16) across and the header down: `groupHeader` (40) in the technical themes, or
|
|
208
|
+
`groupPadding` (16) for an untitled group (`""`, no description, no icon). A child at
|
|
209
|
+
`(w/2, h/2)` touches the interior's top-left corner. Moving the group moves its children.
|
|
210
|
+
- Every group needs a `place`. Without `size` it fits its children: padding + rightmost child edge
|
|
211
|
+
- padding wide, header + lowest child edge + padding tall.
|
|
212
|
+
- Route waypoints are always diagram coordinates.
|
|
213
|
+
|
|
214
|
+
## Containers, stacks and bands
|
|
215
|
+
|
|
216
|
+
These are the pictures of a visual editor's containers and backdrops; flow diagrams take them too.
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
group outer "" { // nested plain rectangles: untitled groups
|
|
220
|
+
group inner "" {
|
|
221
|
+
box core "Core"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
box plate "" // a stack: the outer box first, empty label
|
|
225
|
+
box card "Card"
|
|
226
|
+
group band "" { layer back } // a band behind arranged boxes (layers back, main)
|
|
227
|
+
|
|
228
|
+
style outer { fill "#dae8fc"; stroke "#6c8ebf"; radius 0 }
|
|
229
|
+
style inner { fill "#fff2cc"; stroke "#d6b656"; radius 0 }
|
|
230
|
+
style band { fill "#f5f5f5"; radius 0 }
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
- **Untitled groups** draw only their outline, have no title band and cut no gap in connectors;
|
|
234
|
+
children keep half the padding (8 px) from every edge (`layout.container-margin`).
|
|
235
|
+
- **Stacks**: a box lying strictly inside a box declared before it on the same layer is not
|
|
236
|
+
`layout.overlap`; a partial overlap still is, so are two boxes that coincide, and so is a stack
|
|
237
|
+
declared inner first (its hint says to declare the outer box first). A
|
|
238
|
+
container's own label may lie over its children, but two labels at the same point are
|
|
239
|
+
`layout.label-overlap`: leave the outer labels empty.
|
|
240
|
+
- **Bands**: a group with `place` and `size` is neither arranged by the engine nor an obstacle, so
|
|
241
|
+
on a back layer it stays behind the boxes `layout assisted` arranges (pin one box with `place`
|
|
242
|
+
so the others arrange around it). Boxes and groups on different layers are not checked against
|
|
243
|
+
each other, and connectors cross them straight. In `layout auto` a group's `place` is ignored:
|
|
244
|
+
make the band a group holding its boxes.
|
|
245
|
+
|
|
246
|
+
## Lists and kanban boards
|
|
247
|
+
|
|
248
|
+
```text
|
|
249
|
+
diagram board: free {
|
|
250
|
+
preset board
|
|
251
|
+
group kanban "" {
|
|
252
|
+
layout row // the columns side by side
|
|
253
|
+
spacing 24
|
|
254
|
+
align stretch // every column as tall as the tallest
|
|
255
|
+
group todo "To do" {
|
|
256
|
+
layout column // the cards top to bottom, in source order
|
|
257
|
+
spacing 12
|
|
258
|
+
sticky cache "Cache the catalogue"
|
|
259
|
+
sticky retry "Retry payments once"
|
|
260
|
+
}
|
|
261
|
+
group done "Done" {
|
|
262
|
+
layout column
|
|
263
|
+
sticky login "Sign in with passkeys"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
placement {
|
|
267
|
+
place kanban at (360, 300) // only the outer list needs a place
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
- `layout column|row` in a free group block makes the group a list: its elements and groups go one
|
|
273
|
+
after the other in source order from the interior's corner, `spacing <n>` apart (0..400; half
|
|
274
|
+
`groupPadding`, 8, by default). To reorder cards, reorder their declarations.
|
|
275
|
+
- `align start|center|end|stretch` places children across the axis (`start` by default);
|
|
276
|
+
`stretch` gives a child without a written `size` the interior's full width (column) or height
|
|
277
|
+
(row).
|
|
278
|
+
- Children keep their size; the list is derived from them, and a written `size` on the list is
|
|
279
|
+
only its least size. A list inside a list needs no `place`.
|
|
280
|
+
- A `place` on a child of a list is `layout.place-ignored` (warning): remove it. Lines and pens in a
|
|
281
|
+
list keep their written points. A group that is not a list, inside a list, still places its own
|
|
282
|
+
children with `place`.
|
|
283
|
+
- The engine treats a list as one box in every mode; `pnpm mdg layout` writes a `place` for it and
|
|
284
|
+
nothing for its children.
|
|
285
|
+
- `spacing` or `align` without `layout` is `prop.invalid-value` (add `layout column`); `layout grid`
|
|
286
|
+
lists `column, row`; `layout auto` belongs to the diagram, not to a group. Flow diagrams refuse
|
|
287
|
+
the three.
|
|
288
|
+
|
|
289
|
+
## Layers, order and links
|
|
290
|
+
|
|
291
|
+
- `layers back, main, front` lists layers back to front; `main` is the default and comes last
|
|
292
|
+
when unlisted. Put `layer front` in an object's or relation's block.
|
|
293
|
+
- Within a layer, groups paint first, then objects (lines included) in source order, then
|
|
294
|
+
relations: declare what must be on top later.
|
|
295
|
+
- `link checkout.api` in a block records that the object stands for element `api` of `diagram
|
|
296
|
+
checkout` (same file), `link co.api` through `import checkout as co from "..."`, or `link
|
|
297
|
+
views.checkout.api` through `import "..." as views`. Identity only; nothing is kept in step.
|
|
298
|
+
|
|
299
|
+
## From a flow diagram
|
|
300
|
+
|
|
301
|
+
`pnpm mdg convert sheet.meltemi --to free [--diagram <id>] [--id <new>]` adds a free copy of the
|
|
302
|
+
flow diagram as drawn: every box with `place` and `size`, children inside their copied groups,
|
|
303
|
+
layers, routes, labels, styles and animations, a `link` from each object to its source, and
|
|
304
|
+
classes `from_decision`, `from_data`, `from_tag` for the drawing of the flow kinds; notes stay notes,
|
|
305
|
+
with their `on` clause.
|
|
306
|
+
Edit the copy freely; the flow diagram is unchanged.
|
|
307
|
+
|
|
308
|
+
## Diagnostics
|
|
309
|
+
|
|
310
|
+
| Code | Fix |
|
|
311
|
+
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
312
|
+
| `ref.unknown-layer` | add the layer to `layers` (the hint gives the statement) or fix its name |
|
|
313
|
+
| `ref.unknown-link` | the diagram or element does not exist; fix the name or remove the `link` |
|
|
314
|
+
| `asset.outside-project` | image paths are relative, use `/`, no URLs, and stay inside the project |
|
|
315
|
+
| `asset.unknown-image` | the file does not exist next to the path written |
|
|
316
|
+
| `asset.unsupported-image` | not a PNG, JPEG, GIF, WebP or SVG image, broken, or over 8 MB |
|
|
317
|
+
| `layout.image-unavailable` | the host could not read the image; a placeholder is drawn |
|
|
318
|
+
| `layout.missing-placement` | an object or a group has no `place` (children of a list need none; a group that is not a list, inside a list, places its own children) |
|
|
319
|
+
| `layout.place-ignored` | a child of a list (`layout column\|row`) has a `place`, which the list overrides: remove the `place`, or the group's `layout` |
|
|
320
|
+
| `layout.text-overflow` | a `size` too narrow for a box's text, or a sticky whose text does not fit even at 8 px: shorten the text or use the size in the hint |
|
|
321
|
+
| `layout.too-large` | the content exceeds `preset document` or `preset slide`: split it into views, or write `preset board` for a whiteboard |
|
|
322
|
+
| `layout.overlap` | boxes overlap partly, or a stack is declared inner first: declare the outer box first |
|
|
323
|
+
| `layout.icon-missing` | `shape icon` without an `icon` style: add `icon "pack:name"` or choose another shape |
|
|
324
|
+
| `layout.label-position-ignored` | `labelPosition` only moves the label of `iconPosition center` and `shape icon` elements |
|
|
325
|
+
| `layout.vertical-align-ignored` | `verticalAlign` moves nothing on this shape or kind: choose a shape with a text band (`rectangle`, `ellipse`, `cylinder`), set `labelPosition` with a centred icon, or remove it |
|
|
326
|
+
| `layout.degenerate-line` | a line's points coincide: move an end or add a bend with `via` |
|
|
327
|
+
| `prop.invalid-value` | `textAlign`, `verticalAlign` and `opacity` are free-only; `font`, `fontSize` and `fontWeight` are refused on icons, images and pens; `shape` is for `node` and `box` only; a line or a pen takes no `place`, `size` or `rotation`; a pen needs `[(x, y), ...]` and `width` 1..64; a sticky needs its text; `spacing` and `align` need `layout column\|row`; `opacity` is refused on relations |
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# The Meltemi language (0.2), flow profile
|
|
2
|
+
|
|
3
|
+
A `.meltemi` file is UTF-8 text with LF or CRLF line breaks. Statements end at a line break or
|
|
4
|
+
`;`; `//` and `/* */` are comments and are preserved by every tool. Identifiers match
|
|
5
|
+
`[A-Za-z_][A-Za-z0-9_]*`; strings are double-quoted with `\"`, `\\`, `\n` and `\t` escapes;
|
|
6
|
+
numbers may carry a unit (`1200ms`, `2s`, `50%`).
|
|
7
|
+
|
|
8
|
+
## File structure
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
language "0.2" // optional header, must come first
|
|
12
|
+
|
|
13
|
+
import "../themes/company.meltemi" as company // imports go before the blocks
|
|
14
|
+
import corporate from "../themes/company.meltemi"
|
|
15
|
+
|
|
16
|
+
theme <id> { <token> <value> ... } // optional, see themes.md
|
|
17
|
+
|
|
18
|
+
diagram <id>: flow { ... } // one or more diagrams
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Projects and imports
|
|
22
|
+
|
|
23
|
+
A folder with `project.json` (`{ "name": "...", "language": "0.2" }`) is a project; files in it
|
|
24
|
+
import each other with relative paths (`./`, `../`, ending in `.meltemi`, never URLs).
|
|
25
|
+
`import "<path>" as <ns>` makes `<ns>.<id>` available; `import <id> [as <alias>] from "<path>"`
|
|
26
|
+
binds ids directly. Use imported themes by name: `theme "corporate"`, `theme "company.base"`,
|
|
27
|
+
`extends "company.base"`. Import cycles are errors (`module.cycle`). Validate a whole project with
|
|
28
|
+
`pnpm mdg validate <project folder>`; the full rules are in the repository's
|
|
29
|
+
`docs/language/projects.md`.
|
|
30
|
+
|
|
31
|
+
Every block compiles: `flow`, `free`, `sequence` and `c4` diagrams render, `story` blocks play
|
|
32
|
+
([stories.md](stories.md)) and `export` profiles write deliveries (below); free compositions are described in [free.md](free.md), sequence
|
|
33
|
+
diagrams in [sequence.md](sequence.md), and models with C4 views in [c4.md](c4.md). Any element block may hold `link <diagram>.<element>`, which ties
|
|
34
|
+
it to an element of another diagram.
|
|
35
|
+
|
|
36
|
+
## Inside `diagram <id>: flow { }`
|
|
37
|
+
|
|
38
|
+
| Statement | Meaning |
|
|
39
|
+
| ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
|
|
40
|
+
| `title "..."`, `description "..."` | SVG `<title>` and `<desc>`; the title also appears in the brand frame |
|
|
41
|
+
| `layout auto`, `layout assisted`, `layout manual` | ELK arranges everything, the unplaced boxes only, or nothing (layout.md) |
|
|
42
|
+
| `routing orthogonal` | connector shape: `auto` (default), `orthogonal`, `polyline`, `bezier` |
|
|
43
|
+
| `theme "<name>"` | built-in or file theme; default the project theme or `technical.light` |
|
|
44
|
+
| `preset document`, `preset slide`, `preset board`, `canvas (w, h)` | canvas size and limits; `board` grows with a whiteboard (see themes.md) |
|
|
45
|
+
| `class id { ... }`, `rule kind { ... }` | reusable styles and styles for every element of a kind (themes.md) |
|
|
46
|
+
| `direction LR` | flow of the automatic layout (`LR`, `RL`, `TB`, `BT`) |
|
|
47
|
+
| `layers back, main, front`; `layer back` in a block | paint order, back to front; `main` always exists; elements, groups and relations take `layer` |
|
|
48
|
+
| `id["Label"]` | node (rounded box) |
|
|
49
|
+
| `id[("Label")]` | data store (cylinder) |
|
|
50
|
+
| `node id "Label"`, `decision id "Label?"`, `data id "Label"` | typed declarations; label defaults to the id |
|
|
51
|
+
| `group id "Label" { ... }` | band holding declarations, relations and nested groups |
|
|
52
|
+
| `group id "" { ... }` | a plain container: no title band, padding 16 px all round (free.md) |
|
|
53
|
+
| `note id "Line one\nLine two" [on element]` | free text, left-aligned, no border; `on` attaches it to an element with a dotted leader |
|
|
54
|
+
| `tag id "PKCE"` | small pill with mono text |
|
|
55
|
+
| `a -> b`, `a --> b`, `a <-> b`, `a <--> b` | solid or dashed relation, one way or two-way; undeclared ids become nodes |
|
|
56
|
+
| `a -- b`, `a --- b` | a solid or dashed line without heads between two elements |
|
|
57
|
+
| `a -> b: "Label" as id` | relation with label and id |
|
|
58
|
+
| `{ description "..." }` after an element or relation | second text line of a box; description of a relation |
|
|
59
|
+
| `{ assumption "why" }` after a relation | an inferred relation, drawn dashed and muted until someone confirms it |
|
|
60
|
+
| `{ class a, b }` after an element, group or relation | apply classes |
|
|
61
|
+
| `{ port in west 30% }` after an element | a named port on a side, at a percentage along it (50 % by default) |
|
|
62
|
+
| `placement { ... }` | positions, sizes, routes, label anchors (below) |
|
|
63
|
+
| `style <t>[, <t>...] { ... }` | visual properties for elements or named relations |
|
|
64
|
+
| `animate <t>[, <t>...] { ... }` | motion effects: flow particles, a moving dash, a pulse, a trace (below) |
|
|
65
|
+
|
|
66
|
+
Elements and relations share one namespace per diagram. Anonymous relations get the key
|
|
67
|
+
`<from>-><to>#<n>` in tools and JSON; name a relation (`as id`) before routing or styling it.
|
|
68
|
+
|
|
69
|
+
## Placement
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
placement {
|
|
73
|
+
place api at (360, 180) // centre of the box
|
|
74
|
+
size api (200, 56) // width, height
|
|
75
|
+
route create from api.east to orders.west via [(520, 180)]
|
|
76
|
+
label create at 50% offset (0, -16) // position of the relation label
|
|
77
|
+
row api, orders // constraints: align, row, column,
|
|
78
|
+
distance orders, db 80 // order and distance
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Ports: `north`, `south`, `east`, `west`, `auto` (`from api` means `api.auto`) and the ports an
|
|
83
|
+
element declares with `port`; an undeclared name is `placement.unknown-port`. A route's endpoints
|
|
84
|
+
must be the relation's source and target, in that order. Each element has at most one `place` and
|
|
85
|
+
one `size`; each relation at most one `route` and one `label`. Several `placement` blocks may
|
|
86
|
+
exist; order does not matter.
|
|
87
|
+
|
|
88
|
+
## Styles
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
style api, db { fill "#ebe5fd"; stroke "#6a4fd0"; color "#33247a" }
|
|
92
|
+
style obo, ciba, proxy { line dashed }
|
|
93
|
+
style r1, r2 { fill "#0B1830"; color "#FFFFFF" } // dark label pills
|
|
94
|
+
style legendBox { fill "none" }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
| Property | Element | Relation |
|
|
98
|
+
| --------------- | ------------------------------------------------------------------------------ | ------------------------------------------ |
|
|
99
|
+
| `fill` | background (`"none"` for no fill) | label pill background |
|
|
100
|
+
| `stroke` | outline colour | connector and arrowhead colour |
|
|
101
|
+
| `color` | label and description text | label pill text |
|
|
102
|
+
| `line` | `solid`, `dashed` or `dotted` outline | overrides the arrow style |
|
|
103
|
+
| `width` | outline width (0 to 64; a pen's stroke 1 to 64) | connector width |
|
|
104
|
+
| `radius` | corner radius (0 to 64) of boxes, groups | not allowed |
|
|
105
|
+
| `shape` | `node` only: `hexagon`, `icon`… (free.md) | not allowed |
|
|
106
|
+
| `pattern` | `hatch`, `dots`, `cross` or `none` | not allowed |
|
|
107
|
+
| `arrowhead` | not allowed | head at the target (below) |
|
|
108
|
+
| `arrowtail` | not allowed | head at the source (below) |
|
|
109
|
+
| `routing` | not allowed | `auto`, `orthogonal`, `polyline`, `bezier` |
|
|
110
|
+
| `corners` | not allowed | `sharp` or `rounded` bends |
|
|
111
|
+
| `class` | apply classes | apply classes |
|
|
112
|
+
| `icon` | `"pack:name"`, placed by `iconPosition` | inside the label pill |
|
|
113
|
+
| `iconColor` | colour of a monochrome icon | same |
|
|
114
|
+
| `iconPosition` | `left`, `right`, `top`, `bottom`, `center` | not allowed |
|
|
115
|
+
| `labelPosition` | label edge of a centred icon or `shape icon`: `top`, `bottom`, `left`, `right` | not allowed |
|
|
116
|
+
| `iconSize` | `auto` or 8 to 128: the icon's side | not allowed |
|
|
117
|
+
|
|
118
|
+
Colours are quoted (`"#6a4fd0"`) or colour token names that follow the theme (`danger`, `accent`,
|
|
119
|
+
`muted`, `success`, `warning`, `info`, …).
|
|
120
|
+
|
|
121
|
+
Heads (`arrowhead` at the target, `arrowtail` at the source): `triangle`, `open`, `none`,
|
|
122
|
+
`triangleOutline` (UML generalisation), `diamond` and `diamondOutline` (composition and
|
|
123
|
+
aggregation), `circle`, `circleOutline`, `bar`, `cross`, and the ER crow's feet `many`,
|
|
124
|
+
`oneOrMany`, `onlyOne`, `zeroOrOne`, `zeroOrMany`. A relation has no start head unless it is
|
|
125
|
+
written `<->`/`<-->` (the end's head at both ends) or has `arrowtail`. A line `--` (dashed `---`)
|
|
126
|
+
has no head at either end unless `arrowhead` or `arrowtail` is written; write it for an
|
|
127
|
+
association, a link to a note or a plain connection, instead of `arrowhead none`:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
customer -> order as places
|
|
131
|
+
style places { arrowtail onlyOne; arrowhead zeroOrMany } // one customer places zero or more orders
|
|
132
|
+
api <-> cache // two-way
|
|
133
|
+
api -- db // a line, no heads
|
|
134
|
+
note1 --- api // a dashed line, no heads
|
|
135
|
+
style slow { line dotted; corners rounded } // dotted, rounded bends
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The six tokens are `->`, `-->`, `--`, `---`, `<->`, `<-->`; `--->` is a syntax error. Sequence
|
|
139
|
+
diagrams take the four arrows and C4 views `->` and `-->`: another token is `prop.invalid-value`.
|
|
140
|
+
|
|
141
|
+
Setting the same property twice for a target across statements is `prop.duplicate`; different
|
|
142
|
+
properties in different statements are fine.
|
|
143
|
+
|
|
144
|
+
## Animate
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
animate r1, r2 { effect flow; particles 2 } // particles along named relations
|
|
148
|
+
animate save { effect dash; direction reverse } // a dash moving along a line or outline
|
|
149
|
+
animate db { effect pulse; duration 1500ms; repeat 3; delay 300ms; color accent }
|
|
150
|
+
animate r1 { effect trace } // a highlight that fills the relation, then restarts
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`effect` is required. `duration` 100 ms to 60 s (the theme's `flowDuration`, `dashDuration`,
|
|
154
|
+
`pulseDuration` or `traceDuration`, else 1200 ms for flow, 1500 ms for trace and 1 s otherwise),
|
|
155
|
+
`repeat` `forever` (default) or 1 to 1000, `delay`, `direction forward|reverse` (flow, dash and
|
|
156
|
+
trace), `particles 1..8` (flow), `color` (flow, pulse and trace; a trace defaults to `accent`).
|
|
157
|
+
Flow and trace run on relations (and free lines and pens) only; dash on relations, free lines,
|
|
158
|
+
pens, boxes with an outline and notes or texts that style an outline (`fill`, `stroke` or
|
|
159
|
+
`pattern`); pulse on elements, relations, notes and fragments. One effect of each kind per target
|
|
160
|
+
(`animate.conflict`). Exports are static unless you ask:
|
|
161
|
+
`pnpm mdg export sheet.meltemi --motion animated` writes an animated SVG (CSS keyframes, static
|
|
162
|
+
fallback), `--at 1.5s` the frame at that time. Use the static export for documents and slides.
|
|
163
|
+
|
|
164
|
+
## Stories
|
|
165
|
+
|
|
166
|
+
`story <id> for <diagram> { scene ... }` walks through a diagram: `reveal`, `hide`, `highlight`,
|
|
167
|
+
`focus`, `camera`, `trace`, `draw` (pens, lines and relations drawn again) and `hold` on one
|
|
168
|
+
clock, `parallel` blocks, and `view` with a `transition` to change diagram.
|
|
169
|
+
`pnpm mdg export sheet.meltemi --story <id> --at 2s` writes a frame. See [stories.md](stories.md).
|
|
170
|
+
|
|
171
|
+
## Export profiles and links
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
export slide for checkout {
|
|
175
|
+
format png // svg, png, pdf, html (player), mp4, webm, gif
|
|
176
|
+
scale 2 // png pixels per unit
|
|
177
|
+
size (1920, 1080) // png, pdf, video: fitted and centred
|
|
178
|
+
background transparent // or a quoted colour or a token
|
|
179
|
+
file "slides/checkout.png"
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Plugins installed in `project.json` may declare diagram types (`diagram s: erd { entity a "A" }`):
|
|
184
|
+
their kinds are boxes with the type's style and properties; `pnpm mdg plugins <project>` lists them.
|
|
185
|
+
`pnpm mdg convert <file> --to json` writes the file's model JSON for other tools.
|
|
186
|
+
`pnpm mdg init <folder> --template flow|c4|sequence|free|purchase` starts a project;
|
|
187
|
+
`pnpm mdg preview <project>` serves its catalog and reloads it as files change;
|
|
188
|
+
`pnpm mdg review <project> --base main` lists what changed by id (renames included).
|
|
189
|
+
`pnpm mdg build catalog <project>` writes one offline HTML catalog of the project (settings in
|
|
190
|
+
`project.json` `catalog`; comments and source stay out unless `--source`). In the catalog and in
|
|
191
|
+
`--format html` pages, a double click (or the plus sign) on a system opens its container view, on
|
|
192
|
+
a container its component view, on an element with `link` the diagram it names: write those
|
|
193
|
+
views (`level` + `scope`) and links so readers can drill down; descriptions show on hover.
|
|
194
|
+
`pnpm mdg export sheet.meltemi --profiles` writes every profile; `--profile slide` one.
|
|
195
|
+
`--format mp4|webm|gif` records a story (`--story`) or effects with the installed browser and
|
|
196
|
+
FFmpeg: 1080p at 30 fps, GIF 960 × 540 at 15 fps. Effects that repeat forever last one loop of their
|
|
197
|
+
cycles (6 s with the defaults) unless `--duration` or a profile's `duration` says otherwise, and the
|
|
198
|
+
export notes the length it chose; a transparent MP4 takes the theme's background. Options of
|
|
199
|
+
another format are `export.invalid-option`. Elements, groups and model entities take
|
|
200
|
+
`url "https://…"`: SVG, PDF and HTML exports keep the link.
|
|
201
|
+
`pnpm mdg login`, `push`, `pull`, `publish` and `projects` keep a project in step with its copy in
|
|
202
|
+
the optional cloud service, which `project.json` records in `cloud`, and
|
|
203
|
+
`pnpm mdg review <project> --base cloud` compares with it; run them only when asked (see SKILL.md).
|
|
204
|
+
|
|
205
|
+
## Diagnostics and fixes
|
|
206
|
+
|
|
207
|
+
| Code | Cause and fix |
|
|
208
|
+
| ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
209
|
+
| `syntax.expected-token`, `syntax.unexpected-token` | malformed statement; check quotes, `->`, parentheses, one statement per line |
|
|
210
|
+
| `syntax.unterminated-string` | a string reached the end of the line; close it, use `\n` for line breaks |
|
|
211
|
+
| `syntax.unexpected-character` | characters such as `=>`, `--->` or `#` outside strings; the relation tokens are `->`, `-->`, `--`, `---`, `<->`, `<-->` |
|
|
212
|
+
| `ref.duplicate-id` | the id is already an element, relation or top-level block; rename one |
|
|
213
|
+
| `ref.unknown-element` | target of `place`, `size`, `style` or a qualified endpoint does not exist; declare it |
|
|
214
|
+
| `ref.unknown-relation` | `route`/`label` on an unnamed relation; add `as <id>` |
|
|
215
|
+
| `placement.route-mismatch` | `route` endpoints are reversed or wrong; use the relation's source then target |
|
|
216
|
+
| `placement.duplicate` | second `place`/`size` for an element or `route`/`label` for a relation; delete one |
|
|
217
|
+
| `placement.unknown-port` | the route names a port the element does not declare; the hint lists its ports |
|
|
218
|
+
| `prop.unknown` | unknown word; the hint lists what the block accepts |
|
|
219
|
+
| `prop.invalid-value` | wrong value shape; the message names the expected form; `shape` only on `node` and `box`; a relation token the profile refuses (`--` in a sequence) |
|
|
220
|
+
| `prop.duplicate` | property set twice for the same target; keep one |
|
|
221
|
+
| `layout.missing-placement` | manual layout and an element without `place`, or a group with only one of `place`/`size` |
|
|
222
|
+
| `layout.mode-unsupported` | a host without a layout engine met unplaced boxes; the command line always has ELK |
|
|
223
|
+
| `layout.placement-ignored` | `place` or waypoints in `layout auto`; write `layout assisted` or `manual` |
|
|
224
|
+
| `layout.constraint-conflict` | placed boxes break a constraint; move a `place` or change the constraint |
|
|
225
|
+
| `layout.overlap` | two boxes overlap, or a box crosses a group edge; move it or add `distance`; a stack goes outer first |
|
|
226
|
+
| `layout.label-under-connector` | a label sits on another arrow; move it with `label r at <n>% offset (dx, dy)` |
|
|
227
|
+
| `layout.container-margin` | a box touches the edge or title band of its sized group; enlarge the group or move it |
|
|
228
|
+
| `layout.connector-overlap` | two arrows run along each other; use other ports, a waypoint or `routing bezier` |
|
|
229
|
+
| `layout.connector-crossing` | an arrow runs through a box it does not join; move the box or add a waypoint |
|
|
230
|
+
| `layout.unknown-theme` | theme name is neither built in nor in the file; warning, renders with the default |
|
|
231
|
+
| `theme.unknown-base`, `theme.cycle` | `extends` names a missing theme or loops; point it at a built-in theme |
|
|
232
|
+
| `theme.unknown-class` | a class is not in the diagram, its theme or the built-in ones; declare it or fix the name |
|
|
233
|
+
| `asset.unknown-icon`, `asset.unknown-pack` | the icon name or pack does not exist; search with `pnpm mdg assets icons <words>` |
|
|
234
|
+
| `layout.too-large` | the sheet exceeds its `preset` or `canvas`; split it into views instead of shrinking, or write `preset board` for a whiteboard |
|
|
235
|
+
| `layout.text-overflow` | an explicit `size` is too narrow for its text; use the width in the hint |
|
|
236
|
+
| `layout.unmeasured-font` | a theme's or a style's `font` names no bundled or project family, or characters no font has: name a bundled family |
|
|
237
|
+
| `layout.icon-missing` | `shape icon` without an `icon`: a dashed placeholder is drawn; add the icon or change the shape |
|
|
238
|
+
| `layout.label-position-ignored` | `labelPosition` without `iconPosition center` or `shape icon`; add one of them or remove it |
|
|
239
|
+
| `animate.missing-effect`, `animate.invalid-target` | write `effect`; flow and trace on named relations, free lines and pens, dash on lines, pens and boxes, pulse anywhere |
|
|
240
|
+
| `animate.conflict` | one effect of each kind per target; merge the two statements |
|
|
241
|
+
| `story.*` | stories; see [stories.md](stories.md) |
|
|
242
|
+
| `export.*` | export profiles: a known target, a `format`, options of that format, a video `duration` |
|
|
243
|
+
| `ref.unknown-link` | a `link` names a diagram or element that does not exist; fix it or remove the link |
|
|
244
|
+
| `ref.unknown-layer`, `asset.*-image`, `layout.image-unavailable` | free compositions; see [free.md](free.md) |
|
|
245
|
+
| `export.no-diagram` | no flow or free diagram in the file |
|