@diagrammo/dgmo 0.25.2 → 0.25.3
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/README.md +69 -884
- package/dist/auto.cjs +1 -1
- package/dist/auto.js +1 -1
- package/dist/auto.mjs +1 -1
- package/dist/index.cjs +5 -2
- package/dist/index.js +5 -2
- package/package.json +1 -1
- package/src/utils/svg-embed.ts +12 -3
package/README.md
CHANGED
|
@@ -1,952 +1,137 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# `@diagrammo/dgmo`
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Simple text in. Brilliant diagrams out.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Write plain-text `.dgmo` files, get clean, themeable diagrams and charts. One markup language, **45+ chart types** — flowcharts, sequence diagrams, ER, org charts, C4, gantt, maps, bar/line/pie, and a lot more.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/@diagrammo/dgmo)
|
|
10
|
+
[](https://www.npmjs.com/package/@diagrammo/dgmo)
|
|
11
|
+
[](./LICENSE)
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
- **Local:** [`docs/language-reference.md`](docs/language-reference.md)
|
|
13
|
+
**[📖 Docs](https://diagrammo.app/start) · [🧩 Language Reference](https://diagrammo.app/reference) · [🖥️ Desktop App](https://diagrammo.app/app) · [🪄 Live Editor](https://online.diagrammo.app)**
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
</div>
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
---
|
|
17
18
|
|
|
18
|
-
```bash
|
|
19
|
-
npm install @diagrammo/dgmo
|
|
20
|
-
# or
|
|
21
|
-
pnpm add @diagrammo/dgmo
|
|
22
19
|
```
|
|
20
|
+
sequence Boarding the Marauder
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
brew tap diagrammo/dgmo
|
|
29
|
-
brew install dgmo
|
|
30
|
-
|
|
31
|
-
# or run directly via npx
|
|
32
|
-
npx @diagrammo/dgmo diagram.dgmo
|
|
22
|
+
Quartermaster -Hoist the colors-> Crew
|
|
23
|
+
Crew -Aye, captain-> Bosun
|
|
24
|
+
Bosun -Heading 270-> Helm
|
|
25
|
+
Helm -On course-> Quartermaster
|
|
33
26
|
```
|
|
34
27
|
|
|
35
|
-
|
|
28
|
+
That's a complete diagram. No coordinates, no XML, no drag-and-drop — just text you can diff, review, and version like any other source file.
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
# First time with no args? Creates a sample.dgmo to get you started
|
|
39
|
-
dgmo
|
|
30
|
+
## Install
|
|
40
31
|
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
```bash
|
|
33
|
+
# Library
|
|
34
|
+
npm install @diagrammo/dgmo
|
|
43
35
|
|
|
44
|
-
#
|
|
45
|
-
|
|
36
|
+
# CLI (macOS, via Homebrew)
|
|
37
|
+
brew install diagrammo/dgmo/dgmo
|
|
46
38
|
|
|
47
|
-
#
|
|
48
|
-
dgmo diagram.dgmo
|
|
39
|
+
# CLI (no install)
|
|
40
|
+
npx @diagrammo/dgmo diagram.dgmo
|
|
41
|
+
```
|
|
49
42
|
|
|
50
|
-
|
|
51
|
-
cat diagram.dgmo | dgmo -o out.png
|
|
52
|
-
cat diagram.dgmo | dgmo > out.png # PNG to stdout
|
|
43
|
+
## CLI
|
|
53
44
|
|
|
54
|
-
|
|
45
|
+
```bash
|
|
46
|
+
dgmo # creates a sample.dgmo to get you started
|
|
47
|
+
dgmo diagram.dgmo # → diagram.png
|
|
48
|
+
dgmo diagram.dgmo -o out.svg # → SVG (format from extension)
|
|
49
|
+
cat diagram.dgmo | dgmo > out.png # pipe in, PNG to stdout
|
|
55
50
|
dgmo diagram.dgmo --theme dark --palette catppuccin
|
|
56
51
|
```
|
|
57
52
|
|
|
58
|
-
**Options:**
|
|
59
|
-
|
|
60
53
|
| Flag | Values | Default |
|
|
61
54
|
|------|--------|---------|
|
|
62
55
|
| `--theme` | `light`, `dark`, `transparent` | `light` |
|
|
63
|
-
| `--palette` |
|
|
64
|
-
| `-o` |
|
|
65
|
-
|
|
66
|
-
## Supported chart types
|
|
67
|
-
|
|
68
|
-
### Data Charts
|
|
69
|
-
|
|
70
|
-
| Type | Description |
|
|
71
|
-
|------|-------------|
|
|
72
|
-
| `bar` | Vertical/horizontal bar charts |
|
|
73
|
-
| `line` | Line charts with crosshair |
|
|
74
|
-
| `area` | Filled area charts |
|
|
75
|
-
| `pie` | Pie charts with connector labels |
|
|
76
|
-
| `doughnut` | Doughnut charts |
|
|
77
|
-
| `radar` | Radar/spider charts |
|
|
78
|
-
| `polar-area` | Polar area charts |
|
|
79
|
-
| `bar-stacked` | Stacked bar charts |
|
|
80
|
-
| `multi-line` | Multi-series line charts |
|
|
81
|
-
| `scatter` | XY scatter with categories and sizing |
|
|
82
|
-
| `heatmap` | Matrix heatmaps |
|
|
83
|
-
| `funnel` | Conversion funnels |
|
|
84
|
-
| `sankey` | Flow diagrams |
|
|
85
|
-
| `chord` | Circular relationship diagrams |
|
|
86
|
-
|
|
87
|
-
### Visualizations
|
|
88
|
-
|
|
89
|
-
| Type | Description |
|
|
90
|
-
|------|-------------|
|
|
91
|
-
| `slope` | Before/after comparison |
|
|
92
|
-
| `wordcloud` | Weighted text clouds |
|
|
93
|
-
| `arc` | Arc/network diagrams |
|
|
94
|
-
| `timeline` | Timelines with eras and markers |
|
|
95
|
-
| `venn` | Set intersection diagrams |
|
|
96
|
-
| `quadrant` | 2D quadrant scatter |
|
|
97
|
-
| `tech-radar` | Technology adoption radar (ThoughtWorks style) |
|
|
98
|
-
|
|
99
|
-
### Structural Diagrams
|
|
100
|
-
|
|
101
|
-
| Type | Description |
|
|
102
|
-
|------|-------------|
|
|
103
|
-
| `sequence` | Sequence diagrams with type inference |
|
|
104
|
-
| `flowchart` | Directed graph flowcharts with branching and 6 node shapes |
|
|
105
|
-
| `class` | UML class diagrams with inheritance, composition, and visibility |
|
|
106
|
-
| `er` | Entity-relationship diagrams with crow's foot notation |
|
|
107
|
-
| `org` | Org charts with hierarchy, team containers, and tag group color-coding |
|
|
108
|
-
| `c4` | C4 architecture diagrams (context, containers, components, deployment) |
|
|
109
|
-
| `state` | State machine diagrams |
|
|
110
|
-
| `infra` | Infrastructure capacity and latency diagrams |
|
|
111
|
-
| `kanban` | Kanban boards |
|
|
112
|
-
| `sitemap` | Site structure and navigation maps |
|
|
113
|
-
|
|
114
|
-
### Other
|
|
115
|
-
|
|
116
|
-
| Type | Description |
|
|
117
|
-
|------|-------------|
|
|
118
|
-
| `function` | Mathematical function plots |
|
|
119
|
-
|
|
120
|
-
## How it works
|
|
121
|
-
|
|
122
|
-
Every `.dgmo` file is plain text with a `<type>` header line (optionally followed by a title) and then metadata and data. The library parses each chart type and gives you either:
|
|
123
|
-
|
|
124
|
-
- A **config object** you render yourself
|
|
125
|
-
- A **rendered SVG** directly
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
parse → build config → render
|
|
129
|
-
```
|
|
56
|
+
| `--palette` | one of 13 palettes (see below) | `nord` |
|
|
57
|
+
| `-o` | output path (`.svg` → SVG, else PNG) | `<input>.png` |
|
|
130
58
|
|
|
131
|
-
|
|
59
|
+
## Library
|
|
132
60
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
### Data charts — standard (bar, line, pie, radar, etc.)
|
|
61
|
+
Render any diagram to an SVG string — no browser, no visible DOM:
|
|
136
62
|
|
|
137
63
|
```typescript
|
|
138
|
-
import {
|
|
139
|
-
import * as echarts from 'echarts';
|
|
140
|
-
|
|
141
|
-
const colors = getPalette('nord').light;
|
|
64
|
+
import { render } from '@diagrammo/dgmo';
|
|
142
65
|
|
|
143
|
-
const
|
|
66
|
+
const { svg } = await render(`
|
|
144
67
|
bar Revenue by Quarter
|
|
145
|
-
x-label Quarter
|
|
146
|
-
y-label Revenue ($M)
|
|
147
|
-
|
|
148
68
|
Q1 12
|
|
149
69
|
Q2 19
|
|
150
70
|
Q3 15
|
|
151
71
|
Q4 22
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const parsed = parseChart(content, colors);
|
|
155
|
-
const option = buildSimpleChartOption(parsed, colors, false);
|
|
156
|
-
echarts.init(container).setOption(option);
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### Data charts — extended (scatter, sankey, heatmap, etc.)
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
import { parseExtendedChart, buildExtendedChartOption, getPalette } from '@diagrammo/dgmo';
|
|
163
|
-
import * as echarts from 'echarts';
|
|
164
|
-
|
|
165
|
-
const colors = getPalette('nord').light;
|
|
166
|
-
|
|
167
|
-
const content = `
|
|
168
|
-
sankey Energy Flow
|
|
169
|
-
|
|
170
|
-
Coal orange
|
|
171
|
-
Electricity 50
|
|
172
|
-
Gas blue
|
|
173
|
-
Electricity 30
|
|
174
|
-
Electricity -> Industry 45
|
|
175
|
-
Electricity -> Homes 35
|
|
176
|
-
`;
|
|
177
|
-
|
|
178
|
-
const parsed = parseExtendedChart(content);
|
|
179
|
-
const option = buildExtendedChartOption(parsed, colors, false);
|
|
180
|
-
echarts.init(container).setOption(option);
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Visualizations (slope, timeline, wordcloud, etc.)
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
import { parseVisualization, renderTimeline, getPalette } from '@diagrammo/dgmo';
|
|
187
|
-
|
|
188
|
-
const colors = getPalette('nord').light;
|
|
189
|
-
|
|
190
|
-
const content = `
|
|
191
|
-
timeline Project Milestones
|
|
192
|
-
|
|
193
|
-
2024-01 Kickoff
|
|
194
|
-
2024-03 -> 2024-06 Development
|
|
195
|
-
2024-07 Launch
|
|
196
|
-
`;
|
|
197
|
-
|
|
198
|
-
const parsed = parseVisualization(content, colors);
|
|
199
|
-
renderTimeline(container, parsed, colors, false);
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Sequence diagrams
|
|
203
|
-
|
|
204
|
-
Sequence diagrams use a minimal DSL. Participants are inferred from messages — no declaration blocks needed. Types (service, database, actor, queue, etc.) are inferred from naming conventions.
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
import { parseSequenceDgmo, renderSequenceDiagram, getPalette } from '@diagrammo/dgmo';
|
|
208
|
-
|
|
209
|
-
const colors = getPalette('nord').light;
|
|
210
|
-
|
|
211
|
-
const content = `
|
|
212
|
-
sequence Login Flow
|
|
213
|
-
|
|
214
|
-
User -login(email, pass)-> AuthService
|
|
215
|
-
AuthService -findByEmail(email)-> UserDB
|
|
216
|
-
AuthService <-user- UserDB
|
|
217
|
-
User <-token- AuthService
|
|
218
|
-
`;
|
|
219
|
-
|
|
220
|
-
const parsed = parseSequenceDgmo(content);
|
|
221
|
-
renderSequenceDiagram(container, parsed, colors, false, (lineNum) => {
|
|
222
|
-
// clicked a message — jump to that line in the editor
|
|
223
|
-
});
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**Sequence syntax:**
|
|
227
|
-
|
|
228
|
-
- `A -message-> B` — synchronous call
|
|
229
|
-
- `A -> B` — unlabeled synchronous call
|
|
230
|
-
- `A ~message~> B` — async/fire-and-forget call
|
|
231
|
-
- `A ~> B` — unlabeled async call
|
|
232
|
-
- `A <-message- B` — synchronous return (dashed arrow, from B to A)
|
|
233
|
-
- `A <- B` — unlabeled return
|
|
234
|
-
- `A <~message~ B` — async return
|
|
235
|
-
- `if condition` / `else` / `end` — conditional blocks
|
|
236
|
-
- `loop condition` / `end` — loop blocks
|
|
237
|
-
- `parallel` / `else` / `end` — concurrent branches
|
|
238
|
-
- `== Section ==` — horizontal dividers (collapsible in the desktop app)
|
|
239
|
-
- `[GroupName]` — participant grouping
|
|
240
|
-
- `Name is a database` — explicit type declaration
|
|
241
|
-
- `Name position 0` — explicit ordering
|
|
242
|
-
- `activations off` — disable activation bars
|
|
243
|
-
- `tag Name` + `Value(color)` entries — color-coded metadata dimensions with interactive legend
|
|
244
|
-
- `| key: value` — attach tag metadata to participants, messages, or groups
|
|
245
|
-
|
|
246
|
-
**Participant type inference** — 104 rules map names to shapes automatically:
|
|
247
|
-
|
|
248
|
-
| Pattern | Inferred type | Shape |
|
|
249
|
-
|---------|--------------|-------|
|
|
250
|
-
| User, Admin, Alice, Bob | actor | stick figure |
|
|
251
|
-
| DB, Postgres, Mongo, Redis (store) | database | cylinder |
|
|
252
|
-
| Redis, Memcache (cache) | cache | dashed cylinder |
|
|
253
|
-
| Queue, Kafka, SQS, EventBus | queue | horizontal cylinder |
|
|
254
|
-
| Gateway, Proxy, LB, CDN | networking | shield |
|
|
255
|
-
| App, Browser, Dashboard, CLI | frontend | rounded rect |
|
|
256
|
-
| Service, API, Lambda, Fn | service | pill shape |
|
|
257
|
-
| External, ThirdParty, Vendor | external | dashed square |
|
|
258
|
-
|
|
259
|
-
### Flowcharts
|
|
260
|
-
|
|
261
|
-
Flowcharts use a concise syntax with 6 node shapes: `(terminal)`, `[process]`, `<decision>`, `/io/`, `{preparation}`, and `[[subroutine]]`. Edges support labels and branching.
|
|
262
|
-
|
|
263
|
-
```typescript
|
|
264
|
-
import { parseFlowchart, layoutGraph, renderFlowchart, getPalette } from '@diagrammo/dgmo';
|
|
265
|
-
|
|
266
|
-
const colors = getPalette('nord').dark;
|
|
267
|
-
|
|
268
|
-
const content = `
|
|
269
|
-
flowchart Decision Flow
|
|
270
|
-
|
|
271
|
-
(Start) -> /Get Input/ -> <Valid?>
|
|
272
|
-
-yes-> [Process Data] -> (Done)
|
|
273
|
-
-no-> [Show Error] -> /Get Input/
|
|
274
|
-
`;
|
|
275
|
-
|
|
276
|
-
const parsed = parseFlowchart(content, colors);
|
|
277
|
-
const layout = layoutGraph(parsed);
|
|
278
|
-
renderFlowchart(container, parsed, layout, colors, true);
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### ER diagrams
|
|
282
|
-
|
|
283
|
-
ER diagrams use a table-and-column syntax with constraint annotations and cardinality relationships. Crow's foot notation is the default, with an optional `notation: labels` mode.
|
|
284
|
-
|
|
285
|
-
```typescript
|
|
286
|
-
import { parseERDiagram, layoutERDiagram, renderERDiagram, getPalette } from '@diagrammo/dgmo';
|
|
287
|
-
|
|
288
|
-
const colors = getPalette('nord').light;
|
|
289
|
-
|
|
290
|
-
const content = `
|
|
291
|
-
er Blog Platform
|
|
292
|
-
|
|
293
|
-
users
|
|
294
|
-
id: int [pk]
|
|
295
|
-
name: varchar
|
|
296
|
-
email: varchar [unique]
|
|
297
|
-
|
|
298
|
-
posts
|
|
299
|
-
id: int [pk]
|
|
300
|
-
author_id: int [fk]
|
|
301
|
-
title: varchar
|
|
302
|
-
|
|
303
|
-
users 1--* posts: writes
|
|
304
|
-
`;
|
|
305
|
-
|
|
306
|
-
const parsed = parseERDiagram(content, colors);
|
|
307
|
-
const layout = layoutERDiagram(parsed);
|
|
308
|
-
renderERDiagram(container, parsed, layout, colors, false);
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
**ER diagram syntax:**
|
|
312
|
-
|
|
313
|
-
- `er` — chart type (first line), optionally followed by title: `er Blog Platform`
|
|
314
|
-
- `notation labels` — use text labels instead of crow's foot markers
|
|
315
|
-
- Table declaration: unindented name (e.g. `users`, `order_items`)
|
|
316
|
-
- Column: indented `name: type [constraints]`
|
|
317
|
-
- Constraints: `[pk]`, `[fk]`, `[unique]`, `[nullable]`, or combined `[pk, unique]`
|
|
318
|
-
- Relationships with cardinality: `table1 1--* table2: label`
|
|
319
|
-
- Symbolic: `1--*`, `1-*`, `?--1`, `*--*`
|
|
320
|
-
- Keyword: `one-to-many`, `many-to-one`, `one-to-one`
|
|
321
|
-
- Natural: `one to many`, `1 to many`
|
|
322
|
-
- Colors: `table_name (color)` for explicit color
|
|
323
|
-
|
|
324
|
-
### Org charts
|
|
325
|
-
|
|
326
|
-
Org charts use indentation to define hierarchy, with metadata on nodes, team containers, and tag groups for color-coding.
|
|
327
|
-
|
|
328
|
-
```typescript
|
|
329
|
-
import { parseOrg, renderOrg, getPalette } from '@diagrammo/dgmo';
|
|
330
|
-
|
|
331
|
-
const colors = getPalette('nord').light;
|
|
332
|
-
|
|
333
|
-
const content = `
|
|
334
|
-
org Engineering
|
|
335
|
-
|
|
336
|
-
tag Location
|
|
337
|
-
NY blue
|
|
338
|
-
SF green
|
|
339
|
-
|
|
340
|
-
Alex Chen
|
|
341
|
-
role: CTO
|
|
342
|
-
location: NY
|
|
343
|
-
|
|
344
|
-
[Platform Team]
|
|
345
|
-
goal: Core infrastructure
|
|
346
|
-
|
|
347
|
-
Alice Park role: Senior Engineer, location: NY
|
|
348
|
-
Bob Torres role: Junior Engineer, location: SF
|
|
349
|
-
`;
|
|
350
|
-
|
|
351
|
-
const parsed = parseOrg(content, colors);
|
|
352
|
-
renderOrg(container, parsed, colors, false);
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
**Org chart syntax:**
|
|
356
|
-
|
|
357
|
-
- `org` — chart type (first line), optionally followed by title: `org Engineering`
|
|
358
|
-
- Indentation defines parent-child hierarchy (2 or 4 spaces, consistent within file)
|
|
359
|
-
- Multiple root nodes supported (e.g., co-CEOs at top level)
|
|
360
|
-
|
|
361
|
-
**Node metadata:**
|
|
362
|
-
|
|
363
|
-
```
|
|
364
|
-
Jane Smith
|
|
365
|
-
role: CEO
|
|
366
|
-
location: NY
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
Or single-line with same-line metadata:
|
|
370
|
-
|
|
371
|
-
```
|
|
372
|
-
Jane Smith role: CEO, location: NY
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
**Team containers** — grouping constructs rendered as labeled boxes:
|
|
376
|
-
|
|
377
|
-
```
|
|
378
|
-
[Platform Team]
|
|
379
|
-
goal: Core infrastructure
|
|
380
|
-
charter: Developer experience
|
|
381
|
-
|
|
382
|
-
Alice Park
|
|
383
|
-
role: Senior Engineer
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
Containers can nest and carry their own metadata (key: value pairs). Children are bare labels (no colon).
|
|
387
|
-
|
|
388
|
-
**Tag groups** — define color coding for metadata values. Must appear before org content:
|
|
389
|
-
|
|
390
|
-
```
|
|
391
|
-
tag Location as l
|
|
392
|
-
NY blue
|
|
393
|
-
SF green
|
|
394
|
-
Remote purple default
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
- `tag GroupName` starts a tag group; `as <alias>` provides a shorthand for metadata keys
|
|
398
|
-
- `Value color` maps a metadata value to a color (trailing-token form per spec §1.5)
|
|
399
|
-
- `default` marks the fallback value for nodes without that metadata
|
|
400
|
-
- Nodes whose metadata matches a tag group value get color-coded automatically
|
|
401
|
-
- `##` syntax is deprecated but still accepted — use `tag` for new diagrams
|
|
402
|
-
|
|
403
|
-
**Options:**
|
|
404
|
-
|
|
405
|
-
| Option | Description |
|
|
406
|
-
|--------|-------------|
|
|
407
|
-
| `org Title Text` | Chart title (on first line after chart type) |
|
|
408
|
-
| `sub-node-label Text` | Label for child count badges (e.g., "Crew", "Reports") |
|
|
409
|
-
| `show-sub-node-count` | Show descendant count on nodes |
|
|
410
|
-
|
|
411
|
-
**Comments:**
|
|
412
|
-
|
|
413
|
-
```
|
|
414
|
-
// This is a comment
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
### Routing
|
|
418
|
-
|
|
419
|
-
If you don't know the chart type ahead of time, use the router:
|
|
420
|
-
|
|
421
|
-
```typescript
|
|
422
|
-
import { parseDgmoChartType, getRenderCategory, isExtendedChartType, parseChart, parseExtendedChart } from '@diagrammo/dgmo';
|
|
423
|
-
|
|
424
|
-
const chartType = parseDgmoChartType(content); // e.g. 'bar'
|
|
425
|
-
const category = getRenderCategory(chartType); // 'data-chart' | 'visualization' | 'diagram' | null
|
|
426
|
-
|
|
427
|
-
// Dispatch within data-chart: standard vs extended parser
|
|
428
|
-
if (isExtendedChartType(chartType)) {
|
|
429
|
-
const parsed = parseExtendedChart(content); // scatter, sankey, heatmap, funnel, chord, function
|
|
430
|
-
} else {
|
|
431
|
-
const parsed = parseChart(content); // bar, line, pie, etc.
|
|
432
|
-
}
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
Content with `->` arrows and no chart type header is automatically detected as a sequence diagram.
|
|
436
|
-
|
|
437
|
-
## .dgmo file format
|
|
438
|
-
|
|
439
|
-
Plain text. Lines starting with `#` or `//` are comments. Empty lines are ignored.
|
|
440
|
-
|
|
441
|
-
```
|
|
442
|
-
<type> Optional Title
|
|
443
|
-
x-label X Axis
|
|
444
|
-
y-label Y Axis
|
|
445
|
-
series Series1, Series2
|
|
446
|
-
orientation horizontal
|
|
447
|
-
|
|
448
|
-
# Multi-line values (alternative to comma-separated)
|
|
449
|
-
series
|
|
450
|
-
Series1
|
|
451
|
-
Series2
|
|
452
|
-
|
|
453
|
-
# Data section
|
|
454
|
-
Label value
|
|
455
|
-
Label (color) value
|
|
456
|
-
Label value1, value2
|
|
457
|
-
|
|
458
|
-
# Connections (sankey, chord, arc)
|
|
459
|
-
Source -> Target weight
|
|
460
|
-
Source (color) -> Target (color) weight (linkcolor)
|
|
461
|
-
|
|
462
|
-
# Indentation syntax (sankey)
|
|
463
|
-
Source (color)
|
|
464
|
-
Target (color) weight (linkcolor)
|
|
465
|
-
|
|
466
|
-
# Groups
|
|
467
|
-
## Category Name
|
|
468
|
-
Item1 value
|
|
469
|
-
Item2 value
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
Colors can be specified inline as named colors (`red`, `blue`, `teal`, etc.) or hex values (`#ff6b6b`). They resolve against the active palette.
|
|
473
|
-
|
|
474
|
-
## Palettes
|
|
475
|
-
|
|
476
|
-
Thirteen built-in palettes, each with light and dark variants:
|
|
477
|
-
|
|
478
|
-
- `nordPalette` — cool, muted Scandinavian tones (default)
|
|
479
|
-
- `atlasPalette` — vintage classroom-map pastels on warm manila paper
|
|
480
|
-
- `blueprintPalette` — cyanotype engineering drawing (chalk on blueprint blue)
|
|
481
|
-
- `slatePalette` — restrained corporate/BI neutrals with one corporate blue
|
|
482
|
-
- `tidewaterPalette` — nautical maritime-chart (sea-mist, navy ink, brass)
|
|
483
|
-
- `solarizedPalette` — warm/cool Solarized
|
|
484
|
-
- `catppuccinPalette` — modern pastels
|
|
485
|
-
- `rosePinePalette` — soft mauve and rose
|
|
486
|
-
- `gruvboxPalette` — retro groove
|
|
487
|
-
- `tokyoNightPalette` — Tokyo night
|
|
488
|
-
- `oneDarkPalette` — Atom One Dark inspired
|
|
489
|
-
- `draculaPalette` — Dracula
|
|
490
|
-
- `monokaiPalette` — Monokai
|
|
491
|
-
|
|
492
|
-
```typescript
|
|
493
|
-
import { getPalette, getAvailablePalettes, registerPalette } from '@diagrammo/dgmo';
|
|
494
|
-
|
|
495
|
-
// Use a built-in palette
|
|
496
|
-
const palette = getPalette('nord');
|
|
497
|
-
const colors = palette.light; // or palette.dark
|
|
498
|
-
|
|
499
|
-
// List available palettes
|
|
500
|
-
const all = getAvailablePalettes(); // [{ id, name }, ...]
|
|
501
|
-
|
|
502
|
-
// Register a custom palette
|
|
503
|
-
registerPalette({
|
|
504
|
-
id: 'custom',
|
|
505
|
-
name: 'My Theme',
|
|
506
|
-
light: { bg: '#fff', surface: '#f5f5f5', /* ... */ },
|
|
507
|
-
dark: { bg: '#1a1a1a', surface: '#2a2a2a', /* ... */ },
|
|
508
|
-
});
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
### Color utilities
|
|
512
|
-
|
|
513
|
-
```typescript
|
|
514
|
-
import { hexToHSL, hslToHex, mute, tint, shade, contrastText } from '@diagrammo/dgmo';
|
|
515
|
-
|
|
516
|
-
hexToHSL('#5e81ac') // { h: 213, s: 32, l: 52 }
|
|
517
|
-
mute('#5e81ac') // desaturated + darkened hex
|
|
518
|
-
tint('#5e81ac', 0.3) // blended toward white
|
|
519
|
-
contrastText('#2e3440', '#eceff4', '#2e3440') // WCAG-compliant pick
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
### Mermaid theming
|
|
523
|
-
|
|
524
|
-
Generate Mermaid-compatible CSS variables from any palette:
|
|
525
|
-
|
|
526
|
-
```typescript
|
|
527
|
-
import { buildMermaidThemeVars, buildThemeCSS } from '@diagrammo/dgmo';
|
|
528
|
-
|
|
529
|
-
const vars = buildMermaidThemeVars(palette.light); // ~121 CSS custom properties
|
|
530
|
-
const css = buildThemeCSS(palette.light); // complete CSS string
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
## HTML embed (auto-render)
|
|
534
|
-
|
|
535
|
-
Drop a `<script>` tag on any static HTML page and any `<pre class="dgmo">` block becomes a rendered diagram on load.
|
|
536
|
-
|
|
537
|
-
### 60-second quickstart
|
|
538
|
-
|
|
539
|
-
```html
|
|
540
|
-
<!doctype html>
|
|
541
|
-
<html>
|
|
542
|
-
<head>
|
|
543
|
-
<!-- Add `integrity="sha384-…"` for SRI; the published value for each
|
|
544
|
-
release is in the GitHub release notes (or run `pnpm sri` after
|
|
545
|
-
building from source). -->
|
|
546
|
-
<script
|
|
547
|
-
src="https://cdn.jsdelivr.net/npm/@diagrammo/dgmo@^0.8/dist/auto.js"
|
|
548
|
-
crossorigin="anonymous"></script>
|
|
549
|
-
</head>
|
|
550
|
-
<body>
|
|
551
|
-
<pre class="dgmo">sequence Boarding the Marauder
|
|
552
|
-
|
|
553
|
-
Quartermaster -Hoist colors-> Crew
|
|
554
|
-
Crew -Aye, captain-> Bosun
|
|
555
|
-
Bosun -Heading 270-> Helm
|
|
556
|
-
Helm -On course-> Quartermaster
|
|
557
|
-
</pre>
|
|
558
|
-
</body>
|
|
559
|
-
</html>
|
|
72
|
+
`, { theme: 'light', palette: 'nord' });
|
|
560
73
|
```
|
|
561
74
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
Selectors matched: `.dgmo`, `.language-dgmo` (covers Prism/highlight.js fenced ` ```dgmo ` blocks). Already-rendered nodes are tagged `data-dgmo-processed="true"` so re-runs are idempotent.
|
|
75
|
+
`render()` auto-detects the chart type and dispatches to the right engine. Need the lower-level parsers, config builders, and per-type renderers? They live under the [`@diagrammo/dgmo/advanced`](https://diagrammo.app/dev) subpath — see the docs for the full surface and stability contract.
|
|
565
76
|
|
|
566
|
-
|
|
77
|
+
## Drop into any web page
|
|
567
78
|
|
|
568
|
-
|
|
79
|
+
Add one `<script>` tag and every `<pre class="dgmo">` block renders on load:
|
|
569
80
|
|
|
570
81
|
```html
|
|
571
|
-
<script
|
|
572
|
-
src="https://cdn.jsdelivr.net/npm/@diagrammo/dgmo@^0.8/dist/auto.js"
|
|
573
|
-
data-config='{"theme":"auto","palette":"nord","showSource":true,"showEditorLink":true}'
|
|
574
|
-
></script>
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
| Key | Type | Default | Description |
|
|
578
|
-
|-----|------|---------|-------------|
|
|
579
|
-
| `theme` | `'auto' \| 'light' \| 'dark' \| 'transparent'` | `'auto'` | `'auto'` reads `prefers-color-scheme`, `<html data-theme>`, and `<html class="dark">`; re-renders live when the system preference flips |
|
|
580
|
-
| `palette` | palette id (string) | `'nord'` | Any registered palette: `atlas`, `blueprint`, `catppuccin`, `dracula`, `gruvbox`, `monokai`, `nord`, `one-dark`, `rose-pine`, `slate`, `solarized`, `tidewater`, `tokyo-night` |
|
|
581
|
-
| `showSource` | `boolean` | `true` | Show the collapsible "DGMO source" panel under each diagram |
|
|
582
|
-
| `showEditorLink` | `boolean` | `true` | Include the "Open in editor" button (set `false` for air-gapped intranets) |
|
|
583
|
-
|
|
584
|
-
Per-element override: `<pre class="dgmo" data-show-source="false">` hides only that diagram's source panel.
|
|
585
|
-
|
|
586
|
-
Opt out of auto-bootstrap with `data-auto="false"` and call `dgmo.run()` manually after framework hydration:
|
|
82
|
+
<script src="https://cdn.jsdelivr.net/npm/@diagrammo/dgmo/dist/auto.js"></script>
|
|
587
83
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
84
|
+
<pre class="dgmo">pie Crew Rations
|
|
85
|
+
Grog: 58
|
|
86
|
+
Hardtack: 21
|
|
87
|
+
Limes: 21</pre>
|
|
591
88
|
```
|
|
592
89
|
|
|
593
|
-
|
|
90
|
+
Theme detection, copy button, and "open in editor" come for free. Full config, framework recipes (Astro, Docusaurus, Hugo, MkDocs), self-hosting, and CSP guidance: **[diagrammo.app/embed](https://diagrammo.app/embed)**.
|
|
594
91
|
|
|
595
|
-
|
|
596
|
-
|
|
92
|
+
Using a docs framework? First-class plugins wrap all of this:
|
|
93
|
+
[`remark-dgmo`](https://www.npmjs.com/package/remark-dgmo) · [`astro-dgmo`](https://www.npmjs.com/package/astro-dgmo) · [`docusaurus-plugin-dgmo`](https://www.npmjs.com/package/docusaurus-plugin-dgmo) · [`fumadocs-dgmo`](https://www.npmjs.com/package/fumadocs-dgmo)
|
|
597
94
|
|
|
598
|
-
Use
|
|
95
|
+
## Use it from your AI tool
|
|
599
96
|
|
|
600
|
-
|
|
601
|
-
---
|
|
602
|
-
// src/pages/index.astro
|
|
603
|
-
---
|
|
604
|
-
<script src="https://cdn.jsdelivr.net/npm/@diagrammo/dgmo@^0.8/dist/auto.js" is:inline></script>
|
|
605
|
-
<pre class="dgmo">pie Languages
|
|
606
|
-
TypeScript: 58
|
|
607
|
-
Rust: 21</pre>
|
|
608
|
-
```
|
|
97
|
+
There's an MCP server ([`@diagrammo/dgmo-mcp`](https://www.npmjs.com/package/@diagrammo/dgmo-mcp)) so Claude, Cursor, and other agents can author and render DGMO directly. Setup: **[diagrammo.app/ai](https://diagrammo.app/ai)**.
|
|
609
98
|
|
|
610
|
-
|
|
611
|
-
</details>
|
|
99
|
+
## Chart types
|
|
612
100
|
|
|
613
|
-
|
|
614
|
-
<summary><strong>Docusaurus / MDX</strong></summary>
|
|
101
|
+
**Data charts** — bar · line · area · pie · doughnut · radar · polar-area · bar-stacked · multi-line · scatter · heatmap · funnel · sankey · chord
|
|
615
102
|
|
|
616
|
-
|
|
103
|
+
**Visualizations** — slope · wordcloud · arc · timeline · venn · quadrant · tech-radar · cycle · pyramid · ring · function · map
|
|
617
104
|
|
|
618
|
-
|
|
619
|
-
module.exports = {
|
|
620
|
-
scripts: [{
|
|
621
|
-
src: 'https://cdn.jsdelivr.net/npm/@diagrammo/dgmo@^0.8/dist/auto.js',
|
|
622
|
-
'data-config': '{"theme":"auto"}',
|
|
623
|
-
async: false,
|
|
624
|
-
}],
|
|
625
|
-
};
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
If you use Prism, ensure it loads **after** the dgmo bundle, or set `data-auto="false"` and trigger `dgmo.run()` from a Docusaurus client module.
|
|
629
|
-
</details>
|
|
630
|
-
|
|
631
|
-
<details>
|
|
632
|
-
<summary><strong>MkDocs</strong></summary>
|
|
633
|
-
|
|
634
|
-
In `mkdocs.yml`:
|
|
635
|
-
|
|
636
|
-
```yaml
|
|
637
|
-
extra_javascript:
|
|
638
|
-
- https://cdn.jsdelivr.net/npm/@diagrammo/dgmo@^0.8/dist/auto.js
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
Markdown fences `` ```dgmo `` rendered by Pygments produce `<pre><code class="language-dgmo">…</code></pre>` — the auto bundle replaces the entire `<pre>`, leaving no empty shell.
|
|
642
|
-
</details>
|
|
105
|
+
**Diagrams** — sequence · flowchart · class · er · org · c4 · state · infra · kanban · sitemap · mindmap · gantt · pert · journey-map · boxes-and-lines · wireframe · raci
|
|
643
106
|
|
|
644
|
-
|
|
645
|
-
<summary><strong>Hugo</strong></summary>
|
|
107
|
+
Each type's full syntax, directives, and options live in the **[Language Reference](https://diagrammo.app/reference)** — the authoritative spec.
|
|
646
108
|
|
|
647
|
-
|
|
109
|
+
## Palettes & themes
|
|
648
110
|
|
|
649
|
-
|
|
650
|
-
<script src="https://cdn.jsdelivr.net/npm/@diagrammo/dgmo@^0.8/dist/auto.js"></script>
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
Include it from your base template's `<head>`. Hugo's chroma highlighter emits `<pre><code class="language-dgmo">…</code></pre>` which the bundle picks up automatically.
|
|
654
|
-
</details>
|
|
655
|
-
|
|
656
|
-
### Self-hosting
|
|
111
|
+
Thirteen built-in palettes, each with light, dark, and transparent variants:
|
|
657
112
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
```html
|
|
661
|
-
<script src="/static/auto.js" data-config='{"showEditorLink":false}'></script>
|
|
662
|
-
```
|
|
113
|
+
`nord` (default) · `atlas` · `blueprint` · `slate` · `tidewater` · `solarized` · `catppuccin` · `rose-pine` · `gruvbox` · `tokyo-night` · `one-dark` · `dracula` · `monokai`
|
|
663
114
|
|
|
664
|
-
|
|
115
|
+
Register your own with `registerPalette()`. Color helpers (`getPalette`, `tint`, `mute`, `contrastText`, …) and Mermaid theme-variable generation ship from the package too — see the [docs](https://diagrammo.app/dev).
|
|
665
116
|
|
|
666
|
-
|
|
117
|
+
## Editor support
|
|
667
118
|
|
|
668
|
-
|
|
119
|
+
Syntax highlighting and autocomplete for `.dgmo` files ship as ready-to-use exports:
|
|
669
120
|
|
|
670
|
-
|
|
671
|
-
|
|
121
|
+
- `@diagrammo/dgmo/highlight` — standalone highlighter
|
|
122
|
+
- `@diagrammo/dgmo/editor` — CodeMirror 6 language support
|
|
672
123
|
|
|
673
|
-
|
|
124
|
+
Both back the [desktop app](https://diagrammo.app/app) and the [live editor](https://online.diagrammo.app).
|
|
674
125
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
Recommended Content-Security-Policy snippet:
|
|
678
|
-
|
|
679
|
-
```
|
|
680
|
-
script-src 'self' https://cdn.jsdelivr.net;
|
|
681
|
-
style-src 'self' 'unsafe-inline';
|
|
682
|
-
connect-src 'self';
|
|
683
|
-
```
|
|
684
|
-
|
|
685
|
-
The bundle makes no `fetch`/XHR calls. The injected `<style>` block requires `'unsafe-inline'` in `style-src`; for strict CSP, link the parallel `dist/auto.css` artifact and the bundle skips inline injection.
|
|
686
|
-
|
|
687
|
-
`window.dgmo` and `window.diagrammo` are defined with `Object.defineProperty(..., { writable: false, configurable: false })` so a later-loaded script cannot intercept the API.
|
|
688
|
-
|
|
689
|
-
### SemVer policy
|
|
690
|
-
|
|
691
|
-
Within a major version, the following surface is stable for embedders:
|
|
692
|
-
|
|
693
|
-
- `window.dgmo` API (`initialize`, `run`, `version`)
|
|
694
|
-
- DOM contract (selector, wrapper class names, `data-dgmo-processed` flag)
|
|
695
|
-
- CSS class prefix `dgmo-`
|
|
696
|
-
- Error-banner shape (HTML class names + text format — locked so AI tools can screen-scrape it)
|
|
697
|
-
- Default values (`theme: 'auto'`, `palette: 'nord'`, `showSource: true`, `showEditorLink: true`)
|
|
698
|
-
- UTM parameter shape on the editor link
|
|
699
|
-
|
|
700
|
-
Any breaking change is a major-version bump. Pin `^0.8` (or whatever the current major is) in your CDN URL to opt out of breaking changes.
|
|
701
|
-
|
|
702
|
-
## Server-side / headless export
|
|
703
|
-
|
|
704
|
-
Render any chart to an SVG string without a visible DOM:
|
|
705
|
-
|
|
706
|
-
```typescript
|
|
707
|
-
import { renderForExport, renderExtendedChartForExport } from '@diagrammo/dgmo';
|
|
708
|
-
|
|
709
|
-
// Diagrams, visualizations, and sequence charts
|
|
710
|
-
const svg = await renderForExport(content, 'light');
|
|
711
|
-
|
|
712
|
-
// Data charts (bar, line, scatter, sankey, etc.)
|
|
713
|
-
const svg = await renderExtendedChartForExport(content, 'light');
|
|
714
|
-
```
|
|
715
|
-
|
|
716
|
-
Both accept an optional third argument for a custom `PaletteColors` object (defaults to Nord).
|
|
717
|
-
|
|
718
|
-
## API tiers
|
|
719
|
-
|
|
720
|
-
`@diagrammo/dgmo` ships three import paths with different stability contracts:
|
|
721
|
-
|
|
722
|
-
| Path | Surface | SemVer contract |
|
|
723
|
-
|------|---------|-----------------|
|
|
724
|
-
| `@diagrammo/dgmo` | `render`, `validate`, `encodeDiagramUrl`, `decodeDiagramUrl`, `palettes`, `getPalette`, `themes`, plus the `RenderOptions`, `RenderResult`, `CompactViewState`, `PaletteConfig`, `PaletteColors`, `Theme`, `DgmoError` types | **Stable.** Breaking changes only in major versions. Pin `^0.x` (or `^1.x` once we hit 1.0). |
|
|
725
|
-
| `@diagrammo/dgmo/highlight` | `highlightDgmo`, `NORD_ROLE_STYLES` and other role-style sets | **Stable.** Same policy as root. |
|
|
726
|
-
| `@diagrammo/dgmo/editor` | CodeMirror grammar + language support | **Stable.** Same policy as root. |
|
|
727
|
-
| `@diagrammo/dgmo/advanced` | Parsers (`parseChart`, `parseVisualization`, `parseSequenceDgmo`, …), layout helpers, config builders, low-level renderers, palette-color utilities, sequence internals — see the table below | **Reduced semver.** Symbols may be renamed, signatures may change, or exports may be removed in **minor** versions. Patch versions only fix bugs. Pin `~0.x.y` if you depend on `/advanced`. |
|
|
728
|
-
|
|
729
|
-
The `@diagrammo/dgmo/internal` subpath was renamed to `/advanced` in 0.15.x and exists as a re-export alias for one minor version. It will be removed in 0.17.x — update your imports to `/advanced` before then.
|
|
730
|
-
|
|
731
|
-
## /advanced exports
|
|
732
|
-
|
|
733
|
-
### Router
|
|
734
|
-
|
|
735
|
-
| Export | Description |
|
|
736
|
-
|--------|-------------|
|
|
737
|
-
| `parseDgmoChartType(content)` | Extract chart type from content (infers `sequence` from arrow syntax) |
|
|
738
|
-
| `getRenderCategory(type)` | Map chart type → `'data-chart'` \| `'visualization'` \| `'diagram'` \| `null` |
|
|
739
|
-
| `isExtendedChartType(type)` | Returns `true` for extended data-chart types (scatter, sankey, chord, function, heatmap, funnel) |
|
|
740
|
-
| `RenderCategory` | Type alias for `'data-chart' \| 'visualization' \| 'diagram'` |
|
|
741
|
-
|
|
742
|
-
### Parsers
|
|
743
|
-
|
|
744
|
-
| Export | Description |
|
|
745
|
-
|--------|-------------|
|
|
746
|
-
| `parseChart(content, colors)` | Parse standard data-chart types (bar, line, pie, radar, etc.) |
|
|
747
|
-
| `parseExtendedChart(content)` | Parse extended data-chart types (scatter, sankey, heatmap, etc.) |
|
|
748
|
-
| `parseVisualization(content, colors)` | Parse visualization types (slope, arc, timeline, etc.) |
|
|
749
|
-
| `parseSequenceDgmo(content)` | Parse sequence diagrams |
|
|
750
|
-
| `parseFlowchart(content, colors)` | Parse flowchart diagrams |
|
|
751
|
-
| `parseClassDiagram(content, colors)` | Parse class diagrams |
|
|
752
|
-
| `parseERDiagram(content, colors)` | Parse ER diagrams |
|
|
753
|
-
| `parseOrg(content, colors)` | Parse org chart diagrams |
|
|
754
|
-
| `parseQuadrant(content)` | Parse quadrant charts |
|
|
755
|
-
|
|
756
|
-
### Config builders
|
|
757
|
-
|
|
758
|
-
| Export | Description |
|
|
759
|
-
|--------|-------------|
|
|
760
|
-
| `buildSimpleChartOption(parsed, colors, dark)` | ECharts option from `parseChart` result (bar, line, pie, etc.) |
|
|
761
|
-
| `buildExtendedChartOption(parsed, colors, dark)` | ECharts option from `parseExtendedChart` result (scatter, sankey, etc.) |
|
|
762
|
-
| `buildMermaidQuadrant(parsed, colors)` | Mermaid quadrantChart syntax string |
|
|
763
|
-
|
|
764
|
-
### Renderers
|
|
765
|
-
|
|
766
|
-
| Export | Description |
|
|
767
|
-
|--------|-------------|
|
|
768
|
-
| `renderSlopeChart(el, parsed, colors, dark)` | Slope chart SVG |
|
|
769
|
-
| `renderArcDiagram(el, parsed, colors, dark)` | Arc diagram SVG |
|
|
770
|
-
| `renderTimeline(el, parsed, colors, dark)` | Timeline SVG |
|
|
771
|
-
| `renderWordCloud(el, parsed, colors, dark)` | Word cloud SVG |
|
|
772
|
-
| `renderVenn(el, parsed, colors, dark)` | Venn diagram SVG |
|
|
773
|
-
| `renderQuadrant(el, parsed, colors, dark)` | Quadrant chart SVG |
|
|
774
|
-
| `renderFlowchart(el, parsed, layout, colors, dark)` | Flowchart SVG |
|
|
775
|
-
| `renderClassDiagram(el, parsed, layout, colors, dark)` | Class diagram SVG |
|
|
776
|
-
| `renderERDiagram(el, parsed, layout, colors, dark)` | ER diagram SVG |
|
|
777
|
-
| `renderOrg(el, parsed, colors, dark)` | Org chart SVG |
|
|
778
|
-
| `layoutClassDiagram(parsed)` | Compute class diagram node positions |
|
|
779
|
-
| `layoutERDiagram(parsed)` | Compute ER diagram node positions |
|
|
780
|
-
| `layoutGraph(parsed)` | Compute flowchart node positions |
|
|
781
|
-
| `renderSequenceDiagram(el, parsed, colors, dark, onClick)` | Sequence diagram SVG |
|
|
782
|
-
| `renderForExport(content, theme, palette?)` | Any diagram or visualization → SVG string |
|
|
783
|
-
| `renderExtendedChartForExport(content, theme, palette?)` | Any data-chart → SVG string |
|
|
784
|
-
|
|
785
|
-
### Sequence internals
|
|
786
|
-
|
|
787
|
-
| Export | Description |
|
|
788
|
-
|--------|-------------|
|
|
789
|
-
| `buildRenderSequence(parsed)` | Ordered render steps from parsed diagram |
|
|
790
|
-
| `computeActivations(steps, participants)` | Activation bar positions |
|
|
791
|
-
| `applyPositionOverrides(participants, parsed)` | Apply `Name position N` overrides |
|
|
792
|
-
| `applyGroupOrdering(participants, groups)` | Reorder participants by group |
|
|
793
|
-
| `groupMessagesBySection(elements)` | Group elements into collapsible sections |
|
|
794
|
-
| `inferParticipantType(name)` | Infer participant type from name |
|
|
795
|
-
|
|
796
|
-
### Palette & color
|
|
797
|
-
|
|
798
|
-
| Export | Description |
|
|
799
|
-
|--------|-------------|
|
|
800
|
-
| `getPalette(id)` | Get palette by ID (falls back to Nord) |
|
|
801
|
-
| `getAvailablePalettes()` | List registered palettes `[{ id, name }]` |
|
|
802
|
-
| `registerPalette(config)` | Register a custom palette |
|
|
803
|
-
| `resolveColor(name, colors)` | Resolve color name or hex against a palette |
|
|
804
|
-
| `hexToHSL(hex)` / `hslToHex(h,s,l)` | Color conversion |
|
|
805
|
-
| `mute(hex)` / `tint(hex, amount)` / `shade(hex, base, amount)` | Color manipulation |
|
|
806
|
-
| `contrastText(bg, light, dark)` | WCAG contrast text picker |
|
|
807
|
-
| `buildMermaidThemeVars(colors)` | Mermaid CSS variables |
|
|
808
|
-
| `buildThemeCSS(colors)` | Complete Mermaid theme CSS |
|
|
809
|
-
|
|
810
|
-
## Development
|
|
811
|
-
|
|
812
|
-
### Prerequisites
|
|
813
|
-
|
|
814
|
-
- Node.js 18+
|
|
815
|
-
- pnpm (`npm install -g pnpm`)
|
|
816
|
-
|
|
817
|
-
### Setup
|
|
126
|
+
## Develop
|
|
818
127
|
|
|
819
128
|
```bash
|
|
820
129
|
pnpm install
|
|
821
130
|
pnpm build # tsup → dist/ (ESM + CJS + CLI)
|
|
131
|
+
pnpm test # vitest
|
|
132
|
+
pnpm typecheck
|
|
822
133
|
```
|
|
823
134
|
|
|
824
|
-
### Commands
|
|
825
|
-
|
|
826
|
-
```bash
|
|
827
|
-
pnpm build # Production build (lib + CLI)
|
|
828
|
-
pnpm dev # Watch mode (rebuild on save)
|
|
829
|
-
pnpm test # Run tests (Vitest)
|
|
830
|
-
pnpm test:watch # Tests in watch mode
|
|
831
|
-
pnpm typecheck # TypeScript type checking
|
|
832
|
-
```
|
|
833
|
-
|
|
834
|
-
### Quick CLI testing
|
|
835
|
-
|
|
836
|
-
```bash
|
|
837
|
-
./test-cli.sh input.dgmo [args...] # Builds and runs in one step
|
|
838
|
-
```
|
|
839
|
-
|
|
840
|
-
### Project structure
|
|
841
|
-
|
|
842
|
-
```
|
|
843
|
-
src/
|
|
844
|
-
├── index.ts # Public API exports
|
|
845
|
-
├── cli.ts # CLI entry point → dist/cli.cjs
|
|
846
|
-
├── dgmo-router.ts # Chart type → framework dispatcher
|
|
847
|
-
├── chart.ts # Standard chart parser (bar, line, pie, etc.)
|
|
848
|
-
├── echarts.ts # ECharts parser, config builder, SSR export
|
|
849
|
-
├── d3.ts # D3 parsers + renderers (slope, arc, timeline, wordcloud, venn, quadrant)
|
|
850
|
-
├── class/ # Class diagram parser, layout engine, and renderer
|
|
851
|
-
├── er/ # ER diagram parser, layout engine, and renderer
|
|
852
|
-
├── graph/ # Flowchart parser, layout engine, and renderer
|
|
853
|
-
├── org/ # Org chart parser, layout engine, and renderer
|
|
854
|
-
├── dgmo-mermaid.ts # Quadrant parser + Mermaid syntax builder
|
|
855
|
-
├── colors.ts # Named color map, resolve helper
|
|
856
|
-
├── fonts.ts # Font family constants (Helvetica for resvg)
|
|
857
|
-
├── sequence/
|
|
858
|
-
│ ├── parser.ts # Sequence diagram DSL parser
|
|
859
|
-
│ ├── renderer.ts # SVG renderer (D3-based)
|
|
860
|
-
│ └── participant-inference.ts # 104-rule name → type engine
|
|
861
|
-
└── palettes/
|
|
862
|
-
├── types.ts # PaletteConfig, PaletteColors types
|
|
863
|
-
├── registry.ts # getPalette, registerPalette
|
|
864
|
-
├── color-utils.ts # HSL conversions, mix(), mute(), tint()
|
|
865
|
-
├── mermaid-bridge.ts # Mermaid CSS variable builder
|
|
866
|
-
├── nord.ts # Nord palette (default)
|
|
867
|
-
├── atlas.ts # Atlas palette
|
|
868
|
-
├── blueprint.ts # Blueprint palette
|
|
869
|
-
├── slate.ts # Slate palette
|
|
870
|
-
├── tidewater.ts # Tidewater palette
|
|
871
|
-
├── solarized.ts # Solarized palette
|
|
872
|
-
├── catppuccin.ts # Catppuccin palette
|
|
873
|
-
├── rose-pine.ts # Rose Pine palette
|
|
874
|
-
├── gruvbox.ts # Gruvbox palette
|
|
875
|
-
├── tokyo-night.ts # Tokyo Night palette
|
|
876
|
-
├── one-dark.ts # One Dark palette
|
|
877
|
-
├── dracula.ts # Dracula palette
|
|
878
|
-
└── monokai.ts # Monokai palette
|
|
879
|
-
```
|
|
880
|
-
|
|
881
|
-
### Build output
|
|
882
|
-
|
|
883
|
-
tsup produces:
|
|
884
|
-
- `dist/index.js` + `dist/index.d.ts` (ESM)
|
|
885
|
-
- `dist/index.cjs` + `dist/index.d.cts` (CJS)
|
|
886
|
-
- `dist/cli.cjs` (CLI binary — bundles everything except `@resvg/resvg-js`)
|
|
887
|
-
|
|
888
|
-
### Testing
|
|
889
|
-
|
|
890
|
-
Tests live in `tests/` and use Vitest with jsdom:
|
|
891
|
-
|
|
892
|
-
```bash
|
|
893
|
-
pnpm test # Run all tests
|
|
894
|
-
pnpm test -- --reporter verbose # Verbose output
|
|
895
|
-
```
|
|
896
|
-
|
|
897
|
-
## Releasing
|
|
898
|
-
|
|
899
|
-
### npm publish
|
|
900
|
-
|
|
901
|
-
1. Bump version in `package.json`
|
|
902
|
-
2. Build and test:
|
|
903
|
-
```bash
|
|
904
|
-
pnpm build && pnpm test
|
|
905
|
-
```
|
|
906
|
-
3. Publish:
|
|
907
|
-
```bash
|
|
908
|
-
npm publish
|
|
909
|
-
```
|
|
910
|
-
4. After publishing, update downstream consumers:
|
|
911
|
-
- **homebrew-dgmo**: Update `Formula/dgmo.rb` with new tarball URL and sha256
|
|
912
|
-
- **obsidian-dgmo**: Update `@diagrammo/dgmo` version in `package.json`
|
|
913
|
-
- **diagrammo-app**: Update submodule ref (`git submodule update --remote`)
|
|
914
|
-
|
|
915
|
-
### Generating the sha256 for Homebrew
|
|
916
|
-
|
|
917
|
-
```bash
|
|
918
|
-
VERSION=0.2.7 # new version
|
|
919
|
-
curl -sL "https://registry.npmjs.org/@diagrammo/dgmo/-/dgmo-${VERSION}.tgz" | shasum -a 256
|
|
920
|
-
```
|
|
921
|
-
|
|
922
|
-
## Gallery
|
|
923
|
-
|
|
924
|
-
The gallery renders every fixture in `gallery/fixtures/` across all palettes, themes, and formats, producing a filterable HTML page.
|
|
925
|
-
|
|
926
|
-
```bash
|
|
927
|
-
pnpm gallery # Build CLI + render all combinations
|
|
928
|
-
```
|
|
929
|
-
|
|
930
|
-
Output lands in `gallery/output/` (gitignored):
|
|
931
|
-
|
|
932
|
-
- `gallery/output/renders/` — individual SVG and PNG files
|
|
933
|
-
- `gallery/output/index.html` — filterable gallery page (open in a browser)
|
|
934
|
-
|
|
935
|
-
### Filter options
|
|
936
|
-
|
|
937
|
-
```bash
|
|
938
|
-
pnpm gallery -- --chart bar
|
|
939
|
-
pnpm gallery -- --palette nord
|
|
940
|
-
pnpm gallery -- --theme dark
|
|
941
|
-
pnpm gallery -- --format svg
|
|
942
|
-
pnpm gallery -- --chart sequence --palette catppuccin --theme light --format png
|
|
943
|
-
pnpm gallery -- --concurrency 4 # defaults to CPU count
|
|
944
|
-
```
|
|
945
|
-
|
|
946
|
-
### Adding fixtures
|
|
947
|
-
|
|
948
|
-
Drop a new `.dgmo` file into `gallery/fixtures/` and re-run `pnpm gallery`.
|
|
949
|
-
|
|
950
135
|
## License
|
|
951
136
|
|
|
952
|
-
MIT
|
|
137
|
+
MIT © Demian Neidetcher
|
package/dist/auto.cjs
CHANGED
|
@@ -59158,7 +59158,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
|
59158
59158
|
|
|
59159
59159
|
// src/auto/index.ts
|
|
59160
59160
|
init_safe_href();
|
|
59161
|
-
var VERSION = "0.25.
|
|
59161
|
+
var VERSION = "0.25.3";
|
|
59162
59162
|
var DEFAULTS = {
|
|
59163
59163
|
theme: "auto",
|
|
59164
59164
|
palette: "nord",
|
package/dist/auto.js
CHANGED
|
@@ -400,7 +400,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
|
400
400
|
.dgmo-rendered.dgmo-theme-dark .dgmo-source-pre .dgmo-tok-comment,
|
|
401
401
|
.dgmo-rendered.dgmo-theme-dark .dgmo-source-pre .dgmo-tok-noteContent,
|
|
402
402
|
.dgmo-rendered.dgmo-theme-dark .dgmo-source-pre .dgmo-tok-punctuation { color: #616e88; }
|
|
403
|
-
`;wtt();var rQt="0.25.
|
|
403
|
+
`;wtt();var rQt="0.25.3",hLr={theme:"auto",palette:"nord",showSource:!0,showEditorLink:!0},Qxt={...hLr},Cet=new Set,pLr="https://online.diagrammo.app",gLr=8192,Xxn=256*1024,mLr=200,bLr=1200,vLr="[dgmo:auto]",wLr=/[\x00-\x1F--]/g,eQt="dgmoAutoStyles";function R1(...r){typeof console<"u"&&console.warn&&console.warn(vLr,...r)}function Jxn(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function yLr(r){r.querySelectorAll("script, foreignObject").forEach(a=>a.remove());let o=[r,...Array.from(r.querySelectorAll("*"))];for(let a of o){for(let c of Array.from(a.attributes))c.name.toLowerCase().startsWith("on")&&a.removeAttribute(c.name);if(a.hasAttribute("href")&&AC(a.getAttribute("href"))===null&&a.removeAttribute("href"),a.hasAttributeNS("http://www.w3.org/1999/xlink","href")){let c=a.getAttributeNS("http://www.w3.org/1999/xlink","href");AC(c)===null&&a.removeAttributeNS("http://www.w3.org/1999/xlink","href")}}}function Zxn(r){try{return Pgt().some(n=>n.id===r)}catch{return!1}}function Qxn(){if(typeof document>"u")return null;let r=document.currentScript;if(r&&r instanceof HTMLScriptElement)return r;let n=document.querySelectorAll('script[src*="auto.js"], script[src*="auto.min.js"]');return n.length===0?null:n[n.length-1]}var xLr=["theme","palette","showSource","showEditorLink"],t2n=["__proto__","constructor","prototype"],SLr=["auto","light","dark","transparent"];function e2n(r){return typeof r=="string"&&SLr.includes(r)}function n2n(r){if(!r)return{};let n;try{n=JSON.parse(r)}catch(a){return R1("data-config: invalid JSON",a),{}}if(!Jxn(n))return R1("data-config: not an object"),{};for(let a of t2n)if(Object.prototype.hasOwnProperty.call(n,a))return R1("data-config: rejected (prototype-pollution key:",a,")"),{};let o={};for(let[a,c]of Object.entries(n)){if(!xLr.includes(a)){R1("data-config: dropping unknown key",a);continue}if(a==="theme"){if(!e2n(c)){R1("data-config: rejected theme",c);continue}o.theme=c}else if(a==="palette"){if(typeof c!="string"||!Zxn(c)){R1("data-config: rejected palette",c);continue}o.palette=c}else if(a==="showSource"){if(typeof c!="boolean"){R1("data-config: rejected showSource",c);continue}o.showSource=c}else if(a==="showEditorLink"){if(typeof c!="boolean"){R1("data-config: rejected showEditorLink",c);continue}o.showEditorLink=c}}return o}function r2n(r=document){let n=r.querySelectorAll(".dgmo:not([data-dgmo-processed]), .language-dgmo:not([data-dgmo-processed])");return Array.from(n).filter(o=>!o.closest(".dgmo-rendered"))}function i2n(r){if(r==="light"||r==="dark"||r==="transparent")return r;if(typeof document>"u")return"light";let n=document.documentElement,o=n.getAttribute("data-theme");return o==="dark"?"dark":o==="light"?"light":n.classList.contains("dark")?"dark":n.classList.contains("light")?"light":typeof window<"u"&&window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function o2n(){if(typeof document>"u")return;let r=document.documentElement;if(r?.dataset?.[eQt]==="1")return;if(document.querySelector('link[rel="stylesheet"][href*="auto.css"]')){r&&r.dataset&&(r.dataset[eQt]="1");return}let o=document.createElement("style");o.setAttribute("data-dgmo-auto",""),o.textContent=qxn,document.head.appendChild(o),r&&r.dataset&&(r.dataset[eQt]="1")}function ELr(r){let n=document.createDocumentFragment(),o;try{o=Yxn(r)}catch{return n.appendChild(document.createTextNode(r)),n}for(let a of o){if(!a.text)continue;let c=document.createElement("span");c.className=`dgmo-tok-${a.role}`,c.textContent=a.text,n.appendChild(c)}return n}var a2n='<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5.5" y="5.5" width="8" height="8" rx="1.5"/><path d="M10.5 5.5V3a1.5 1.5 0 0 0-1.5-1.5H3A1.5 1.5 0 0 0 1.5 3v6A1.5 1.5 0 0 0 3 10.5h2.5"/></svg>',_Lr='<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="3 8.5 6.5 12 13 4.5"/></svg>',kLr='<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 2h5v5"/><path d="M14 2L7 9"/><path d="M13 9v4a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h4"/></svg>';function t2t(r,n){r.innerHTML=n}function TLr(r,n,o){let a=document.createElement("div");a.className="dgmo-source-panel";let c=document.createElement("button");c.type="button",c.className="dgmo-source-toggle",c.setAttribute("aria-expanded","false");let u=document.createElement("span");u.className="dgmo-chevron",u.setAttribute("aria-hidden","true"),u.textContent="\u25B8",c.appendChild(u);let f=document.createElement("span");f.textContent="DGMO source",c.appendChild(f);let d=document.createElement("div");d.className="dgmo-source-body";let b=document.createElement("pre");b.className="dgmo-source-pre",b.appendChild(ELr(r)),d.appendChild(b);let v=document.createElement("div");v.className="dgmo-source-actions";let y=document.createElement("button");if(y.type="button",y.className="dgmo-btn dgmo-btn-copy",y.setAttribute("aria-label","Copy DGMO source"),y.title="Copy source",t2t(y,a2n),y.addEventListener("click",()=>{CLr(r,y)}),v.appendChild(y),o){let x=document.createElement("a");x.className="dgmo-btn dgmo-btn-editor",x.target="_blank",x.rel="noopener noreferrer",x.setAttribute("aria-label","Open in editor"),t2t(x,kLr),n?(x.href=n,x.title="Open in editor"):(x.setAttribute("aria-disabled","true"),x.title="Diagram too large for share link; copy source and paste into editor",x.addEventListener("click",S=>S.preventDefault())),v.appendChild(x)}return d.appendChild(v),a.appendChild(c),a.appendChild(d),c.addEventListener("click",()=>{let x=d.classList.toggle("dgmo-open");c.setAttribute("aria-expanded",x?"true":"false")}),a}async function CLr(r,n){let o=!1;try{navigator?.clipboard?.writeText&&(await navigator.clipboard.writeText(r),o=!0)}catch{}if(!o&&typeof document<"u")try{let a=document.createElement("textarea");a.value=r,a.setAttribute("readonly",""),a.style.position="absolute",a.style.left="-9999px",document.body.appendChild(a),a.select(),o=document.execCommand("copy"),document.body.removeChild(a)}catch{o=!1}o?(t2t(n,_Lr),n.classList.add("dgmo-btn-copied"),setTimeout(()=>{t2t(n,a2n),n.classList.remove("dgmo-btn-copied")},bLr)):R1("clipboard write failed")}function Tet(r){let n=document.createElement("div");n.className="dgmo-error-banner",n.setAttribute("role","alert");let o=document.createElement("div");if(o.className="dgmo-error-banner-title",o.textContent=`${r.severity??"error"}: ${r.message}`,n.appendChild(o),r.line!==void 0&&r.line>0){let a=document.createElement("div");a.className="dgmo-error-banner-loc",a.textContent=r.column!==void 0?`at ${r.line}:${r.column}`:`at line ${r.line}`,n.appendChild(a)}return n}function MLr(r){let n=r.split(`
|
|
404
404
|
`).map(o=>o.trim()).find(o=>o.length>0);return n?n.replace(wLr,"").slice(0,mLr):"DGMO diagram"}function LLr(r){if(r.tagName==="CODE"){let n=r.parentElement;if(n?.tagName==="PRE"){let o=Array.from(n.childNodes).filter(a=>a.nodeType===1||a.nodeType===3&&(a.textContent||"").trim().length>0);if(o.length===1&&o[0]===r)return n}}return r}async function s2n(r){if(!(r instanceof HTMLElement))return{};if(r.dataset.dgmoProcessed==="true")return{};r.dataset.dgmoProcessed="true";let n=r.textContent||"";if(new TextEncoder().encode(n).byteLength>Xxn){r.style.visibility="";let A=Tet({message:`DGMO source too large to render \u2014 ${Xxn/1024} KB max`,severity:"error"});return r.parentElement?.insertBefore(A,r),R1("source exceeds 256 KB cap"),{}}let a=Qxt,c=a.theme==="transparent"?"transparent":i2n(a.theme),u=c==="transparent"?"transparent":c,f=MLr(n),d=r.dataset.showSource,b=a.showSource;d==="true"?b=!0:d==="false"?b=!1:d!==void 0&&R1("data-show-source: invalid value",d,'\u2014 expected "true" or "false"');let v;try{v=await kxn(n,{theme:u,palette:a.palette})}catch(A){r.style.visibility="";let I=A instanceof Error?A.message:"Render failed unexpectedly",N=Tet({message:I,severity:"error"});return r.parentElement?.insertBefore(N,r),R1("render() rejected:",A),{}}if(v.diagnostics&&v.diagnostics.length>0){r.style.visibility="";let A=v.diagnostics[0],I=Tet({message:A.message,severity:A.severity,line:A.line,...A.column!==void 0&&{column:A.column}});return r.parentElement?.insertBefore(I,r),R1("diagnostic:",A.message,A.line,A.column),{}}if(!v.svg){r.style.visibility="";let A=Tet({message:"Empty SVG returned from renderer",severity:"error"});return r.parentElement?.insertBefore(A,r),{}}let y=document.createElement("div"),x=c==="dark"?"dgmo-theme-dark":c==="transparent"?"dgmo-theme-transparent":"dgmo-theme-light";y.className=`dgmo-rendered ${x}`,y.dataset.dgmoProcessed="true";let S=document.createElement("div");S.innerHTML=v.svg;let _=S.querySelector("svg");if(!_){r.style.visibility="";let A=Tet({message:"Empty SVG returned from renderer",severity:"error"});return r.parentElement?.insertBefore(A,r),{}}if(yLr(_),_.setAttribute("role","img"),_.setAttribute("aria-label",f),y.appendChild(_),b){let A=null;if(a.showEditorLink){let N=c==="dark"?"dark":"light",D=Mxn(n,{baseUrl:pLr,palette:a.palette,theme:N});if(D.url){let G=`utm_source=auto-embed&utm_medium=html&utm_campaign=${encodeURIComponent(rQt)}`,B=D.url.indexOf("#"),O;if(B===-1){let W=D.url.includes("?")?"&":"?";O=D.url+W+G}else{let W=D.url.slice(0,B),Y=D.url.slice(B+1),H=W.includes("?")?"&":"?",j=Y.length>0?"&":"";O=W+H+G+"#"+Y+j+G}A=O,AC(A)||(A=null)}else D.error==="too-large"&&D.compressedSize>gLr&&(A=null)}let I=TLr(n,A,a.showEditorLink);y.appendChild(I)}let C={wrapper:y,source:n,perElementShowSource:d==="true"?!0:d==="false"?!1:null};return Cet.add(C),LLr(r).replaceWith(y),{wrapper:y}}function iQt(r={}){if(!Jxn(r))return;for(let o of t2n)if(Object.prototype.hasOwnProperty.call(r,o)){R1("initialize: rejected (prototype-pollution key:",o,")");return}let n={...Qxt};e2n(r.theme)&&(n.theme=r.theme),typeof r.palette=="string"&&Zxn(r.palette)&&(n.palette=r.palette),typeof r.showSource=="boolean"&&(n.showSource=r.showSource),typeof r.showEditorLink=="boolean"&&(n.showEditorLink=r.showEditorLink),Qxt=n}async function oQt(r={}){o2n();for(let o of Array.from(Cet))document.contains(o.wrapper)||Cet.delete(o);let n;if(r.nodes){n=("length"in r.nodes&&typeof r.nodes!="string"?Array.from(r.nodes):[]).filter(c=>c instanceof Element&&(c.matches(".dgmo, .language-dgmo")||c.querySelector(".dgmo, .language-dgmo")!==null));let a=[];for(let c of n)c.matches(".dgmo, .language-dgmo")&&a.push(c),c.querySelectorAll(".dgmo:not([data-dgmo-processed]), .language-dgmo:not([data-dgmo-processed])").forEach(f=>a.push(f));n=Array.from(new Set(a)).filter(c=>!c.closest(".dgmo-rendered"))}else n=r2n();await Promise.all(n.map(o=>s2n(o).catch(()=>({}))))}function ALr(){if(Qxt.theme==="auto")for(let r of Array.from(Cet)){let n=document.createElement("pre");n.className="dgmo",n.textContent=r.source,r.perElementShowSource!==null&&(n.dataset.showSource=String(r.perElementShowSource)),r.wrapper.replaceWith(n),Cet.delete(r),s2n(n)}}function ILr(){if(typeof window>"u"||!window.matchMedia)return;let r=window.matchMedia("(prefers-color-scheme: dark)"),n=()=>ALr();r.addEventListener?r.addEventListener("change",n):"addListener"in r&&typeof r.addListener=="function"&&r.addListener(n)}function nQt(){if(typeof document>"u")return;document.querySelectorAll(".dgmo:not(.dgmo-rendered), .language-dgmo").forEach(n=>{n.closest(".dgmo-rendered")||(n.style.visibility="visible")}),document.documentElement&&document.documentElement.dataset&&(document.documentElement.dataset.dgmoAutoFailed="1")}function NLr(){try{o2n();let r=Qxn(),n=r?.getAttribute("data-auto"),o=r?.getAttribute("data-config");if(o){let c=n2n(o);iQt(c)}if(ILr(),typeof window<"u"&&window.setTimeout(()=>{document.querySelectorAll(".dgmo:not(.dgmo-rendered):not([data-dgmo-processed])").length>0&&(R1("safety timeout: un-hiding unrendered sources"),nQt())},3e4),n==="false")return;let a=()=>{oQt().catch(c=>{R1("run() crashed:",c),nQt()})};typeof document<"u"&&document.readyState!=="loading"?a():typeof document<"u"&&document.addEventListener("DOMContentLoaded",a,{once:!0})}catch(r){R1("bootstrap failed:",r),nQt()}}var c2n=Object.freeze({initialize:iQt,run:oQt,version:rQt});function Kxn(r,n){try{Object.defineProperty(r,n,{value:c2n,writable:!1,configurable:!1,enumerable:!0})}catch{}}typeof window<"u"&&(Kxn(window,"dgmo"),Kxn(window,"diagrammo"),NLr());var PLr=c2n;return qze(DLr);})();
|
|
405
405
|
/*! Bundled license information:
|
|
406
406
|
|
package/dist/auto.mjs
CHANGED
|
@@ -59168,7 +59168,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
|
59168
59168
|
|
|
59169
59169
|
// src/auto/index.ts
|
|
59170
59170
|
init_safe_href();
|
|
59171
|
-
var VERSION = "0.25.
|
|
59171
|
+
var VERSION = "0.25.3";
|
|
59172
59172
|
var DEFAULTS = {
|
|
59173
59173
|
theme: "auto",
|
|
59174
59174
|
palette: "nord",
|
package/dist/index.cjs
CHANGED
|
@@ -58782,8 +58782,11 @@ function computeBBox(svg) {
|
|
|
58782
58782
|
const y = attr(tag, "y");
|
|
58783
58783
|
if (x !== null && y !== null) {
|
|
58784
58784
|
const w = text.length * 7;
|
|
58785
|
-
|
|
58786
|
-
|
|
58785
|
+
const anchor = tag.match(/\btext-anchor="([^"]*)"/)?.[1] ?? "start";
|
|
58786
|
+
const left = anchor === "middle" ? x - w / 2 : anchor === "end" ? x - w : x;
|
|
58787
|
+
const right = anchor === "middle" ? x + w / 2 : anchor === "end" ? x : x + w;
|
|
58788
|
+
push(left, y - 14);
|
|
58789
|
+
push(right, y + 4);
|
|
58787
58790
|
}
|
|
58788
58791
|
}
|
|
58789
58792
|
for (const m of svg.matchAll(/<path\b[^>]*?\bd="([^"]+)"/g)) {
|
package/dist/index.js
CHANGED
|
@@ -58787,8 +58787,11 @@ function computeBBox(svg) {
|
|
|
58787
58787
|
const y = attr(tag, "y");
|
|
58788
58788
|
if (x !== null && y !== null) {
|
|
58789
58789
|
const w = text.length * 7;
|
|
58790
|
-
|
|
58791
|
-
|
|
58790
|
+
const anchor = tag.match(/\btext-anchor="([^"]*)"/)?.[1] ?? "start";
|
|
58791
|
+
const left = anchor === "middle" ? x - w / 2 : anchor === "end" ? x - w : x;
|
|
58792
|
+
const right = anchor === "middle" ? x + w / 2 : anchor === "end" ? x : x + w;
|
|
58793
|
+
push(left, y - 14);
|
|
58794
|
+
push(right, y + 4);
|
|
58792
58795
|
}
|
|
58793
58796
|
}
|
|
58794
58797
|
for (const m of svg.matchAll(/<path\b[^>]*?\bd="([^"]+)"/g)) {
|
package/package.json
CHANGED
package/src/utils/svg-embed.ts
CHANGED
|
@@ -204,9 +204,18 @@ function computeBBox(
|
|
|
204
204
|
const y = attr(tag, 'y');
|
|
205
205
|
if (x !== null && y !== null) {
|
|
206
206
|
const w = text.length * 7;
|
|
207
|
-
// text-anchor
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
// Honor text-anchor so the horizontal extent points the right way:
|
|
208
|
+
// `start` (SVG default) grows rightward from x, `end` grows leftward,
|
|
209
|
+
// `middle` straddles x. Assuming middle for everything under-measures
|
|
210
|
+
// start-anchored text (e.g. pyramid right-column descriptions), which
|
|
211
|
+
// collapses the tight viewBox and clips that text in embeds.
|
|
212
|
+
const anchor = tag.match(/\btext-anchor="([^"]*)"/)?.[1] ?? 'start';
|
|
213
|
+
const left =
|
|
214
|
+
anchor === 'middle' ? x - w / 2 : anchor === 'end' ? x - w : x;
|
|
215
|
+
const right =
|
|
216
|
+
anchor === 'middle' ? x + w / 2 : anchor === 'end' ? x : x + w;
|
|
217
|
+
push(left, y - 14);
|
|
218
|
+
push(right, y + 4);
|
|
210
219
|
}
|
|
211
220
|
}
|
|
212
221
|
|