@diagrammo/dgmo 0.15.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/dist/advanced.cjs +479 -454
- package/dist/advanced.d.cts +34 -35
- package/dist/advanced.d.ts +34 -35
- package/dist/advanced.js +479 -453
- package/dist/auto.cjs +374 -352
- package/dist/auto.js +103 -103
- package/dist/auto.mjs +374 -352
- package/dist/cli.cjs +140 -140
- package/dist/editor.cjs +8 -9
- package/dist/editor.js +8 -9
- package/dist/highlight.cjs +8 -9
- package/dist/highlight.js +8 -9
- package/dist/index.cjs +365 -342
- package/dist/index.js +365 -342
- package/dist/internal.cjs +479 -454
- package/dist/internal.d.cts +34 -35
- package/dist/internal.d.ts +34 -35
- package/dist/internal.js +479 -453
- package/dist/pert.d.cts +2 -2
- package/dist/pert.d.ts +2 -2
- package/docs/language-reference.md +83 -66
- package/gallery/fixtures/area.dgmo +3 -3
- package/gallery/fixtures/bar-stacked.dgmo +5 -5
- package/gallery/fixtures/boxes-and-lines.dgmo +2 -2
- package/gallery/fixtures/c4-full.dgmo +8 -8
- package/gallery/fixtures/class-full.dgmo +2 -2
- package/gallery/fixtures/doughnut.dgmo +6 -6
- package/gallery/fixtures/flowchart-colors.dgmo +3 -3
- package/gallery/fixtures/function.dgmo +3 -3
- package/gallery/fixtures/gantt-full.dgmo +9 -9
- package/gallery/fixtures/gantt.dgmo +7 -7
- package/gallery/fixtures/infra-full.dgmo +6 -6
- package/gallery/fixtures/infra.dgmo +2 -2
- package/gallery/fixtures/kanban.dgmo +9 -9
- package/gallery/fixtures/line.dgmo +2 -2
- package/gallery/fixtures/multi-line.dgmo +3 -3
- package/gallery/fixtures/org-full.dgmo +6 -6
- package/gallery/fixtures/quadrant.dgmo +2 -2
- package/gallery/fixtures/sankey.dgmo +9 -9
- package/gallery/fixtures/scatter.dgmo +3 -3
- package/gallery/fixtures/sequence-tags-protocols.dgmo +8 -8
- package/gallery/fixtures/sequence-tags.dgmo +7 -7
- package/gallery/fixtures/sitemap-full.dgmo +7 -7
- package/gallery/fixtures/slope.dgmo +5 -5
- package/gallery/fixtures/spr-eras.dgmo +9 -9
- package/gallery/fixtures/timeline.dgmo +3 -3
- package/gallery/fixtures/venn.dgmo +3 -3
- package/package.json +1 -1
- package/src/advanced.ts +0 -1
- package/src/boxes-and-lines/renderer.ts +5 -1
- package/src/c4/parser.ts +1 -1
- package/src/c4/renderer.ts +15 -8
- package/src/chart.ts +18 -9
- package/src/class/parser.ts +7 -6
- package/src/class/renderer.ts +17 -6
- package/src/cli.ts +6 -6
- package/src/completion.ts +13 -3
- package/src/cycle/parser.ts +14 -0
- package/src/cycle/renderer.ts +6 -3
- package/src/d3.ts +86 -46
- package/src/echarts.ts +26 -9
- package/src/editor/dgmo.grammar +1 -3
- package/src/editor/dgmo.grammar.js +8 -8
- package/src/editor/dgmo.grammar.terms.js +11 -12
- package/src/editor/highlight-api.ts +0 -1
- package/src/editor/highlight.ts +0 -1
- package/src/er/parser.ts +18 -11
- package/src/er/renderer.ts +19 -7
- package/src/gantt/parser.ts +1 -1
- package/src/gantt/renderer.ts +7 -4
- package/src/graph/flowchart-parser.ts +18 -84
- package/src/graph/flowchart-renderer.ts +3 -8
- package/src/graph/layout.ts +0 -2
- package/src/graph/state-parser.ts +17 -62
- package/src/graph/state-renderer.ts +3 -8
- package/src/infra/parser.ts +21 -11
- package/src/infra/renderer.ts +7 -4
- package/src/journey-map/parser.ts +10 -3
- package/src/journey-map/renderer.ts +3 -1
- package/src/kanban/parser.ts +10 -6
- package/src/kanban/renderer.ts +3 -1
- package/src/mindmap/parser.ts +2 -2
- package/src/mindmap/renderer.ts +2 -1
- package/src/org/parser.ts +2 -2
- package/src/org/renderer.ts +4 -3
- package/src/pert/parser.ts +7 -7
- package/src/pert/renderer.ts +7 -2
- package/src/pert/types.ts +1 -1
- package/src/pyramid/parser.ts +12 -0
- package/src/raci/parser.ts +40 -10
- package/src/raci/renderer.ts +2 -1
- package/src/raci/types.ts +4 -3
- package/src/ring/parser.ts +12 -0
- package/src/sequence/parser.ts +15 -9
- package/src/sequence/renderer.ts +1 -1
- package/src/sitemap/layout.ts +0 -2
- package/src/sitemap/parser.ts +11 -37
- package/src/sitemap/renderer.ts +13 -13
- package/src/sitemap/types.ts +0 -1
- package/src/tech-radar/renderer.ts +5 -3
- package/src/tech-radar/types.ts +2 -0
- package/src/utils/arrows.ts +3 -28
- package/src/utils/legend-d3.ts +12 -6
- package/src/utils/legend-layout.ts +1 -1
- package/src/utils/legend-types.ts +1 -1
- package/src/utils/parsing.ts +64 -35
- package/src/utils/tag-groups.ts +98 -18
- package/src/wireframe/parser.ts +2 -2
package/src/cycle/parser.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
measureIndent,
|
|
8
8
|
parseFirstLine,
|
|
9
9
|
parsePipeMetadata,
|
|
10
|
+
peelTrailingColorName,
|
|
10
11
|
tryParseSharedOption,
|
|
11
12
|
} from '../utils/parsing';
|
|
12
13
|
import type { ParsedCycle, CycleNode, CycleEdge } from './types';
|
|
@@ -149,6 +150,7 @@ export function parseCycle(content: string): ParsedCycle {
|
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
// Parse node: Label | color: blue, span: 3, description: text
|
|
153
|
+
// OR shortcut form (color only): `Label color` (universal §1.5)
|
|
152
154
|
const pipeIdx = trimmed.indexOf('|');
|
|
153
155
|
let label: string;
|
|
154
156
|
let metadata: Record<string, string> = {};
|
|
@@ -166,6 +168,18 @@ export function parseCycle(content: string): ParsedCycle {
|
|
|
166
168
|
continue;
|
|
167
169
|
}
|
|
168
170
|
|
|
171
|
+
// Universal trailing-token shortcut: if no `| color:` was set explicitly
|
|
172
|
+
// and the label ends in a recognized color word, treat that word as the
|
|
173
|
+
// color and strip it from the label.
|
|
174
|
+
if (!metadata['color']) {
|
|
175
|
+
const { label: stripped, colorName: shortcutColor } =
|
|
176
|
+
peelTrailingColorName(label);
|
|
177
|
+
if (shortcutColor) {
|
|
178
|
+
metadata['color'] = shortcutColor;
|
|
179
|
+
label = stripped;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
169
183
|
// Extract known keys from metadata
|
|
170
184
|
const color = metadata['color'];
|
|
171
185
|
const spanStr = metadata['span'];
|
package/src/cycle/renderer.ts
CHANGED
|
@@ -46,6 +46,7 @@ export interface CycleRenderOptions {
|
|
|
46
46
|
controlsExpanded?: boolean;
|
|
47
47
|
onToggleDescriptions?: (active: boolean) => void;
|
|
48
48
|
onToggleControlsExpand?: () => void;
|
|
49
|
+
exportMode?: boolean;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
/**
|
|
@@ -144,7 +145,7 @@ export function renderCycle(
|
|
|
144
145
|
const legendConfig: LegendConfig = {
|
|
145
146
|
groups: [],
|
|
146
147
|
position: { placement: 'top-center', titleRelation: 'below-title' },
|
|
147
|
-
mode: '
|
|
148
|
+
mode: renderOptions?.exportMode ? 'export' : 'preview',
|
|
148
149
|
controlsGroup,
|
|
149
150
|
};
|
|
150
151
|
const legendState: LegendState = {
|
|
@@ -519,7 +520,8 @@ export function renderCycleForExport(
|
|
|
519
520
|
palette: PaletteColors,
|
|
520
521
|
isDark: boolean,
|
|
521
522
|
exportDims?: D3ExportDimensions,
|
|
522
|
-
viewState?: CompactViewState
|
|
523
|
+
viewState?: CompactViewState,
|
|
524
|
+
exportMode?: boolean
|
|
523
525
|
): void {
|
|
524
526
|
renderCycle(
|
|
525
527
|
container,
|
|
@@ -528,7 +530,8 @@ export function renderCycleForExport(
|
|
|
528
530
|
isDark,
|
|
529
531
|
undefined,
|
|
530
532
|
exportDims,
|
|
531
|
-
viewState
|
|
533
|
+
viewState,
|
|
534
|
+
{ exportMode }
|
|
532
535
|
);
|
|
533
536
|
}
|
|
534
537
|
|
package/src/d3.ts
CHANGED
|
@@ -205,6 +205,7 @@ import {
|
|
|
205
205
|
normalizeNumericToken,
|
|
206
206
|
parseFirstLine,
|
|
207
207
|
parsePipeMetadata,
|
|
208
|
+
peelTrailingColorName,
|
|
208
209
|
MULTIPLE_PIPE_ERROR,
|
|
209
210
|
} from './utils/parsing';
|
|
210
211
|
import {
|
|
@@ -593,8 +594,12 @@ export function parseVisualization(
|
|
|
593
594
|
currentTimelineTagGroup = null;
|
|
594
595
|
}
|
|
595
596
|
|
|
596
|
-
// [Group] container headers for arc
|
|
597
|
-
|
|
597
|
+
// [Group] container headers for arc / timeline (§1.5 trailing-token):
|
|
598
|
+
// `[Group]` — no color
|
|
599
|
+
// `[Group] color` — trailing-token color (recognized palette word)
|
|
600
|
+
const groupMatch = line.match(
|
|
601
|
+
/^\[(.+?)\](?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
|
|
602
|
+
);
|
|
598
603
|
if (groupMatch) {
|
|
599
604
|
if (result.type === 'arc') {
|
|
600
605
|
const name = groupMatch[1].trim();
|
|
@@ -649,10 +654,11 @@ export function parseVisualization(
|
|
|
649
654
|
currentTimelineGroup = null;
|
|
650
655
|
}
|
|
651
656
|
|
|
652
|
-
// Arc link line
|
|
657
|
+
// Arc link line (§1.5 trailing-token):
|
|
658
|
+
// `source -> target [color] [weight]` — color before weight
|
|
653
659
|
if (result.type === 'arc') {
|
|
654
660
|
const linkMatch = line.match(
|
|
655
|
-
/^(.+?)\s*->\s*(.+?)(?:\(
|
|
661
|
+
/^(.+?)\s*->\s*(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?(?:\s+(-?[\d,_]+(?:\.[\d]+)?))?$/
|
|
656
662
|
);
|
|
657
663
|
if (linkMatch) {
|
|
658
664
|
const source = linkMatch[1].trim();
|
|
@@ -698,8 +704,12 @@ export function parseVisualization(
|
|
|
698
704
|
// fall through to process this line normally
|
|
699
705
|
} else {
|
|
700
706
|
if (line.startsWith('//')) continue;
|
|
707
|
+
// Timeline era block entry (\u00a71.5 trailing-token):
|
|
708
|
+
// `<start> -> <end> Label` (no color)
|
|
709
|
+
// `<start> -> <end> Label color` (trailing color word)
|
|
710
|
+
// Color (group 4) must be a recognized lowercase palette word.
|
|
701
711
|
const eraEntryMatch = line.match(
|
|
702
|
-
/^(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s*(?:->|\u2013>)\s*(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s
|
|
712
|
+
/^(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s*(?:->|\u2013>)\s*(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
|
|
703
713
|
);
|
|
704
714
|
if (eraEntryMatch) {
|
|
705
715
|
const colorAnnotation = eraEntryMatch[4]?.trim() || null;
|
|
@@ -731,8 +741,9 @@ export function parseVisualization(
|
|
|
731
741
|
// fall through to process this line normally
|
|
732
742
|
} else {
|
|
733
743
|
if (line.startsWith('//')) continue;
|
|
744
|
+
// Timeline marker block entry (§1.5 trailing-token).
|
|
734
745
|
const markerEntryMatch = line.match(
|
|
735
|
-
/^(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s
|
|
746
|
+
/^(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
|
|
736
747
|
);
|
|
737
748
|
if (markerEntryMatch) {
|
|
738
749
|
const colorAnnotation = markerEntryMatch[3]?.trim() || null;
|
|
@@ -772,9 +783,11 @@ export function parseVisualization(
|
|
|
772
783
|
continue;
|
|
773
784
|
}
|
|
774
785
|
|
|
775
|
-
// Timeline era lines
|
|
786
|
+
// Timeline era lines, inline (\u00a71.5 trailing-token):
|
|
787
|
+
// `era YYYY->YYYY Label` \u2014 no color
|
|
788
|
+
// `era YYYY->YYYY Label color` \u2014 trailing-token color (recognized palette word)
|
|
776
789
|
const eraMatch = line.match(
|
|
777
|
-
/^era\s+(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s*(?:->|\u2013>)\s*(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s
|
|
790
|
+
/^era\s+(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s*(?:->|\u2013>)\s*(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
|
|
778
791
|
);
|
|
779
792
|
if (eraMatch) {
|
|
780
793
|
const colorAnnotation = eraMatch[4]?.trim() || null;
|
|
@@ -795,9 +808,11 @@ export function parseVisualization(
|
|
|
795
808
|
continue;
|
|
796
809
|
}
|
|
797
810
|
|
|
798
|
-
// Timeline marker lines
|
|
811
|
+
// Timeline marker lines, inline (§1.5 trailing-token):
|
|
812
|
+
// `marker YYYY Label` — no color
|
|
813
|
+
// `marker YYYY Label color` — trailing-token color
|
|
799
814
|
const markerMatch = line.match(
|
|
800
|
-
/^marker\s+(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s
|
|
815
|
+
/^marker\s+(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
|
|
801
816
|
);
|
|
802
817
|
if (markerMatch) {
|
|
803
818
|
const colorAnnotation = markerMatch[3]?.trim() || null;
|
|
@@ -959,19 +974,20 @@ export function parseVisualization(
|
|
|
959
974
|
}
|
|
960
975
|
}
|
|
961
976
|
|
|
962
|
-
// Set declaration
|
|
963
|
-
//
|
|
977
|
+
// Set declaration (§1.5 universal trailing-token):
|
|
978
|
+
// `Name` / `Name color` / `Name as <alias>` / `Name color as <alias>`
|
|
979
|
+
// Legacy `Name color alias <token>` emits E_VENN_ALIAS_KEYWORD_REMOVED.
|
|
964
980
|
// Only attempt set parsing if the line wasn't a bare-keyword option (handled above).
|
|
965
981
|
if (!/^(solid-fill|no-name|no-value|no-percent|no-title)$/i.test(line)) {
|
|
966
982
|
// Detect legacy `alias` keyword first — graceful degradation parses
|
|
967
983
|
// the rest of the line so the set still appears.
|
|
968
|
-
const legacyAliasMatch = line.match(
|
|
969
|
-
/^([^(:]+?)(?:\(([^)]+)\))?\s+alias\s+(\S+)\s*$/i
|
|
970
|
-
);
|
|
984
|
+
const legacyAliasMatch = line.match(/^(.+?)\s+alias\s+(\S+)\s*$/i);
|
|
971
985
|
if (legacyAliasMatch) {
|
|
972
|
-
const
|
|
973
|
-
const
|
|
974
|
-
|
|
986
|
+
const nameWithMaybeColor = legacyAliasMatch[1].trim();
|
|
987
|
+
const aliasToken = legacyAliasMatch[2].trim();
|
|
988
|
+
// Split off trailing-token color from the name region.
|
|
989
|
+
const { label: name, colorName } =
|
|
990
|
+
peelTrailingColorName(nameWithMaybeColor);
|
|
975
991
|
let color: string | null = null;
|
|
976
992
|
if (colorName) {
|
|
977
993
|
color =
|
|
@@ -995,11 +1011,14 @@ export function parseVisualization(
|
|
|
995
1011
|
}
|
|
996
1012
|
|
|
997
1013
|
const setDeclMatch = line.match(
|
|
998
|
-
/^(
|
|
1014
|
+
/^(.+?)(?:\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11}))?\s*$/i
|
|
999
1015
|
);
|
|
1000
1016
|
if (setDeclMatch) {
|
|
1001
|
-
const
|
|
1002
|
-
const
|
|
1017
|
+
const nameWithMaybeColor = setDeclMatch[1].trim();
|
|
1018
|
+
const alias = setDeclMatch[2]?.trim() ?? null;
|
|
1019
|
+
// Split off trailing-token color from the name region (before `as`).
|
|
1020
|
+
const { label: name, colorName } =
|
|
1021
|
+
peelTrailingColorName(nameWithMaybeColor);
|
|
1003
1022
|
let color: string | null = null;
|
|
1004
1023
|
if (colorName) {
|
|
1005
1024
|
color =
|
|
@@ -1010,7 +1029,6 @@ export function parseVisualization(
|
|
|
1010
1029
|
palette
|
|
1011
1030
|
) ?? null;
|
|
1012
1031
|
}
|
|
1013
|
-
const alias = setDeclMatch[3]?.trim() ?? null;
|
|
1014
1032
|
result.vennSets.push({ name, alias, color, lineNumber });
|
|
1015
1033
|
continue;
|
|
1016
1034
|
}
|
|
@@ -1057,19 +1075,20 @@ export function parseVisualization(
|
|
|
1057
1075
|
continue;
|
|
1058
1076
|
}
|
|
1059
1077
|
|
|
1060
|
-
// Quadrant position labels
|
|
1078
|
+
// Quadrant position labels (§1.5 trailing-token):
|
|
1079
|
+
// `top-right Label` — no color
|
|
1080
|
+
// `top-right Label color` — trailing-token color (recognized palette word)
|
|
1061
1081
|
const quadrantLabelRe =
|
|
1062
1082
|
/^(top-right|top-left|bottom-left|bottom-right)\s+(.+)/i;
|
|
1063
1083
|
const quadrantMatch = line.match(quadrantLabelRe);
|
|
1064
1084
|
if (quadrantMatch) {
|
|
1065
1085
|
const position = quadrantMatch[1].toLowerCase();
|
|
1066
1086
|
const labelPart = quadrantMatch[2].trim();
|
|
1067
|
-
//
|
|
1068
|
-
const
|
|
1069
|
-
const
|
|
1070
|
-
const color = labelColorMatch
|
|
1087
|
+
// Peel trailing recognized color word from the label.
|
|
1088
|
+
const { label: text, colorName } = peelTrailingColorName(labelPart);
|
|
1089
|
+
const color = colorName
|
|
1071
1090
|
? (resolveColorWithDiagnostic(
|
|
1072
|
-
|
|
1091
|
+
colorName,
|
|
1073
1092
|
lineNumber,
|
|
1074
1093
|
result.diagnostics,
|
|
1075
1094
|
palette
|
|
@@ -1325,12 +1344,12 @@ export function parseVisualization(
|
|
|
1325
1344
|
continue;
|
|
1326
1345
|
}
|
|
1327
1346
|
|
|
1328
|
-
// Color annotation: `Label
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
const colorPart =
|
|
1347
|
+
// Color annotation (§1.5 trailing-token): `Label color` → split.
|
|
1348
|
+
const { label: labelPart, colorName: colorWord } =
|
|
1349
|
+
peelTrailingColorName(joinedLabel);
|
|
1350
|
+
const colorPart = colorWord
|
|
1332
1351
|
? (resolveColorWithDiagnostic(
|
|
1333
|
-
|
|
1352
|
+
colorWord,
|
|
1334
1353
|
lineNumber,
|
|
1335
1354
|
result.diagnostics,
|
|
1336
1355
|
palette
|
|
@@ -3885,7 +3904,8 @@ function renderTimelineTagLegendOverlay(
|
|
|
3885
3904
|
onTagStateChange:
|
|
3886
3905
|
| ((activeTagGroup: string | null, swimlaneTagGroup: string | null) => void)
|
|
3887
3906
|
| undefined,
|
|
3888
|
-
viewMode: boolean | undefined
|
|
3907
|
+
viewMode: boolean | undefined,
|
|
3908
|
+
exportMode?: boolean
|
|
3889
3909
|
): void {
|
|
3890
3910
|
if (parsed.timelineTagGroups.length === 0) return;
|
|
3891
3911
|
|
|
@@ -4038,7 +4058,7 @@ function renderTimelineTagLegendOverlay(
|
|
|
4038
4058
|
const centralConfig: LegendConfig = {
|
|
4039
4059
|
groups: centralGroups,
|
|
4040
4060
|
position: { placement: 'top-center', titleRelation: 'below-title' },
|
|
4041
|
-
mode: '
|
|
4061
|
+
mode: exportMode ? 'export' : 'preview',
|
|
4042
4062
|
capsulePillAddonWidth: iconAddon,
|
|
4043
4063
|
};
|
|
4044
4064
|
const centralState: LegendState = { activeGroup: centralActive };
|
|
@@ -5517,7 +5537,8 @@ export function renderTimeline(
|
|
|
5517
5537
|
activeTagGroup: string | null,
|
|
5518
5538
|
swimlaneTagGroup: string | null
|
|
5519
5539
|
) => void,
|
|
5520
|
-
viewMode?: boolean
|
|
5540
|
+
viewMode?: boolean,
|
|
5541
|
+
exportMode?: boolean
|
|
5521
5542
|
): void {
|
|
5522
5543
|
const setup = setupTimeline(
|
|
5523
5544
|
container,
|
|
@@ -5599,7 +5620,8 @@ export function renderTimeline(
|
|
|
5599
5620
|
swimlaneTagGroup,
|
|
5600
5621
|
activeTagGroup,
|
|
5601
5622
|
onTagStateChange,
|
|
5602
|
-
viewMode
|
|
5623
|
+
viewMode,
|
|
5624
|
+
exportMode
|
|
5603
5625
|
);
|
|
5604
5626
|
}
|
|
5605
5627
|
|
|
@@ -7512,8 +7534,10 @@ export async function renderForExport(
|
|
|
7512
7534
|
c4System?: string;
|
|
7513
7535
|
c4Container?: string;
|
|
7514
7536
|
tagGroup?: string;
|
|
7537
|
+
exportMode?: boolean;
|
|
7515
7538
|
}
|
|
7516
7539
|
): Promise<string> {
|
|
7540
|
+
const exportMode = options?.exportMode ?? false;
|
|
7517
7541
|
// Flowchart and org chart use their own parser pipelines — intercept before parseVisualization()
|
|
7518
7542
|
const { parseDgmoChartType } = await import('./dgmo-router');
|
|
7519
7543
|
const detectedType = parseDgmoChartType(content);
|
|
@@ -7567,7 +7591,9 @@ export async function renderForExport(
|
|
|
7567
7591
|
undefined,
|
|
7568
7592
|
{ width: exportWidth, height: exportHeight },
|
|
7569
7593
|
activeTagGroup,
|
|
7570
|
-
hiddenAttributes
|
|
7594
|
+
hiddenAttributes,
|
|
7595
|
+
undefined,
|
|
7596
|
+
exportMode
|
|
7571
7597
|
);
|
|
7572
7598
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
7573
7599
|
}
|
|
@@ -7621,7 +7647,8 @@ export async function renderForExport(
|
|
|
7621
7647
|
undefined,
|
|
7622
7648
|
{ width: exportWidth, height: exportHeight },
|
|
7623
7649
|
activeTagGroup,
|
|
7624
|
-
hiddenAttributes
|
|
7650
|
+
hiddenAttributes,
|
|
7651
|
+
exportMode
|
|
7625
7652
|
);
|
|
7626
7653
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
7627
7654
|
}
|
|
@@ -7650,6 +7677,7 @@ export async function renderForExport(
|
|
|
7650
7677
|
collapsedLanes: viewState?.cl ? new Set(viewState.cl) : undefined,
|
|
7651
7678
|
collapsedColumns: viewState?.cc ? new Set(viewState.cc) : undefined,
|
|
7652
7679
|
compactMeta: viewState?.cm,
|
|
7680
|
+
exportMode,
|
|
7653
7681
|
});
|
|
7654
7682
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
7655
7683
|
}
|
|
@@ -7677,7 +7705,9 @@ export async function renderForExport(
|
|
|
7677
7705
|
effectivePalette,
|
|
7678
7706
|
theme === 'dark',
|
|
7679
7707
|
undefined,
|
|
7680
|
-
{ width: exportWidth, height: exportHeight }
|
|
7708
|
+
{ width: exportWidth, height: exportHeight },
|
|
7709
|
+
undefined,
|
|
7710
|
+
exportMode
|
|
7681
7711
|
);
|
|
7682
7712
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
7683
7713
|
}
|
|
@@ -7711,7 +7741,8 @@ export async function renderForExport(
|
|
|
7711
7741
|
erParsed.options['active-tag'],
|
|
7712
7742
|
viewState?.tag ?? options?.tagGroup
|
|
7713
7743
|
),
|
|
7714
|
-
viewState?.sem
|
|
7744
|
+
viewState?.sem,
|
|
7745
|
+
exportMode
|
|
7715
7746
|
);
|
|
7716
7747
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
7717
7748
|
}
|
|
@@ -7751,6 +7782,7 @@ export async function renderForExport(
|
|
|
7751
7782
|
exportDims: { width: exportWidth, height: exportHeight },
|
|
7752
7783
|
activeTagGroup: viewState?.tag ?? options?.tagGroup,
|
|
7753
7784
|
hiddenTagValues: blHiddenTagValues,
|
|
7785
|
+
exportMode,
|
|
7754
7786
|
}
|
|
7755
7787
|
);
|
|
7756
7788
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
@@ -7810,7 +7842,7 @@ export async function renderForExport(
|
|
|
7810
7842
|
undefined,
|
|
7811
7843
|
hideDescriptions,
|
|
7812
7844
|
colorByDepth ? null : activeTagGroup,
|
|
7813
|
-
colorByDepth ? { colorByDepth: true } :
|
|
7845
|
+
colorByDepth ? { colorByDepth: true, exportMode } : { exportMode }
|
|
7814
7846
|
);
|
|
7815
7847
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
7816
7848
|
}
|
|
@@ -7912,7 +7944,8 @@ export async function renderForExport(
|
|
|
7912
7944
|
c4Parsed.tagGroups,
|
|
7913
7945
|
c4Parsed.options['active-tag'],
|
|
7914
7946
|
viewState?.tag ?? options?.tagGroup
|
|
7915
|
-
)
|
|
7947
|
+
),
|
|
7948
|
+
exportMode
|
|
7916
7949
|
);
|
|
7917
7950
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
7918
7951
|
}
|
|
@@ -8079,6 +8112,7 @@ export async function renderForExport(
|
|
|
8079
8112
|
resolved.options.activeTag ?? undefined,
|
|
8080
8113
|
viewState?.tag ?? options?.tagGroup
|
|
8081
8114
|
),
|
|
8115
|
+
exportMode,
|
|
8082
8116
|
},
|
|
8083
8117
|
{ width: EXPORT_W, height: EXPORT_H }
|
|
8084
8118
|
);
|
|
@@ -8126,7 +8160,8 @@ export async function renderForExport(
|
|
|
8126
8160
|
effectivePalette,
|
|
8127
8161
|
theme === 'dark',
|
|
8128
8162
|
{ width: RADAR_EXPORT_W, height: RADAR_EXPORT_H },
|
|
8129
|
-
viewState
|
|
8163
|
+
viewState,
|
|
8164
|
+
exportMode
|
|
8130
8165
|
);
|
|
8131
8166
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
8132
8167
|
}
|
|
@@ -8153,6 +8188,7 @@ export async function renderForExport(
|
|
|
8153
8188
|
);
|
|
8154
8189
|
renderJourneyMap(container, jmParsed, effectivePalette, theme === 'dark', {
|
|
8155
8190
|
exportDims: { width: jmLayout.totalWidth, height: jmLayout.totalHeight },
|
|
8191
|
+
exportMode,
|
|
8156
8192
|
});
|
|
8157
8193
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
8158
8194
|
}
|
|
@@ -8172,7 +8208,8 @@ export async function renderForExport(
|
|
|
8172
8208
|
effectivePalette,
|
|
8173
8209
|
theme === 'dark',
|
|
8174
8210
|
{ width: EXPORT_WIDTH, height: EXPORT_HEIGHT },
|
|
8175
|
-
viewState
|
|
8211
|
+
viewState,
|
|
8212
|
+
exportMode
|
|
8176
8213
|
);
|
|
8177
8214
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
8178
8215
|
}
|
|
@@ -8311,7 +8348,10 @@ export async function renderForExport(
|
|
|
8311
8348
|
undefined,
|
|
8312
8349
|
viewState?.tag ?? options?.tagGroup
|
|
8313
8350
|
),
|
|
8314
|
-
viewState?.swim
|
|
8351
|
+
viewState?.swim,
|
|
8352
|
+
undefined,
|
|
8353
|
+
undefined,
|
|
8354
|
+
exportMode
|
|
8315
8355
|
);
|
|
8316
8356
|
} else if (parsed.type === 'venn') {
|
|
8317
8357
|
renderVenn(container, parsed, effectivePalette, isDark, undefined, dims);
|
package/src/echarts.ts
CHANGED
|
@@ -367,12 +367,15 @@ export function parseExtendedChart(
|
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
// [Category] container header with optional color: [Category Name] or [Category Name](color)
|
|
370
|
-
|
|
370
|
+
// Category brackets with optional trailing-token color (§1.5):
|
|
371
|
+
// `[Name]` or `[Name] color`. Per universal rule, color is a bare token.
|
|
372
|
+
const categoryMatch = trimmed.match(/^\[(.+?)\](?:\s+(\S+))?\s*$/);
|
|
371
373
|
if (categoryMatch) {
|
|
372
374
|
const catName = categoryMatch[1].trim();
|
|
373
|
-
const
|
|
375
|
+
const rawCatColor = categoryMatch[2]?.trim();
|
|
376
|
+
const catColor = rawCatColor
|
|
374
377
|
? (resolveColorWithDiagnostic(
|
|
375
|
-
|
|
378
|
+
rawCatColor,
|
|
376
379
|
lineNumber,
|
|
377
380
|
result.diagnostics,
|
|
378
381
|
palette
|
|
@@ -388,9 +391,14 @@ export function parseExtendedChart(
|
|
|
388
391
|
continue;
|
|
389
392
|
}
|
|
390
393
|
|
|
391
|
-
// Sankey/chord link syntax
|
|
394
|
+
// Sankey/chord link syntax (§1.5 universal trailing-token):
|
|
395
|
+
// `Source -> Target value` (directed, no link color)
|
|
396
|
+
// `Source -> Target value linkColor` (directed, trailing-token link color)
|
|
397
|
+
// `Source -- Target value` (undirected)
|
|
398
|
+
// Link color (if present) must be a recognized lowercase palette word.
|
|
399
|
+
// Source/target labels still accept trailing-token color via extractColor.
|
|
392
400
|
const arrowMatch = trimmed.match(
|
|
393
|
-
/^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\d,_]+(?:\.[\d]+)?)
|
|
401
|
+
/^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\d,_]+(?:\.[\d]+)?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
|
|
394
402
|
);
|
|
395
403
|
if (arrowMatch) {
|
|
396
404
|
const [, rawSource, arrow, rawTarget, rawVal, rawLinkColor] = arrowMatch;
|
|
@@ -441,13 +449,22 @@ export function parseExtendedChart(
|
|
|
441
449
|
sankeyStack.pop();
|
|
442
450
|
}
|
|
443
451
|
if (sankeyStack.length > 0) {
|
|
444
|
-
//
|
|
445
|
-
//
|
|
452
|
+
// Indented sankey child (§1.5 trailing-token):
|
|
453
|
+
// `TargetName value` — link, no link color
|
|
454
|
+
// `TargetName value linkColor` — link with link color
|
|
455
|
+
// `TargetName nodeColor value` — node-colored child
|
|
456
|
+
// `TargetName nodeColor value linkColor` — both
|
|
457
|
+
// Strategy: peel a trailing recognized color word (after the value)
|
|
458
|
+
// first, then run parseDataRowValues on the remainder. Trailing
|
|
459
|
+
// tokens that aren't recognized colors stay in the data row.
|
|
446
460
|
const valColorMatch = trimmed.match(
|
|
447
|
-
/(-?[\d,_]+(?:\.[\d]+)?)\s
|
|
461
|
+
/(-?[\d,_]+(?:\.[\d]+)?)\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/
|
|
448
462
|
);
|
|
449
463
|
const strippedLine = valColorMatch
|
|
450
|
-
? trimmed.replace(
|
|
464
|
+
? trimmed.replace(
|
|
465
|
+
/\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/,
|
|
466
|
+
''
|
|
467
|
+
)
|
|
451
468
|
: trimmed;
|
|
452
469
|
const dataRow = parseDataRowValues(strippedLine);
|
|
453
470
|
if (dataRow && dataRow.values.length === 1) {
|
package/src/editor/dgmo.grammar
CHANGED
|
@@ -8,7 +8,6 @@ contentPart {
|
|
|
8
8
|
SectionMarker |
|
|
9
9
|
Url |
|
|
10
10
|
OpenBracket | CloseBracket | OpenParen | CloseParen | OpenAngle | CloseAngle |
|
|
11
|
-
ColorAnnotation |
|
|
12
11
|
Pipe | Colon | Comma | Plus | Dash | Tilde | Star | Question |
|
|
13
12
|
ChartType |
|
|
14
13
|
TagKeyword | DirectiveKeyword | ControlKeyword | ModifierKeyword |
|
|
@@ -38,7 +37,6 @@ contentPart {
|
|
|
38
37
|
|
|
39
38
|
SectionMarker { "==" }
|
|
40
39
|
Url { "http" "s"? "://" ![ \t\n|,)\]>]+ }
|
|
41
|
-
ColorAnnotation { "(" $[a-z\-]+ ")" }
|
|
42
40
|
|
|
43
41
|
Pipe { "|" }
|
|
44
42
|
Colon { ":" }
|
|
@@ -66,7 +64,7 @@ contentPart {
|
|
|
66
64
|
|
|
67
65
|
@precedence {
|
|
68
66
|
Comment, SyncArrow, AsyncArrow,
|
|
69
|
-
Duration, DateLiteral, Percentage, Number, SectionMarker, Url,
|
|
67
|
+
Duration, DateLiteral, Percentage, Number, SectionMarker, Url,
|
|
70
68
|
Pipe, Colon, Comma, Plus, Dash, Tilde, Star, Question,
|
|
71
69
|
OpenBracket, CloseBracket, OpenParen, CloseParen, OpenAngle, CloseAngle,
|
|
72
70
|
QuotedString, Identifier, Punct
|
|
@@ -3,16 +3,16 @@ import {LRParser} from "@lezer/lr"
|
|
|
3
3
|
import {specializeKeyword} from "./tokens"
|
|
4
4
|
export const parser = LRParser.deserialize({
|
|
5
5
|
version: 14,
|
|
6
|
-
states: "!WQVQPOOOOQO'#
|
|
7
|
-
stateData: "&
|
|
8
|
-
goto: "!
|
|
9
|
-
nodeNames: "⚠ ChartType TagKeyword DirectiveKeyword ControlKeyword ModifierKeyword Document Comment ContentLine SyncArrow AsyncArrow Duration DateLiteral Percentage Number SectionMarker Url OpenBracket CloseBracket OpenParen CloseParen OpenAngle CloseAngle
|
|
10
|
-
maxTerm:
|
|
6
|
+
states: "!WQVQPOOOOQO'#DU'#DUOOQO'#DP'#DPO%]QPO'#CdOOQO'#DO'#DOQVQPOOOOQO-E6}-E6}OOQO,59O,59OOOQO-E6|-E6|",
|
|
7
|
+
stateData: "&Q~OvOS~OPPOQPORPOSPOTPOVSOXPOYPOZPO[PO]PO^PO_PO`POaPObPOcPOdPOePOfPOgPOhPOiPOjPOkPOlPOmPOnPOoPOpPOqPOwSO~OPPOQPORPOSPOTPOXPOYPOZPO[PO]PO^PO_PO`POaPObPOcPOdPOePOfPOgPOhPOiPOjPOkPOlPOmPOnPOoPOpPOqPO~OwVO~P#]OVXYZ[]^_`ghijklmnabcdefopqk~",
|
|
8
|
+
goto: "!byPPPPPPPPzPPPPPPPPPPPPPPPPPPPPPPPPP!O!UPPPP!]TSOTQTORWTSROTRURVQORT",
|
|
9
|
+
nodeNames: "⚠ ChartType TagKeyword DirectiveKeyword ControlKeyword ModifierKeyword Document Comment ContentLine SyncArrow AsyncArrow Duration DateLiteral Percentage Number SectionMarker Url OpenBracket CloseBracket OpenParen CloseParen OpenAngle CloseAngle Pipe Colon Comma Plus Dash Tilde Star Question QuotedString Identifier Punct",
|
|
10
|
+
maxTerm: 40,
|
|
11
11
|
skippedNodes: [0],
|
|
12
12
|
repeatNodeCount: 2,
|
|
13
|
-
tokenData: "
|
|
13
|
+
tokenData: "<v~RzOX#uXY#zYZ$VZp#upq#zqr#urs$[st#uux#uxy%eyz%lz{%s{|%z|}&R}!O&Y!O!P#u!P!Q&i!Q!['Y![!]/{!]!^#u!^!_0S!_!`0Z!`!a0h!a!b0o!b!c#u!c!}0v!}#O3|#O#P#u#P#Q4R#Q#R#u#R#S0v#S#T#u#T#[0v#[#]4Y#]#o0v#o#p#u#p#q<Y#q#r#u#r#s<a#s;'S#u;'S;=`<p<%lO#u~#zOq~~$PQv~XY#zpq#z~$[Ow~~$aUq~OY$sZr$srs%Ys;'S$s;'S;=`%_<%lO$s~$vUOY$sZr$srs%Ys;'S$s;'S;=`%_<%lO$s~%_Oo~~%bP;=`<%l$s~%lOc~q~~%sOd~q~~%zOm~q~~&ROj~q~~&YOi~q~~&aPk~q~!`!a&d~&iOX~~&nPq~!P!Q&q~&vSV~OY&qZ;'S&q;'S;=`'S<%lO&q~'VP;=`<%l&q~'a]^~q~uv(Y|}(_!O!P)[!Q![*{#R#S/g#U#V*V#W#X*]#[#]*]#a#b*j#e#f*]#g#h*]#k#l*]#m#n*]~(_O]~~(bP!Q![(e~(hP!Q![(k~(nP!Q![(q~(vQ^~|}(_!O!P(|~)PP!Q![)S~)XP^~!Q![)S~)_P!Q![)b~)gY^~uv(Y!Q![)b#U#V*V#W#X*]#[#]*]#a#b*j#e#f*]#g#h*]#k#l*]#m#n*]~*YP#W#X*]~*bPZ~!a!b*e~*jOZ~~*oQZ~!a!b*e#]#^*u~*xP#b#c*]~+Q]^~uv(Y|}(_!O!P)[!Q![+y#R#S/g#U#V*V#W#X*]#[#]*]#a#b*j#e#f*]#g#h*]#k#l*]#m#n*]~,O]^~uv(Y|}(_!O!P)[!Q![,w#R#S/g#U#V*V#W#X*]#[#]*]#a#b*j#e#f*]#g#h*]#k#l*]#m#n*]~,|]^~uv(Y}!O-u!O!P)[!Q![.l#R#S/g#U#V*V#W#X*]#[#]*]#a#b*j#e#f*]#g#h*]#k#l*]#m#n*]~-xP!Q![-{~.OP!Q![.R~.WP[~}!O.Z~.^P!Q![.a~.dP!Q![.g~.lO[~~.q[^~uv(Y!O!P)[!Q![.l#R#S/g#U#V*V#W#X*]#[#]*]#a#b*j#e#f*]#g#h*]#k#l*]#m#n*]~/jP!Q![/m~/rR^~!O!P(|!Q![/m#R#S/g~0SOh~q~~0ZOe~q~~0`Pq~!_!`0c~0hO_~~0oOf~q~~0vOn~q~~0}_p~q~qr1|st1|vw1|wx1|{|1|}!O3Q!O!P1|!P!Q1|!Q![1|!_!`1|!a!b1|!b!c1|!c!}1|#R#S1|#T#o1|~2R_p~qr1|st1|vw1|wx1|{|1|}!O3Q!O!P1|!P!Q1|!Q![1|!_!`1|!a!b1|!b!c1|!c!}1|#R#S1|#T#o1|~3T]qr1|st1|vw1|wx1|{|1|!O!P1|!P!Q1|!_!`1|!a!b1|!b!c1|!c!}1|#R#S1|#T#o1|~4ROa~~4YOb~q~~4aap~q~qr1|st1|vw1|wx1|{|1|}!O3Q!O!P1|!P!Q1|!Q![1|!_!`1|!a!b1|!b!c1|!c!}1|#R#S1|#T#h1|#h#i5f#i#o1|~5kap~qr1|st1|vw1|wx1|{|1|}!O3Q!O!P1|!P!Q1|!Q![1|!_!`1|!a!b1|!b!c1|!c!}1|#R#S1|#T#h1|#h#i6p#i#o1|~6uap~qr1|st1|vw1|wx1|{|1|}!O3Q!O!P1|!P!Q1|!Q![1|!_!`1|!a!b1|!b!c1|!c!}1|#R#S1|#T#d1|#d#e7z#e#o1|~8Pbp~qr1|st1|vw1|wx1|{|1|}!O3Q!O!P1|!P!Q1|!Q![1|![!]9X!_!`1|!a!b1|!b!c1|!c!}1|#R#S1|#T#g1|#g#h;R#h#o1|~9[P!P!Q9_~9bP!P!Q9e~9hYOX:WZp:Wqy:Wz|:W}!`:W!a#P:W#Q#p:W#q;'S:W;'S;=`:{<%lO:W~:]Y`~OX:WZp:Wqy:Wz|:W}!`:W!a#P:W#Q#p:W#q;'S:W;'S;=`:{<%lO:W~;OP;=`<%l:W~;W`p~qr1|st1|vw1|wx1|{|1|}!O3Q!O!P1|!P!Q1|!Q![1|![!]9X!_!`1|!a!b1|!b!c1|!c!}1|#R#S1|#T#o1|~<aOg~q~~<hPl~q~!`!a<k~<pOY~~<sP;=`<%l#u",
|
|
14
14
|
tokenizers: [0],
|
|
15
15
|
topRules: {"Document":[0,6]},
|
|
16
|
-
specialized: [{term:
|
|
17
|
-
tokenPrec:
|
|
16
|
+
specialized: [{term: 32, get: (value, stack) => (specializeKeyword(value, stack) << 1), external: specializeKeyword}],
|
|
17
|
+
tokenPrec: 204
|
|
18
18
|
})
|
|
@@ -22,15 +22,14 @@ export const
|
|
|
22
22
|
CloseParen = 20,
|
|
23
23
|
OpenAngle = 21,
|
|
24
24
|
CloseAngle = 22,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Punct = 34
|
|
25
|
+
Pipe = 23,
|
|
26
|
+
Colon = 24,
|
|
27
|
+
Comma = 25,
|
|
28
|
+
Plus = 26,
|
|
29
|
+
Dash = 27,
|
|
30
|
+
Tilde = 28,
|
|
31
|
+
Star = 29,
|
|
32
|
+
Question = 30,
|
|
33
|
+
QuotedString = 31,
|
|
34
|
+
Identifier = 32,
|
|
35
|
+
Punct = 33
|
package/src/editor/highlight.ts
CHANGED