@diagrammo/dgmo 0.47.0 → 0.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.js +11 -11
- package/dist/auto.js +16 -16
- package/dist/auto.mjs +41 -12
- package/dist/block.js +4 -4
- package/dist/{chunk-FNB3PNGF.js → chunk-7DTWEFUE.js} +3 -3
- package/dist/{chunk-2DXMZRWJ.js → chunk-B65G5DNL.js} +8 -1
- package/dist/{chunk-RZCF2VVM.js → chunk-B7JUCQUA.js} +3 -1
- package/dist/{chunk-DU7W62N5.js → chunk-FANX6UJR.js} +3 -3
- package/dist/{chunk-6FZYCKXB.js → chunk-HSH73DP6.js} +2 -2
- package/dist/{chunk-P4RH4OSP.js → chunk-ILKORZ3H.js} +2 -2
- package/dist/{chunk-Y5QGVTVC.js → chunk-JTSMEYIZ.js} +7 -3
- package/dist/{chunk-RCERWOJR.js → chunk-ODZVHU3R.js} +1 -2
- package/dist/{chunk-DZAQBW35.js → chunk-SGZYXELT.js} +3 -7
- package/dist/{chunk-CUVHQHZ7.js → chunk-THXCFRTU.js} +3 -3
- package/dist/{chunk-IH6ZMVQ5.js → chunk-UC7TFHUM.js} +29 -11
- package/dist/{chunk-EMS2SK26.js → chunk-ZBWMSD5N.js} +3 -1
- package/dist/cli.cjs +15 -15
- package/dist/{dgmo-router-DZCIDUO5.js → dgmo-router-X35VLZLM.js} +3 -3
- package/dist/element.js +16 -16
- package/dist/element.mjs +41 -12
- package/dist/{flowchart-renderer-ZAEOL4DX.js → flowchart-renderer-SNDSII4D.js} +2 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -4
- package/dist/{parser-FUSKFGZN.js → parser-2EWECDSA.js} +2 -2
- package/dist/{renderer-UWA5XS74.js → renderer-4JHRUBE6.js} +3 -3
- package/dist/{renderer-WZRREQ2P.js → renderer-5MYBMBYO.js} +2 -2
- package/dist/{renderer-TOCOVLHS.js → renderer-B2OMQIQG.js} +3 -3
- package/dist/{renderer-2XQQQ6QR.js → renderer-N43WR5GV.js} +3 -3
- package/dist/{renderer-T7YKC5VP.js → renderer-ZRNG54CW.js} +3 -3
- package/dist/{state-renderer-RFYHSP4K.js → state-renderer-B4DQBM6M.js} +2 -2
- package/package.json +23 -71
- package/dist/advanced.cjs +0 -71648
- package/dist/advanced.d.cts +0 -5719
- package/dist/auto.cjs +0 -70648
- package/dist/auto.d.cts +0 -54
- package/dist/block.cjs +0 -70208
- package/dist/block.d.cts +0 -115
- package/dist/editor.cjs +0 -526
- package/dist/editor.d.cts +0 -26
- package/dist/element.cjs +0 -70530
- package/dist/element.d.cts +0 -62
- package/dist/highlight.cjs +0 -852
- package/dist/highlight.d.cts +0 -49
- package/dist/index.cjs +0 -70491
- package/dist/index.d.cts +0 -160
- package/dist/pert.cjs +0 -325
- package/dist/pert.d.cts +0 -559
- package/dist/themes-1-CuKpeH.d.cts +0 -908
- package/src/advanced.ts +0 -873
- package/src/arc/parser.ts +0 -15
- package/src/arc/renderer.ts +0 -633
- package/src/auto/index.ts +0 -621
- package/src/auto/shared.ts +0 -370
- package/src/auto/styles.ts +0 -73
- package/src/block/layout.ts +0 -198
- package/src/block/parser.ts +0 -427
- package/src/block/renderer.ts +0 -484
- package/src/block/types.ts +0 -67
- package/src/boxes-and-lines/collapse.ts +0 -96
- package/src/boxes-and-lines/focus.ts +0 -257
- package/src/boxes-and-lines/label-placement.ts +0 -339
- package/src/boxes-and-lines/layout-grouped.ts +0 -912
- package/src/boxes-and-lines/layout-layered.ts +0 -722
- package/src/boxes-and-lines/layout-search.ts +0 -1678
- package/src/boxes-and-lines/layout.ts +0 -398
- package/src/boxes-and-lines/parser.ts +0 -1181
- package/src/boxes-and-lines/renderer.ts +0 -1465
- package/src/boxes-and-lines/types.ts +0 -66
- package/src/c4/layout.ts +0 -2441
- package/src/c4/parser.ts +0 -1158
- package/src/c4/renderer.ts +0 -2008
- package/src/c4/types.ts +0 -89
- package/src/chart-type-registry.ts +0 -529
- package/src/chart-types.ts +0 -225
- package/src/chart.ts +0 -685
- package/src/charts-d3/bar.ts +0 -338
- package/src/charts-d3/chord.ts +0 -140
- package/src/charts-d3/function.ts +0 -147
- package/src/charts-d3/funnel.ts +0 -104
- package/src/charts-d3/heatmap.ts +0 -145
- package/src/charts-d3/index.ts +0 -337
- package/src/charts-d3/interactions.ts +0 -477
- package/src/charts-d3/line.ts +0 -344
- package/src/charts-d3/mount.ts +0 -151
- package/src/charts-d3/pie.ts +0 -117
- package/src/charts-d3/polar.ts +0 -89
- package/src/charts-d3/radar.ts +0 -0
- package/src/charts-d3/sankey.ts +0 -0
- package/src/charts-d3/scatter.ts +0 -185
- package/src/charts-d3/shared.ts +0 -208
- package/src/class/layout.ts +0 -326
- package/src/class/parser.ts +0 -635
- package/src/class/renderer.ts +0 -793
- package/src/class/types.ts +0 -58
- package/src/cli-banner.ts +0 -106
- package/src/cli.ts +0 -1080
- package/src/colors-diagnostics.ts +0 -35
- package/src/colors.ts +0 -379
- package/src/completion-types.ts +0 -27
- package/src/completion.ts +0 -2668
- package/src/cycle/layout.ts +0 -1026
- package/src/cycle/parser.ts +0 -387
- package/src/cycle/renderer.ts +0 -653
- package/src/cycle/types.ts +0 -101
- package/src/d3.ts +0 -1434
- package/src/data-chart-parser.ts +0 -1007
- package/src/dgmo-router.ts +0 -296
- package/src/diagnostics-registry.ts +0 -108
- package/src/diagnostics.ts +0 -0
- package/src/dimensions.ts +0 -20
- package/src/directives-registry.ts +0 -396
- package/src/editor/dgmo.grammar +0 -76
- package/src/editor/dgmo.grammar.d.ts +0 -2
- package/src/editor/dgmo.grammar.js +0 -18
- package/src/editor/dgmo.grammar.terms.d.ts +0 -5
- package/src/editor/dgmo.grammar.terms.js +0 -35
- package/src/editor/highlight-api.ts +0 -596
- package/src/editor/highlight.ts +0 -36
- package/src/editor/index.ts +0 -27
- package/src/editor/keywords.ts +0 -128
- package/src/editor/tokens.ts +0 -30
- package/src/element/index.ts +0 -432
- package/src/embed/css.ts +0 -312
- package/src/embed/escape.ts +0 -15
- package/src/embed/index.ts +0 -280
- package/src/er/classify.ts +0 -228
- package/src/er/layout.ts +0 -530
- package/src/er/parser.ts +0 -750
- package/src/er/renderer.ts +0 -725
- package/src/er/types.ts +0 -52
- package/src/error-card.ts +0 -269
- package/src/event-line/diagnostics.ts +0 -117
- package/src/event-line/parser.ts +0 -643
- package/src/event-line/renderer.ts +0 -1742
- package/src/event-line/types.ts +0 -74
- package/src/fonts.ts +0 -3
- package/src/gantt/calculator.ts +0 -979
- package/src/gantt/parser.ts +0 -1641
- package/src/gantt/renderer.ts +0 -3787
- package/src/gantt/resolver.ts +0 -172
- package/src/gantt/types.ts +0 -206
- package/src/graph/diagnostics.ts +0 -64
- package/src/graph/edge-spline.ts +0 -29
- package/src/graph/flowchart-parser.ts +0 -759
- package/src/graph/flowchart-renderer.ts +0 -817
- package/src/graph/layout.ts +0 -472
- package/src/graph/notes.ts +0 -21
- package/src/graph/state-collapse.ts +0 -78
- package/src/graph/state-parser.ts +0 -574
- package/src/graph/state-renderer.ts +0 -653
- package/src/graph/types.ts +0 -65
- package/src/index.ts +0 -261
- package/src/infra/compute.ts +0 -1385
- package/src/infra/layout.ts +0 -888
- package/src/infra/parser.ts +0 -1234
- package/src/infra/renderer.ts +0 -2534
- package/src/infra/roles.ts +0 -75
- package/src/infra/types.ts +0 -216
- package/src/infra/validation.ts +0 -201
- package/src/journey-map/layout.ts +0 -490
- package/src/journey-map/parser.ts +0 -557
- package/src/journey-map/renderer.ts +0 -1580
- package/src/journey-map/types.ts +0 -47
- package/src/kanban/mutations.ts +0 -175
- package/src/kanban/parser.ts +0 -509
- package/src/kanban/renderer.ts +0 -1449
- package/src/kanban/types.ts +0 -39
- package/src/label-layout.ts +0 -368
- package/src/map/colorize.ts +0 -54
- package/src/map/completion.ts +0 -316
- package/src/map/context-labels.ts +0 -609
- package/src/map/data/PROVENANCE.json +0 -1
- package/src/map/data/README.md +0 -40
- package/src/map/data/airport-collisions.json +0 -1
- package/src/map/data/airports.json +0 -1
- package/src/map/data/gazetteer.json +0 -1
- package/src/map/data/lakes.json +0 -1
- package/src/map/data/mountain-ranges.json +0 -1
- package/src/map/data/na-lakes.json +0 -1
- package/src/map/data/na-land.json +0 -1
- package/src/map/data/region-names.json +0 -1
- package/src/map/data/rivers.json +0 -1
- package/src/map/data/types.ts +0 -121
- package/src/map/data/us-states.json +0 -1
- package/src/map/data/water-bodies.json +0 -1
- package/src/map/data/world-coarse.json +0 -1
- package/src/map/data/world-detail.json +0 -1
- package/src/map/diagnostics.ts +0 -134
- package/src/map/dimensions.ts +0 -150
- package/src/map/geo-query.ts +0 -295
- package/src/map/geo.ts +0 -438
- package/src/map/invert.ts +0 -111
- package/src/map/layout.ts +0 -5069
- package/src/map/legend-band.ts +0 -127
- package/src/map/load-data.ts +0 -186
- package/src/map/parser.ts +0 -783
- package/src/map/renderer.ts +0 -1445
- package/src/map/resolved-types.ts +0 -160
- package/src/map/resolver.ts +0 -1146
- package/src/map/types.ts +0 -194
- package/src/mindmap/collapse.ts +0 -67
- package/src/mindmap/layout.ts +0 -649
- package/src/mindmap/parser.ts +0 -430
- package/src/mindmap/renderer.ts +0 -637
- package/src/mindmap/text-wrap.ts +0 -218
- package/src/mindmap/types.ts +0 -56
- package/src/org/collapse.ts +0 -151
- package/src/org/layout.ts +0 -1262
- package/src/org/parser.ts +0 -519
- package/src/org/renderer.ts +0 -866
- package/src/org/resolver.ts +0 -636
- package/src/palettes/atlas.ts +0 -77
- package/src/palettes/blueprint.ts +0 -73
- package/src/palettes/catppuccin.ts +0 -84
- package/src/palettes/color-utils.ts +0 -443
- package/src/palettes/index.ts +0 -67
- package/src/palettes/nord.ts +0 -67
- package/src/palettes/registry.ts +0 -114
- package/src/palettes/slate.ts +0 -73
- package/src/palettes/tidewater.ts +0 -73
- package/src/palettes/tokyo-night.ts +0 -86
- package/src/palettes/types.ts +0 -88
- package/src/pert/analyzer.ts +0 -1183
- package/src/pert/diagnostics.ts +0 -110
- package/src/pert/index.ts +0 -43
- package/src/pert/internal.ts +0 -252
- package/src/pert/layout.ts +0 -971
- package/src/pert/monte-carlo.ts +0 -446
- package/src/pert/parser.ts +0 -1606
- package/src/pert/renderer.ts +0 -4009
- package/src/pert/share-normalize.ts +0 -62
- package/src/pert/types.ts +0 -604
- package/src/pyramid/parser.ts +0 -185
- package/src/pyramid/renderer.ts +0 -768
- package/src/pyramid/types.ts +0 -28
- package/src/quadrant/parser.ts +0 -18
- package/src/quadrant/renderer.ts +0 -638
- package/src/raci/diagnostics.ts +0 -213
- package/src/raci/index.ts +0 -23
- package/src/raci/mutations.ts +0 -321
- package/src/raci/parser.ts +0 -699
- package/src/raci/renderer.ts +0 -1627
- package/src/raci/types.ts +0 -82
- package/src/raci/variants.ts +0 -320
- package/src/render.ts +0 -268
- package/src/ring/parser.ts +0 -212
- package/src/ring/renderer.ts +0 -490
- package/src/ring/types.ts +0 -27
- package/src/sequence/collapse.ts +0 -174
- package/src/sequence/parser.ts +0 -1596
- package/src/sequence/participant-inference.ts +0 -152
- package/src/sequence/renderer.ts +0 -3168
- package/src/sequence/tag-resolution.ts +0 -164
- package/src/sharing.ts +0 -211
- package/src/sitemap/collapse.ts +0 -100
- package/src/sitemap/layout.ts +0 -925
- package/src/sitemap/parser.ts +0 -755
- package/src/sitemap/renderer.ts +0 -828
- package/src/sitemap/types.ts +0 -42
- package/src/slope/parser.ts +0 -18
- package/src/slope/renderer.ts +0 -378
- package/src/swimlane/diagnostics.ts +0 -94
- package/src/swimlane/layout.ts +0 -597
- package/src/swimlane/parser.ts +0 -613
- package/src/swimlane/renderer.ts +0 -681
- package/src/swimlane/types.ts +0 -151
- package/src/tech-radar/interactive.ts +0 -1129
- package/src/tech-radar/layout.ts +0 -197
- package/src/tech-radar/parser.ts +0 -436
- package/src/tech-radar/renderer.ts +0 -1239
- package/src/tech-radar/shared.ts +0 -151
- package/src/tech-radar/types.ts +0 -86
- package/src/themes.ts +0 -22
- package/src/timeline/parser.ts +0 -472
- package/src/timeline/renderer.ts +0 -3024
- package/src/timeline/types.ts +0 -33
- package/src/timeline/viz-parser.ts +0 -21
- package/src/treemap/diagnostics.ts +0 -62
- package/src/treemap/layout-radial.ts +0 -233
- package/src/treemap/layout.ts +0 -189
- package/src/treemap/parser.ts +0 -463
- package/src/treemap/renderer-radial.ts +0 -438
- package/src/treemap/renderer.ts +0 -572
- package/src/treemap/treemap-shared.ts +0 -309
- package/src/treemap/types.ts +0 -60
- package/src/utils/arrow-markers.ts +0 -51
- package/src/utils/arrows-diagnostics.ts +0 -62
- package/src/utils/arrows.ts +0 -227
- package/src/utils/brand.ts +0 -61
- package/src/utils/card.ts +0 -183
- package/src/utils/collapse-engine/tree-edges.ts +0 -115
- package/src/utils/collapse-engine/tree.ts +0 -117
- package/src/utils/d3-helpers.ts +0 -219
- package/src/utils/d3-types.ts +0 -9
- package/src/utils/description-helpers.ts +0 -38
- package/src/utils/duration.ts +0 -312
- package/src/utils/export-container.ts +0 -41
- package/src/utils/expr-eval.ts +0 -27
- package/src/utils/fit-canvas.ts +0 -64
- package/src/utils/hover-styles.ts +0 -673
- package/src/utils/inline-markdown.ts +0 -96
- package/src/utils/legend-constants.ts +0 -48
- package/src/utils/legend-d3.ts +0 -618
- package/src/utils/legend-integration.ts +0 -107
- package/src/utils/legend-layout.ts +0 -776
- package/src/utils/legend-svg.ts +0 -214
- package/src/utils/legend-types.ts +0 -272
- package/src/utils/name-normalize.ts +0 -163
- package/src/utils/note-box/constants.ts +0 -25
- package/src/utils/note-box/index.ts +0 -11
- package/src/utils/note-box/metrics.ts +0 -90
- package/src/utils/note-box/svg.ts +0 -331
- package/src/utils/notes/bounds.ts +0 -30
- package/src/utils/notes/build.ts +0 -131
- package/src/utils/notes/index.ts +0 -18
- package/src/utils/notes/model.ts +0 -19
- package/src/utils/notes/parse.ts +0 -131
- package/src/utils/notes/place.ts +0 -177
- package/src/utils/notes/resolve.ts +0 -88
- package/src/utils/number-format.ts +0 -36
- package/src/utils/parsing.ts +0 -953
- package/src/utils/reserved-key-registry.ts +0 -239
- package/src/utils/safe-href.ts +0 -38
- package/src/utils/scaling.ts +0 -97
- package/src/utils/svg-embed.ts +0 -251
- package/src/utils/tag-groups.ts +0 -607
- package/src/utils/text-measure.ts +0 -122
- package/src/utils/time-ticks.ts +0 -253
- package/src/utils/title-constants.ts +0 -24
- package/src/utils/visual-conventions.ts +0 -61
- package/src/utils/wrapped-desc.ts +0 -87
- package/src/venn/parser.ts +0 -18
- package/src/venn/renderer.ts +0 -1047
- package/src/version-control/diagnostics.ts +0 -67
- package/src/version-control/parser.ts +0 -544
- package/src/version-control/renderer.ts +0 -724
- package/src/version-control/types.ts +0 -100
- package/src/visualizations/parse.ts +0 -1560
- package/src/visualizations/types.ts +0 -262
- package/src/wireframe/layout.ts +0 -479
- package/src/wireframe/parser.ts +0 -1114
- package/src/wireframe/renderer.ts +0 -1318
- package/src/wireframe/types.ts +0 -110
- package/src/wordcloud/parser.ts +0 -18
- package/src/wordcloud/renderer.ts +0 -357
|
@@ -1,557 +0,0 @@
|
|
|
1
|
-
import type { PaletteColors } from '../palettes';
|
|
2
|
-
import { resolveColorWithDiagnostic } from '../colors';
|
|
3
|
-
import {
|
|
4
|
-
formatDgmoError,
|
|
5
|
-
makeDgmoError,
|
|
6
|
-
makeFail,
|
|
7
|
-
suggest,
|
|
8
|
-
} from '../diagnostics';
|
|
9
|
-
import {
|
|
10
|
-
JOURNEY_MAP_REGISTRY,
|
|
11
|
-
withTagAliases,
|
|
12
|
-
} from '../utils/reserved-key-registry';
|
|
13
|
-
import {
|
|
14
|
-
splitNameAndMeta,
|
|
15
|
-
warnUnknownMetaKeys,
|
|
16
|
-
peelTrailingColorName,
|
|
17
|
-
} from '../utils/parsing';
|
|
18
|
-
import {
|
|
19
|
-
matchTagBlockHeading,
|
|
20
|
-
stripDefaultModifier,
|
|
21
|
-
validateTagGroupNames,
|
|
22
|
-
finalizeAutoTagColors,
|
|
23
|
-
AUTO_TAG_COLOR_SENTINEL,
|
|
24
|
-
tagAttrKey,
|
|
25
|
-
} from '../utils/tag-groups';
|
|
26
|
-
import {
|
|
27
|
-
measureIndent,
|
|
28
|
-
extractColor,
|
|
29
|
-
parseFirstLine,
|
|
30
|
-
OPTION_NOCOLON_RE,
|
|
31
|
-
} from '../utils/parsing';
|
|
32
|
-
import { tryStripDescriptionKeyword } from '../utils/description-helpers';
|
|
33
|
-
import type {
|
|
34
|
-
ParsedJourneyMap,
|
|
35
|
-
JourneyMapPhase,
|
|
36
|
-
JourneyMapStep,
|
|
37
|
-
JourneyMapPersona,
|
|
38
|
-
JourneyMapAnnotation,
|
|
39
|
-
} from './types';
|
|
40
|
-
import type { TagGroup } from '../utils/tag-groups';
|
|
41
|
-
import type { Writable } from '../utils/brand';
|
|
42
|
-
|
|
43
|
-
// ============================================================
|
|
44
|
-
// Regex patterns
|
|
45
|
-
// ============================================================
|
|
46
|
-
|
|
47
|
-
const PHASE_RE = /^\[(.+?)\]$/;
|
|
48
|
-
const ANNOTATION_RE = /^(pain|opportunity|thought)\s*:\s*(.+)$/i;
|
|
49
|
-
|
|
50
|
-
/** Known journey-map options (key-value). */
|
|
51
|
-
const KNOWN_OPTIONS = new Set(['active-tag']);
|
|
52
|
-
/** Known journey-map boolean options (bare keyword = on). */
|
|
53
|
-
const KNOWN_BOOLEANS = new Set(['solid-fill', 'no-title']);
|
|
54
|
-
const REMOVED_BOOLEANS: Record<string, string> = {
|
|
55
|
-
'no-legend':
|
|
56
|
-
'"no-legend" has been removed — remove tag groups to hide the legend.',
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// ============================================================
|
|
60
|
-
// Parser
|
|
61
|
-
// ============================================================
|
|
62
|
-
|
|
63
|
-
export function parseJourneyMap(
|
|
64
|
-
content: string,
|
|
65
|
-
palette?: PaletteColors
|
|
66
|
-
): ParsedJourneyMap {
|
|
67
|
-
const options: Record<string, string> = {};
|
|
68
|
-
const result: Writable<ParsedJourneyMap> = {
|
|
69
|
-
type: 'journey-map',
|
|
70
|
-
phases: [],
|
|
71
|
-
steps: [],
|
|
72
|
-
tagGroups: [],
|
|
73
|
-
options,
|
|
74
|
-
diagnostics: [],
|
|
75
|
-
error: null,
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const fail = makeFail(result);
|
|
79
|
-
|
|
80
|
-
const warn = (line: number, message: string): void => {
|
|
81
|
-
result.diagnostics.push(makeDgmoError(line, message, 'warning'));
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
if (!content?.trim()) {
|
|
85
|
-
return fail(0, 'No content provided');
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const lines = content.split('\n');
|
|
89
|
-
let contentStarted = false;
|
|
90
|
-
let currentTagGroup: Writable<TagGroup> | null = null;
|
|
91
|
-
let inPersona = false;
|
|
92
|
-
let currentPhase: Writable<JourneyMapPhase> | null = null;
|
|
93
|
-
let currentStep: Writable<JourneyMapStep> | null = null;
|
|
94
|
-
let currentPersona: Writable<JourneyMapPersona> | null = null;
|
|
95
|
-
let stepBaseIndent = 0;
|
|
96
|
-
let phaseCounter = 0;
|
|
97
|
-
let stepCounter = 0;
|
|
98
|
-
let hasPhases = false;
|
|
99
|
-
|
|
100
|
-
const aliasMap = new Map<string, string>();
|
|
101
|
-
const tagValueSets = new Map<string, Set<string>>();
|
|
102
|
-
|
|
103
|
-
for (let i = 0; i < lines.length; i++) {
|
|
104
|
-
// In-bounds by loop guard.
|
|
105
|
-
const line = lines[i]!;
|
|
106
|
-
const lineNumber = i + 1;
|
|
107
|
-
const trimmed = line.trim();
|
|
108
|
-
|
|
109
|
-
// Skip empty lines
|
|
110
|
-
if (!trimmed) {
|
|
111
|
-
if (currentTagGroup) currentTagGroup = null;
|
|
112
|
-
if (inPersona) inPersona = false;
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Skip comments
|
|
117
|
-
if (trimmed.startsWith('//')) continue;
|
|
118
|
-
|
|
119
|
-
const indent = measureIndent(line);
|
|
120
|
-
|
|
121
|
-
// --- Header phase ---
|
|
122
|
-
|
|
123
|
-
// Extract chart type + title from first line
|
|
124
|
-
if (!contentStarted && !currentTagGroup && !inPersona) {
|
|
125
|
-
const firstLine = parseFirstLine(trimmed);
|
|
126
|
-
if (firstLine) {
|
|
127
|
-
if (firstLine.chartType !== 'journey-map') {
|
|
128
|
-
const allTypes = ['journey-map', 'kanban', 'sequence', 'flowchart'];
|
|
129
|
-
let msg = `Expected chart type "journey-map", got "${firstLine.chartType}"`;
|
|
130
|
-
const hint = suggest(firstLine.chartType, allTypes);
|
|
131
|
-
if (hint) msg += `. ${hint}`;
|
|
132
|
-
return fail(lineNumber, msg);
|
|
133
|
-
}
|
|
134
|
-
if (firstLine.title) {
|
|
135
|
-
result.title = firstLine.title;
|
|
136
|
-
result.titleLineNumber = lineNumber;
|
|
137
|
-
}
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Persona keyword
|
|
143
|
-
if (!contentStarted && !currentTagGroup && indent === 0) {
|
|
144
|
-
const personaMatch = trimmed.match(/^persona\s+(.+)$/i);
|
|
145
|
-
if (personaMatch) {
|
|
146
|
-
// Capture group 1 present by regex shape.
|
|
147
|
-
const afterKeyword = personaMatch[1]!.trim();
|
|
148
|
-
let personaName: string;
|
|
149
|
-
let personaColor: string | undefined;
|
|
150
|
-
|
|
151
|
-
// Same-line form (pipes removed in 0.18.0). Two ways to set color:
|
|
152
|
-
// 1. explicit `persona <name> color: <token>` (long form)
|
|
153
|
-
// 2. universal §1.5 trailing-token color (`persona <name> green`);
|
|
154
|
-
// capitalize the word (`Green`) to keep it as literal name text.
|
|
155
|
-
const colorMatch = afterKeyword.match(/^(.+?)\s+color:\s*(\S+)$/i);
|
|
156
|
-
if (colorMatch) {
|
|
157
|
-
personaName = colorMatch[1]!.trim();
|
|
158
|
-
personaColor =
|
|
159
|
-
resolveColorWithDiagnostic(
|
|
160
|
-
colorMatch[2]!,
|
|
161
|
-
lineNumber,
|
|
162
|
-
result.diagnostics,
|
|
163
|
-
palette
|
|
164
|
-
) ?? undefined;
|
|
165
|
-
} else {
|
|
166
|
-
const { label, colorName } = peelTrailingColorName(afterKeyword);
|
|
167
|
-
if (colorName) {
|
|
168
|
-
personaName = label;
|
|
169
|
-
personaColor =
|
|
170
|
-
resolveColorWithDiagnostic(
|
|
171
|
-
colorName,
|
|
172
|
-
lineNumber,
|
|
173
|
-
result.diagnostics,
|
|
174
|
-
palette
|
|
175
|
-
) ?? undefined;
|
|
176
|
-
} else {
|
|
177
|
-
personaName = afterKeyword;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (!personaName) {
|
|
182
|
-
return fail(lineNumber, 'persona requires a name');
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
currentPersona = {
|
|
186
|
-
name: personaName,
|
|
187
|
-
...(personaColor !== undefined && { color: personaColor }),
|
|
188
|
-
lineNumber,
|
|
189
|
-
};
|
|
190
|
-
result.persona = currentPersona;
|
|
191
|
-
inPersona = true;
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
if (/^persona\s*$/i.test(trimmed)) {
|
|
195
|
-
return fail(lineNumber, 'persona requires a name');
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Persona description (indented lines while inPersona)
|
|
200
|
-
if (inPersona && indent > 0) {
|
|
201
|
-
if (currentPersona) {
|
|
202
|
-
currentPersona.description = currentPersona.description
|
|
203
|
-
? currentPersona.description + '\n' + trimmed
|
|
204
|
-
: trimmed;
|
|
205
|
-
}
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// End persona on non-indented line
|
|
210
|
-
if (inPersona && indent === 0) {
|
|
211
|
-
inPersona = false;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Tag group heading
|
|
215
|
-
if (!contentStarted) {
|
|
216
|
-
const tagBlockMatch = matchTagBlockHeading(trimmed);
|
|
217
|
-
if (tagBlockMatch) {
|
|
218
|
-
currentTagGroup = {
|
|
219
|
-
name: tagBlockMatch.name,
|
|
220
|
-
...(tagBlockMatch.alias !== undefined && {
|
|
221
|
-
alias: tagBlockMatch.alias,
|
|
222
|
-
}),
|
|
223
|
-
entries: [],
|
|
224
|
-
lineNumber,
|
|
225
|
-
};
|
|
226
|
-
if (tagBlockMatch.alias) {
|
|
227
|
-
aliasMap.set(
|
|
228
|
-
tagBlockMatch.alias.toLowerCase(),
|
|
229
|
-
tagAttrKey(tagBlockMatch.name)
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
aliasMap.set(
|
|
233
|
-
tagAttrKey(tagBlockMatch.name),
|
|
234
|
-
tagAttrKey(tagBlockMatch.name)
|
|
235
|
-
);
|
|
236
|
-
result.tagGroups.push(currentTagGroup);
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Tag group entries (indented under tag heading)
|
|
242
|
-
if (currentTagGroup && !contentStarted) {
|
|
243
|
-
if (indent > 0) {
|
|
244
|
-
const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
|
|
245
|
-
const { label, color } = extractColor(
|
|
246
|
-
cleanEntry,
|
|
247
|
-
palette,
|
|
248
|
-
result.diagnostics,
|
|
249
|
-
lineNumber
|
|
250
|
-
);
|
|
251
|
-
// Bare value (no explicit color) → keep it; finalized below.
|
|
252
|
-
if (isDefault) {
|
|
253
|
-
currentTagGroup.defaultValue = label;
|
|
254
|
-
} else if (currentTagGroup.entries.length === 0) {
|
|
255
|
-
currentTagGroup.defaultValue = label;
|
|
256
|
-
}
|
|
257
|
-
currentTagGroup.entries.push({
|
|
258
|
-
value: label,
|
|
259
|
-
color: color ?? AUTO_TAG_COLOR_SENTINEL,
|
|
260
|
-
lineNumber,
|
|
261
|
-
});
|
|
262
|
-
continue;
|
|
263
|
-
}
|
|
264
|
-
currentTagGroup = null;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Generic header options
|
|
268
|
-
if (!contentStarted && !currentTagGroup && indent === 0) {
|
|
269
|
-
const optMatch = trimmed.match(OPTION_NOCOLON_RE);
|
|
270
|
-
if (optMatch && !PHASE_RE.test(trimmed)) {
|
|
271
|
-
// Capture groups 1 and 2 present by regex shape.
|
|
272
|
-
const key = optMatch[1]!.trim().toLowerCase();
|
|
273
|
-
if (KNOWN_OPTIONS.has(key)) {
|
|
274
|
-
options[key] = optMatch[2]!.trim();
|
|
275
|
-
continue;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
const removedMsg = REMOVED_BOOLEANS[trimmed.toLowerCase()];
|
|
279
|
-
if (removedMsg && !PHASE_RE.test(trimmed)) {
|
|
280
|
-
warn(lineNumber, removedMsg);
|
|
281
|
-
continue;
|
|
282
|
-
}
|
|
283
|
-
if (
|
|
284
|
-
KNOWN_BOOLEANS.has(trimmed.toLowerCase()) &&
|
|
285
|
-
!PHASE_RE.test(trimmed)
|
|
286
|
-
) {
|
|
287
|
-
options[trimmed.toLowerCase()] = 'on';
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// --- Content phase detection ---
|
|
293
|
-
|
|
294
|
-
// Phase header at indent 0
|
|
295
|
-
const phaseMatch = indent === 0 ? trimmed.match(PHASE_RE) : null;
|
|
296
|
-
if (phaseMatch) {
|
|
297
|
-
contentStarted = true;
|
|
298
|
-
currentTagGroup = null;
|
|
299
|
-
inPersona = false;
|
|
300
|
-
hasPhases = true;
|
|
301
|
-
|
|
302
|
-
// Finalize previous step
|
|
303
|
-
if (currentStep) {
|
|
304
|
-
currentStep.endLineNumber = lineNumber - 1;
|
|
305
|
-
}
|
|
306
|
-
currentStep = null;
|
|
307
|
-
|
|
308
|
-
phaseCounter++;
|
|
309
|
-
currentPhase = {
|
|
310
|
-
id: `phase-${phaseCounter}`,
|
|
311
|
-
// Capture group 1 present by regex shape.
|
|
312
|
-
name: phaseMatch[1]!.trim(),
|
|
313
|
-
steps: [],
|
|
314
|
-
lineNumber,
|
|
315
|
-
};
|
|
316
|
-
result.phases.push(currentPhase);
|
|
317
|
-
continue;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// Flat mode: indent-0 line that is not a phase/keyword — check if step
|
|
321
|
-
if (indent === 0 && !contentStarted) {
|
|
322
|
-
// Check if this looks like a step (contains pipe or is a bare step name)
|
|
323
|
-
if (
|
|
324
|
-
trimmed.includes('|') ||
|
|
325
|
-
(!KNOWN_OPTIONS.has(trimmed.toLowerCase()) &&
|
|
326
|
-
!KNOWN_BOOLEANS.has(trimmed.toLowerCase()))
|
|
327
|
-
) {
|
|
328
|
-
contentStarted = true;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// --- Content phase ---
|
|
333
|
-
|
|
334
|
-
if (!contentStarted) continue;
|
|
335
|
-
|
|
336
|
-
// Mixed mode check: indent-0 non-phase line when phases exist
|
|
337
|
-
if (indent === 0 && hasPhases && !phaseMatch) {
|
|
338
|
-
// Stray line between phases
|
|
339
|
-
if (trimmed.includes('|') || !PHASE_RE.test(trimmed)) {
|
|
340
|
-
warn(
|
|
341
|
-
lineNumber,
|
|
342
|
-
`Step "${trimmed}" sits outside any phase and is ignored — indent it under a '[Phase]' header (per §22).`
|
|
343
|
-
);
|
|
344
|
-
continue;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// Annotations/description on current step (deeper indent)
|
|
349
|
-
if (currentStep && indent > stepBaseIndent) {
|
|
350
|
-
// Check for annotation keywords
|
|
351
|
-
const annoMatch = trimmed.match(ANNOTATION_RE);
|
|
352
|
-
if (annoMatch) {
|
|
353
|
-
// Capture groups 1 and 2 present by regex shape.
|
|
354
|
-
currentStep.annotations.push({
|
|
355
|
-
type: annoMatch[1]!.toLowerCase() as JourneyMapAnnotation['type'],
|
|
356
|
-
text: annoMatch[2]!.trim(),
|
|
357
|
-
});
|
|
358
|
-
currentStep.endLineNumber = lineNumber;
|
|
359
|
-
continue;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// Check for description keyword
|
|
363
|
-
const descResult = tryStripDescriptionKeyword(trimmed);
|
|
364
|
-
if (descResult.isKeyword) {
|
|
365
|
-
currentStep.description = descResult.text;
|
|
366
|
-
currentStep.endLineNumber = lineNumber;
|
|
367
|
-
continue;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// Unknown deeper-indented line — treat as detail, skip silently
|
|
371
|
-
currentStep.endLineNumber = lineNumber;
|
|
372
|
-
continue;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// Step line (indented under phase, or indent-0 in flat mode)
|
|
376
|
-
if ((currentPhase && indent > 0) || (!hasPhases && indent === 0)) {
|
|
377
|
-
// Finalize previous step
|
|
378
|
-
if (currentStep) {
|
|
379
|
-
currentStep.endLineNumber = lineNumber - 1;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
stepCounter++;
|
|
383
|
-
const step = parseStepLine(
|
|
384
|
-
trimmed,
|
|
385
|
-
lineNumber,
|
|
386
|
-
stepCounter,
|
|
387
|
-
aliasMap,
|
|
388
|
-
warn,
|
|
389
|
-
result.diagnostics
|
|
390
|
-
);
|
|
391
|
-
stepBaseIndent = indent;
|
|
392
|
-
currentStep = step;
|
|
393
|
-
|
|
394
|
-
if (currentPhase) {
|
|
395
|
-
currentPhase.steps.push(step);
|
|
396
|
-
} else {
|
|
397
|
-
result.steps.push(step);
|
|
398
|
-
}
|
|
399
|
-
continue;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// Unrecognized line
|
|
403
|
-
if (indent > 0 && !currentPhase && hasPhases) {
|
|
404
|
-
warn(
|
|
405
|
-
lineNumber,
|
|
406
|
-
`Indented line outside any phase — add a '[Phase]' header above it, or unindent it to a top-level step. (§22)`
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Finalize last step
|
|
412
|
-
if (currentStep) {
|
|
413
|
-
currentStep.endLineNumber = lines.length;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// --- Post-parse validation ---
|
|
417
|
-
|
|
418
|
-
// Build tag value sets
|
|
419
|
-
for (const group of result.tagGroups) {
|
|
420
|
-
const values = new Set(group.entries.map((e) => e.value.toLowerCase()));
|
|
421
|
-
tagValueSets.set(tagAttrKey(group.name), values);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Validate tag values on all steps
|
|
425
|
-
const allSteps = hasPhases
|
|
426
|
-
? result.phases.flatMap((p) => p.steps)
|
|
427
|
-
: result.steps;
|
|
428
|
-
|
|
429
|
-
for (const step of allSteps) {
|
|
430
|
-
for (const [tagKey, tagValue] of Object.entries(step.tags)) {
|
|
431
|
-
const groupKey =
|
|
432
|
-
aliasMap.get(tagKey.toLowerCase()) ?? tagKey.toLowerCase();
|
|
433
|
-
const validValues = tagValueSets.get(groupKey);
|
|
434
|
-
if (validValues && !validValues.has(tagValue.toLowerCase())) {
|
|
435
|
-
const entries = result.tagGroups
|
|
436
|
-
.find((g) => g.name.toLowerCase() === groupKey)
|
|
437
|
-
?.entries.map((e) => e.value);
|
|
438
|
-
let msg = `Unknown tag value "${tagValue}" for group "${groupKey}"`;
|
|
439
|
-
if (entries) {
|
|
440
|
-
const hint = suggest(tagValue, entries);
|
|
441
|
-
if (hint) msg += `. ${hint}`;
|
|
442
|
-
}
|
|
443
|
-
warn(step.lineNumber, msg);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Hint for missing scores
|
|
448
|
-
if (step.score === undefined) {
|
|
449
|
-
warn(
|
|
450
|
-
step.lineNumber,
|
|
451
|
-
`Step "${step.title}" has no score — it will not appear on the emotion curve`
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// No content check
|
|
457
|
-
if (
|
|
458
|
-
result.phases.length === 0 &&
|
|
459
|
-
result.steps.length === 0 &&
|
|
460
|
-
!result.error
|
|
461
|
-
) {
|
|
462
|
-
return fail(1, 'No phases or steps found');
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// Assign palette colors to bare (colorless) tag values.
|
|
466
|
-
finalizeAutoTagColors(result.tagGroups as Writable<TagGroup>[], palette);
|
|
467
|
-
|
|
468
|
-
validateTagGroupNames(result.tagGroups, warn, (line, msg) => {
|
|
469
|
-
const diag = makeDgmoError(line, msg);
|
|
470
|
-
result.diagnostics.push(diag);
|
|
471
|
-
if (!result.error) result.error = formatDgmoError(diag);
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
return result;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// ============================================================
|
|
478
|
-
// Step line parser
|
|
479
|
-
// ============================================================
|
|
480
|
-
|
|
481
|
-
function parseStepLine(
|
|
482
|
-
trimmed: string,
|
|
483
|
-
lineNumber: number,
|
|
484
|
-
counter: number,
|
|
485
|
-
aliasMap: Map<string, string>,
|
|
486
|
-
warn: (line: number, message: string) => void,
|
|
487
|
-
diagnostics?: import('../diagnostics').DgmoError[]
|
|
488
|
-
): Writable<JourneyMapStep> {
|
|
489
|
-
let score: number | undefined;
|
|
490
|
-
let emotionLabel: string | undefined;
|
|
491
|
-
const tags: Record<string, string> = {};
|
|
492
|
-
|
|
493
|
-
// §1.4 unified metadata grammar — same-line form; use splitNameAndMeta to
|
|
494
|
-
// extract `score:`, `emotion:`, and any other reserved/tag-alias keys.
|
|
495
|
-
const registry = withTagAliases(
|
|
496
|
-
JOURNEY_MAP_REGISTRY,
|
|
497
|
-
new Set(aliasMap.keys())
|
|
498
|
-
);
|
|
499
|
-
const split = splitNameAndMeta(
|
|
500
|
-
trimmed,
|
|
501
|
-
registry,
|
|
502
|
-
aliasMap,
|
|
503
|
-
undefined,
|
|
504
|
-
diagnostics,
|
|
505
|
-
lineNumber
|
|
506
|
-
);
|
|
507
|
-
warnUnknownMetaKeys(
|
|
508
|
-
split.meta,
|
|
509
|
-
registry,
|
|
510
|
-
(msg) => warn(lineNumber, msg),
|
|
511
|
-
split.name
|
|
512
|
-
);
|
|
513
|
-
const title = split.name;
|
|
514
|
-
const splitMeta = { ...split.meta };
|
|
515
|
-
// Extract reserved score / emotion into the dedicated fields.
|
|
516
|
-
if ('score' in splitMeta) {
|
|
517
|
-
const scoreVal = splitMeta['score'];
|
|
518
|
-
delete splitMeta['score'];
|
|
519
|
-
const parsed = parseInt(scoreVal, 10);
|
|
520
|
-
if (
|
|
521
|
-
!isNaN(parsed) &&
|
|
522
|
-
scoreVal === String(parsed) &&
|
|
523
|
-
parsed >= 1 &&
|
|
524
|
-
parsed <= 5
|
|
525
|
-
) {
|
|
526
|
-
score = parsed;
|
|
527
|
-
} else if (!isNaN(parsed) && (parsed < 1 || parsed > 5)) {
|
|
528
|
-
warn(lineNumber, `Score out of range: ${parsed} (must be 1-5)`);
|
|
529
|
-
} else {
|
|
530
|
-
warn(lineNumber, `Score must be an integer 1-5, got ${scoreVal}`);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
if ('emotion' in splitMeta) {
|
|
534
|
-
const emotionVal = splitMeta['emotion'];
|
|
535
|
-
delete splitMeta['emotion'];
|
|
536
|
-
if (emotionVal.includes(' ')) {
|
|
537
|
-
warn(
|
|
538
|
-
lineNumber,
|
|
539
|
-
`Emotion label must be a single word — got "${emotionVal}"`
|
|
540
|
-
);
|
|
541
|
-
} else {
|
|
542
|
-
emotionLabel = emotionVal;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
Object.assign(tags, splitMeta);
|
|
546
|
-
|
|
547
|
-
return {
|
|
548
|
-
id: `step-${counter}`,
|
|
549
|
-
title,
|
|
550
|
-
...(score !== undefined && { score }),
|
|
551
|
-
...(emotionLabel !== undefined && { emotionLabel }),
|
|
552
|
-
tags,
|
|
553
|
-
annotations: [],
|
|
554
|
-
lineNumber,
|
|
555
|
-
endLineNumber: lineNumber,
|
|
556
|
-
};
|
|
557
|
-
}
|