@diagrammo/dgmo 0.8.20 → 0.8.22
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/AGENTS.md +2 -1
- package/README.md +1 -0
- package/dist/cli.cjs +142 -90
- package/dist/editor.cjs +30 -4
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +30 -4
- package/dist/editor.js.map +1 -1
- package/dist/highlight.cjs +25 -3
- package/dist/highlight.cjs.map +1 -1
- package/dist/highlight.js +25 -3
- package/dist/highlight.js.map +1 -1
- package/dist/index.cjs +21201 -12886
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +646 -89
- package/dist/index.d.ts +646 -89
- package/dist/index.js +21178 -12889
- package/dist/index.js.map +1 -1
- package/docs/guide/chart-mindmap.md +198 -0
- package/docs/guide/chart-sequence.md +23 -1
- package/docs/guide/chart-sitemap.md +18 -1
- package/docs/guide/chart-tech-radar.md +219 -0
- package/docs/guide/chart-wireframe.md +100 -0
- package/docs/guide/index.md +8 -0
- package/docs/guide/registry.json +1 -0
- package/docs/language-reference.md +249 -4
- package/gallery/fixtures/boxes-and-lines.dgmo +10 -3
- package/gallery/fixtures/c4-full.dgmo +2 -2
- package/gallery/fixtures/cycle/ooda-loop.dgmo +25 -0
- package/gallery/fixtures/cycle/pdca-circle-nodes.dgmo +12 -0
- package/gallery/fixtures/cycle/pdca-minimal.dgmo +6 -0
- package/gallery/fixtures/cycle/sprint-cycle-span.dgmo +17 -0
- package/gallery/fixtures/gantt-full.dgmo +2 -2
- package/gallery/fixtures/gantt.dgmo +2 -2
- package/gallery/fixtures/infra-full.dgmo +2 -2
- package/gallery/fixtures/infra.dgmo +1 -1
- package/gallery/fixtures/sequence-tags-protocols.dgmo +2 -2
- package/gallery/fixtures/sequence-tags.dgmo +2 -2
- package/gallery/fixtures/tech-radar-dense.dgmo +77 -0
- package/gallery/fixtures/tech-radar.dgmo +36 -0
- package/gallery/fixtures/timeline.dgmo +1 -1
- package/package.json +1 -1
- package/src/boxes-and-lines/collapse.ts +21 -3
- package/src/boxes-and-lines/layout.ts +360 -42
- package/src/boxes-and-lines/parser.ts +94 -11
- package/src/boxes-and-lines/renderer.ts +371 -114
- package/src/boxes-and-lines/types.ts +2 -1
- package/src/c4/layout.ts +8 -8
- package/src/c4/parser.ts +35 -2
- package/src/c4/renderer.ts +19 -3
- package/src/c4/types.ts +1 -0
- package/src/chart.ts +14 -7
- package/src/completion.ts +253 -0
- package/src/cycle/layout.ts +732 -0
- package/src/cycle/parser.ts +352 -0
- package/src/cycle/renderer.ts +539 -0
- package/src/cycle/types.ts +77 -0
- package/src/d3.ts +240 -40
- package/src/dgmo-router.ts +15 -0
- package/src/echarts.ts +7 -4
- package/src/editor/dgmo.grammar +5 -1
- package/src/editor/dgmo.grammar.js +1 -1
- package/src/editor/keywords.ts +26 -0
- package/src/gantt/parser.ts +2 -8
- package/src/graph/flowchart-parser.ts +15 -21
- package/src/graph/layout.ts +73 -9
- package/src/graph/state-collapse.ts +78 -0
- package/src/graph/state-parser.ts +5 -10
- package/src/graph/state-renderer.ts +139 -34
- package/src/index.ts +78 -0
- package/src/infra/layout.ts +218 -74
- package/src/infra/parser.ts +30 -6
- package/src/infra/renderer.ts +14 -8
- package/src/infra/types.ts +10 -3
- package/src/journey-map/layout.ts +386 -0
- package/src/journey-map/parser.ts +540 -0
- package/src/journey-map/renderer.ts +1456 -0
- package/src/journey-map/types.ts +47 -0
- package/src/kanban/parser.ts +3 -10
- package/src/kanban/renderer.ts +325 -63
- package/src/mindmap/collapse.ts +88 -0
- package/src/mindmap/layout.ts +605 -0
- package/src/mindmap/parser.ts +373 -0
- package/src/mindmap/renderer.ts +544 -0
- package/src/mindmap/text-wrap.ts +217 -0
- package/src/mindmap/types.ts +55 -0
- package/src/org/parser.ts +2 -6
- package/src/render.ts +18 -21
- package/src/sequence/renderer.ts +273 -56
- package/src/sharing.ts +3 -0
- package/src/sitemap/layout.ts +56 -18
- package/src/sitemap/parser.ts +26 -17
- package/src/sitemap/renderer.ts +34 -0
- package/src/sitemap/types.ts +1 -0
- package/src/tech-radar/index.ts +14 -0
- package/src/tech-radar/interactive.ts +1058 -0
- package/src/tech-radar/layout.ts +190 -0
- package/src/tech-radar/parser.ts +385 -0
- package/src/tech-radar/renderer.ts +1159 -0
- package/src/tech-radar/shared.ts +187 -0
- package/src/tech-radar/types.ts +81 -0
- package/src/utils/description-helpers.ts +33 -0
- package/src/utils/export-container.ts +3 -2
- package/src/utils/legend-d3.ts +1 -0
- package/src/utils/legend-layout.ts +5 -3
- package/src/utils/parsing.ts +48 -7
- package/src/utils/tag-groups.ts +46 -60
- package/src/wireframe/layout.ts +460 -0
- package/src/wireframe/parser.ts +956 -0
- package/src/wireframe/renderer.ts +1293 -0
- package/src/wireframe/types.ts +110 -0
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
OPTION_NOCOLON_RE,
|
|
21
21
|
} from '../utils/parsing';
|
|
22
22
|
|
|
23
|
-
const MAX_GROUP_DEPTH =
|
|
23
|
+
const MAX_GROUP_DEPTH = 2;
|
|
24
24
|
|
|
25
25
|
/** Boxes-and-lines requires explicit first line — no heuristic detection. */
|
|
26
26
|
export function looksLikeBoxesAndLines(_content: string): boolean {
|
|
@@ -45,9 +45,9 @@ function measureIndent(line: string): number {
|
|
|
45
45
|
function parsePipeMetadata(
|
|
46
46
|
segment: string,
|
|
47
47
|
aliasMap: Map<string, string>
|
|
48
|
-
): { metadata: Record<string, string>; description?: string } {
|
|
48
|
+
): { metadata: Record<string, string>; description?: string[] } {
|
|
49
49
|
const metadata: Record<string, string> = {};
|
|
50
|
-
let description: string | undefined;
|
|
50
|
+
let description: string[] | undefined;
|
|
51
51
|
|
|
52
52
|
const items = segment.split(',');
|
|
53
53
|
for (const item of items) {
|
|
@@ -59,7 +59,7 @@ function parsePipeMetadata(
|
|
|
59
59
|
const rawKey = trimmed.slice(0, colonIdx).trim().toLowerCase();
|
|
60
60
|
const value = trimmed.slice(colonIdx + 1).trim();
|
|
61
61
|
if (rawKey === 'description') {
|
|
62
|
-
description = value;
|
|
62
|
+
description = [value];
|
|
63
63
|
} else {
|
|
64
64
|
const resolvedKey = aliasMap.get(rawKey) ?? rawKey;
|
|
65
65
|
metadata[resolvedKey] = value;
|
|
@@ -98,6 +98,25 @@ export function parseBoxesAndLines(content: string): ParsedBoxesAndLines {
|
|
|
98
98
|
let lastNodeLabel: string | null = null;
|
|
99
99
|
let lastSourceIsGroup = false;
|
|
100
100
|
|
|
101
|
+
// Description collection state
|
|
102
|
+
let descState: {
|
|
103
|
+
nodeLabel: string;
|
|
104
|
+
indent: number;
|
|
105
|
+
lines: string[];
|
|
106
|
+
edgeSeen: boolean;
|
|
107
|
+
} | null = null;
|
|
108
|
+
|
|
109
|
+
function flushDescription() {
|
|
110
|
+
if (descState && descState.lines.length > 0) {
|
|
111
|
+
const node = result.nodes.find((n) => n.label === descState!.nodeLabel);
|
|
112
|
+
if (node) {
|
|
113
|
+
const existing = node.description ?? [];
|
|
114
|
+
node.description = [...existing, ...descState!.lines];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
descState = null;
|
|
118
|
+
}
|
|
119
|
+
|
|
101
120
|
// Group stack for nesting
|
|
102
121
|
interface GroupState {
|
|
103
122
|
group: BLGroup;
|
|
@@ -283,7 +302,51 @@ export function parseBoxesAndLines(content: string): ParsedBoxesAndLines {
|
|
|
283
302
|
|
|
284
303
|
// Non-indented line closes tag group
|
|
285
304
|
if (currentTagGroup && indent === 0) {
|
|
286
|
-
currentTagGroup = null;
|
|
305
|
+
currentTagGroup = null;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Description collection: indented non-edge lines under a node
|
|
309
|
+
if (descState !== null) {
|
|
310
|
+
if (indent > descState.indent) {
|
|
311
|
+
// Check if this is an edge line
|
|
312
|
+
if (trimmed.includes('->') || trimmed.includes('<->')) {
|
|
313
|
+
descState.edgeSeen = true;
|
|
314
|
+
// Fall through to normal edge processing
|
|
315
|
+
} else if (descState.edgeSeen) {
|
|
316
|
+
// Text after edges — emit warning
|
|
317
|
+
result.diagnostics.push(
|
|
318
|
+
makeDgmoError(
|
|
319
|
+
lineNum,
|
|
320
|
+
`Move description lines above edges for '${descState.nodeLabel}' — descriptions must come before -> lines`,
|
|
321
|
+
'warning'
|
|
322
|
+
)
|
|
323
|
+
);
|
|
324
|
+
continue;
|
|
325
|
+
} else if (
|
|
326
|
+
/^-\s*\w/.test(trimmed) &&
|
|
327
|
+
!trimmed.startsWith('- ') &&
|
|
328
|
+
!trimmed.includes('->') &&
|
|
329
|
+
!trimmed.includes('<->')
|
|
330
|
+
) {
|
|
331
|
+
// Looks like a malformed edge (e.g. "-Target" but not "- list item")
|
|
332
|
+
result.diagnostics.push(
|
|
333
|
+
makeDgmoError(
|
|
334
|
+
lineNum,
|
|
335
|
+
`Looks like an incomplete edge — did you mean "-> ${trimmed.slice(1).trim()}"?`,
|
|
336
|
+
'warning'
|
|
337
|
+
)
|
|
338
|
+
);
|
|
339
|
+
descState.lines.push(trimmed);
|
|
340
|
+
continue;
|
|
341
|
+
} else {
|
|
342
|
+
// Collect as description
|
|
343
|
+
descState.lines.push(trimmed);
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
} else {
|
|
347
|
+
// Indent decreased — flush description
|
|
348
|
+
flushDescription();
|
|
349
|
+
}
|
|
287
350
|
}
|
|
288
351
|
|
|
289
352
|
// Close groups that are no longer scoped by indent
|
|
@@ -358,6 +421,7 @@ export function parseBoxesAndLines(content: string): ParsedBoxesAndLines {
|
|
|
358
421
|
if (groupMatch && !trimmed.includes('->') && !trimmed.includes('<->')) {
|
|
359
422
|
contentStarted = true;
|
|
360
423
|
currentTagGroup = null;
|
|
424
|
+
flushDescription();
|
|
361
425
|
const label = groupMatch[1];
|
|
362
426
|
|
|
363
427
|
// Check nesting depth
|
|
@@ -387,13 +451,20 @@ export function parseBoxesAndLines(content: string): ParsedBoxesAndLines {
|
|
|
387
451
|
}
|
|
388
452
|
}
|
|
389
453
|
|
|
454
|
+
const parentGs = currentGroupState();
|
|
390
455
|
const group: BLGroup = {
|
|
391
456
|
label,
|
|
392
457
|
children: [],
|
|
393
458
|
lineNumber: lineNum,
|
|
394
459
|
metadata: groupMeta,
|
|
460
|
+
...(parentGs ? { parentGroup: parentGs.group.label } : {}),
|
|
395
461
|
};
|
|
396
462
|
|
|
463
|
+
// Add nested group as child of parent group
|
|
464
|
+
if (parentGs && indent > parentGs.indent) {
|
|
465
|
+
parentGs.group.children.push(label);
|
|
466
|
+
}
|
|
467
|
+
|
|
397
468
|
groupLabels.add(label);
|
|
398
469
|
groupStack.push({ group, indent, depth: currentDepth });
|
|
399
470
|
lastNodeLabel = label;
|
|
@@ -409,7 +480,18 @@ export function parseBoxesAndLines(content: string): ParsedBoxesAndLines {
|
|
|
409
480
|
|
|
410
481
|
// Indented shorthand: `-> Target` or `-label-> Target`
|
|
411
482
|
if (trimmed.startsWith('->') || /^-[^>].*->/.test(trimmed)) {
|
|
412
|
-
|
|
483
|
+
// If the edge is at group-child indent level, use the containing group
|
|
484
|
+
const gs = currentGroupState();
|
|
485
|
+
const inGroup = gs && indent > gs.indent;
|
|
486
|
+
if (inGroup) {
|
|
487
|
+
const sourcePrefix = `[${gs.group.label}]`;
|
|
488
|
+
edgeText = `${sourcePrefix} ${trimmed}`;
|
|
489
|
+
} else if (lastNodeLabel) {
|
|
490
|
+
const sourcePrefix = lastSourceIsGroup
|
|
491
|
+
? `[${lastNodeLabel}]`
|
|
492
|
+
: lastNodeLabel;
|
|
493
|
+
edgeText = `${sourcePrefix} ${trimmed}`;
|
|
494
|
+
} else {
|
|
413
495
|
result.diagnostics.push(
|
|
414
496
|
makeDgmoError(
|
|
415
497
|
lineNum,
|
|
@@ -419,10 +501,6 @@ export function parseBoxesAndLines(content: string): ParsedBoxesAndLines {
|
|
|
419
501
|
);
|
|
420
502
|
continue;
|
|
421
503
|
}
|
|
422
|
-
const sourcePrefix = lastSourceIsGroup
|
|
423
|
-
? `[${lastNodeLabel}]`
|
|
424
|
-
: lastNodeLabel;
|
|
425
|
-
edgeText = `${sourcePrefix} ${trimmed}`;
|
|
426
504
|
}
|
|
427
505
|
|
|
428
506
|
const edge = parseEdgeLine(
|
|
@@ -442,6 +520,7 @@ export function parseBoxesAndLines(content: string): ParsedBoxesAndLines {
|
|
|
442
520
|
// Node: everything else
|
|
443
521
|
contentStarted = true;
|
|
444
522
|
currentTagGroup = null;
|
|
523
|
+
flushDescription(); // Flush any pending description from previous node
|
|
445
524
|
const node = parseNodeLine(trimmed, lineNum, aliasMap, result.diagnostics);
|
|
446
525
|
if (!node) {
|
|
447
526
|
result.diagnostics.push(
|
|
@@ -479,8 +558,12 @@ export function parseBoxesAndLines(content: string): ParsedBoxesAndLines {
|
|
|
479
558
|
}
|
|
480
559
|
|
|
481
560
|
result.nodes.push(node);
|
|
561
|
+
descState = { nodeLabel: node.label, indent, lines: [], edgeSeen: false };
|
|
482
562
|
}
|
|
483
563
|
|
|
564
|
+
// Flush any remaining description
|
|
565
|
+
flushDescription();
|
|
566
|
+
|
|
484
567
|
// Close any remaining groups
|
|
485
568
|
while (groupStack.length > 0) {
|
|
486
569
|
const gs = groupStack.pop()!;
|
|
@@ -555,7 +638,7 @@ function parseNodeLine(
|
|
|
555
638
|
_diagnostics: DgmoError[]
|
|
556
639
|
): BLNode | null {
|
|
557
640
|
let metadata: Record<string, string> = {};
|
|
558
|
-
let description: string | undefined;
|
|
641
|
+
let description: string[] | undefined;
|
|
559
642
|
|
|
560
643
|
// Split on pipe for metadata
|
|
561
644
|
const pipeIdx = trimmed.indexOf('|');
|