@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
package/src/kanban/parser.ts
DELETED
|
@@ -1,509 +0,0 @@
|
|
|
1
|
-
import type { PaletteColors } from '../palettes';
|
|
2
|
-
import {
|
|
3
|
-
formatDgmoError,
|
|
4
|
-
makeDgmoError,
|
|
5
|
-
makeFail,
|
|
6
|
-
suggest,
|
|
7
|
-
} from '../diagnostics';
|
|
8
|
-
import { resolveColorWithDiagnostic } from '../colors';
|
|
9
|
-
import {
|
|
10
|
-
KANBAN_REGISTRY,
|
|
11
|
-
withTagAliases,
|
|
12
|
-
} from '../utils/reserved-key-registry';
|
|
13
|
-
import {
|
|
14
|
-
matchTagBlockHeading,
|
|
15
|
-
stripDefaultModifier,
|
|
16
|
-
validateTagGroupNames,
|
|
17
|
-
finalizeAutoTagColors,
|
|
18
|
-
AUTO_TAG_COLOR_SENTINEL,
|
|
19
|
-
tagAttrKey,
|
|
20
|
-
} from '../utils/tag-groups';
|
|
21
|
-
import {
|
|
22
|
-
measureIndent,
|
|
23
|
-
extractColor,
|
|
24
|
-
splitNameAndMeta,
|
|
25
|
-
parseFirstLine,
|
|
26
|
-
OPTION_NOCOLON_RE,
|
|
27
|
-
warnUnknownMetaKeys,
|
|
28
|
-
} from '../utils/parsing';
|
|
29
|
-
import { normalizeName } from '../utils/name-normalize';
|
|
30
|
-
import type { Writable } from '../utils/brand';
|
|
31
|
-
import type {
|
|
32
|
-
ParsedKanban,
|
|
33
|
-
KanbanColumn,
|
|
34
|
-
KanbanCard,
|
|
35
|
-
KanbanTagGroup,
|
|
36
|
-
} from './types';
|
|
37
|
-
|
|
38
|
-
// ============================================================
|
|
39
|
-
// Regex patterns
|
|
40
|
-
// ============================================================
|
|
41
|
-
|
|
42
|
-
// [Column Name], [Column Name] color, [Column Name] as <alias>, [Column Name] wip: 3, etc.
|
|
43
|
-
// Universal §1.5 trailing-token: color is a bare token after `]`.
|
|
44
|
-
// Universal §1.4 same-line metadata also allowed after `]`.
|
|
45
|
-
// Captures: [1]=label [2]=trailing content (color / alias / metadata, parsed below)
|
|
46
|
-
const COLUMN_RE = /^\[(.+?)\]\s*(.*)$/;
|
|
47
|
-
const PALETTE_COLOR_WORD_RE =
|
|
48
|
-
/^(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\b/;
|
|
49
|
-
const AS_ALIAS_TOKEN_RE = /^as\s+([A-Za-z][A-Za-z0-9_]{0,11})\b/;
|
|
50
|
-
|
|
51
|
-
/** Known kanban options (key-value). */
|
|
52
|
-
// `lane-by <group>` sets the swimlane axis. NB: the keyword is `lane-by`, not
|
|
53
|
-
// `swimlane`, because `swimlane` is itself a chart type — `swimlane Team` would
|
|
54
|
-
// parse as a swimlane-chart declaration titled "Team".
|
|
55
|
-
const KNOWN_OPTIONS = new Set(['hide', 'active-tag', 'lane-by']);
|
|
56
|
-
/** Known kanban boolean options (bare keyword = on). */
|
|
57
|
-
const KNOWN_BOOLEANS = new Set<string>(['solid-fill', 'no-title']);
|
|
58
|
-
const REMOVED_BOOLEANS: Record<string, string> = {
|
|
59
|
-
'no-auto-color':
|
|
60
|
-
'"no-auto-color" was removed — colors are always auto-assigned from the palette; delete this line.',
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// ============================================================
|
|
64
|
-
// Parser
|
|
65
|
-
// ============================================================
|
|
66
|
-
|
|
67
|
-
export function parseKanban(
|
|
68
|
-
content: string,
|
|
69
|
-
palette?: PaletteColors
|
|
70
|
-
): ParsedKanban {
|
|
71
|
-
const options: Record<string, string> = {};
|
|
72
|
-
const result: Writable<ParsedKanban> = {
|
|
73
|
-
type: 'kanban',
|
|
74
|
-
columns: [],
|
|
75
|
-
tagGroups: [],
|
|
76
|
-
options,
|
|
77
|
-
diagnostics: [],
|
|
78
|
-
error: null,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const fail = makeFail(result);
|
|
82
|
-
|
|
83
|
-
const warn = (line: number, message: string): void => {
|
|
84
|
-
result.diagnostics.push(makeDgmoError(line, message, 'warning'));
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
if (!content?.trim()) {
|
|
88
|
-
return fail(0, 'No content provided');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const lines = content.split('\n');
|
|
92
|
-
let contentStarted = false;
|
|
93
|
-
let currentTagGroup: Writable<KanbanTagGroup> | null = null;
|
|
94
|
-
let currentColumn: Writable<KanbanColumn> | null = null;
|
|
95
|
-
let currentCard: Writable<KanbanCard> | null = null;
|
|
96
|
-
let cardBaseIndent = 0; // indent level of current card (for detail detection)
|
|
97
|
-
let columnCounter = 0;
|
|
98
|
-
let cardCounter = 0;
|
|
99
|
-
|
|
100
|
-
// metaAliasMap: tag-group metadata-key aliases (per A1 convention).
|
|
101
|
-
const metaAliasMap = new Map<string, string>();
|
|
102
|
-
// nameAliasMap: TD-18 entity-name aliases for kanban columns. Per C8.
|
|
103
|
-
const nameAliasMap = new Map<string, string>();
|
|
104
|
-
|
|
105
|
-
// Build a lookup for tag group entries (for validation)
|
|
106
|
-
const tagValueSets = new Map<string, Set<string>>();
|
|
107
|
-
|
|
108
|
-
for (let i = 0; i < lines.length; i++) {
|
|
109
|
-
// In-bounds by loop guard.
|
|
110
|
-
const line = lines[i]!;
|
|
111
|
-
const lineNumber = i + 1;
|
|
112
|
-
const trimmed = line.trim();
|
|
113
|
-
|
|
114
|
-
// Skip empty lines
|
|
115
|
-
if (!trimmed) {
|
|
116
|
-
if (currentTagGroup) currentTagGroup = null;
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Skip comments
|
|
121
|
-
if (trimmed.startsWith('//')) continue;
|
|
122
|
-
|
|
123
|
-
// --- Header phase ---
|
|
124
|
-
|
|
125
|
-
// Extract chart type + title from first line (e.g. `kanban Sprint 12`)
|
|
126
|
-
if (!contentStarted && !currentTagGroup) {
|
|
127
|
-
const firstLine = parseFirstLine(trimmed);
|
|
128
|
-
if (firstLine) {
|
|
129
|
-
if (firstLine.chartType !== 'kanban') {
|
|
130
|
-
const allTypes = [
|
|
131
|
-
'kanban',
|
|
132
|
-
'org',
|
|
133
|
-
'class',
|
|
134
|
-
'flowchart',
|
|
135
|
-
'sequence',
|
|
136
|
-
'er',
|
|
137
|
-
'bar',
|
|
138
|
-
'line',
|
|
139
|
-
'pie',
|
|
140
|
-
];
|
|
141
|
-
let msg = `Expected chart type "kanban", got "${firstLine.chartType}"`;
|
|
142
|
-
const hint = suggest(firstLine.chartType, allTypes);
|
|
143
|
-
if (hint) msg += `. ${hint}`;
|
|
144
|
-
return fail(lineNumber, msg);
|
|
145
|
-
}
|
|
146
|
-
if (firstLine.title) {
|
|
147
|
-
result.title = firstLine.title;
|
|
148
|
-
result.titleLineNumber = lineNumber;
|
|
149
|
-
}
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Tag group heading — `tag Name`
|
|
155
|
-
// Must be checked BEFORE OPTION_RE to prevent `tag Rank` being swallowed as option
|
|
156
|
-
if (!contentStarted) {
|
|
157
|
-
const tagBlockMatch = matchTagBlockHeading(trimmed);
|
|
158
|
-
if (tagBlockMatch) {
|
|
159
|
-
currentTagGroup = {
|
|
160
|
-
name: tagBlockMatch.name,
|
|
161
|
-
...(tagBlockMatch.alias !== undefined && {
|
|
162
|
-
alias: tagBlockMatch.alias,
|
|
163
|
-
}),
|
|
164
|
-
entries: [],
|
|
165
|
-
lineNumber,
|
|
166
|
-
};
|
|
167
|
-
if (tagBlockMatch.alias) {
|
|
168
|
-
metaAliasMap.set(
|
|
169
|
-
normalizeName(tagBlockMatch.alias),
|
|
170
|
-
tagAttrKey(tagBlockMatch.name)
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
// §1.4 dispatch: register the canonical tag name so `priority: X`
|
|
174
|
-
// also dispatches as metadata (not just the optional `p: X` alias).
|
|
175
|
-
metaAliasMap.set(
|
|
176
|
-
normalizeName(tagBlockMatch.name),
|
|
177
|
-
tagAttrKey(tagBlockMatch.name)
|
|
178
|
-
);
|
|
179
|
-
result.tagGroups.push(currentTagGroup);
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Generic header options (space-separated: `key value` or bare boolean `key`)
|
|
185
|
-
// Only match known option keys to avoid swallowing content lines
|
|
186
|
-
if (!contentStarted && !currentTagGroup && measureIndent(line) === 0) {
|
|
187
|
-
const optMatch = trimmed.match(OPTION_NOCOLON_RE);
|
|
188
|
-
if (optMatch && !COLUMN_RE.test(trimmed)) {
|
|
189
|
-
// OPTION_NOCOLON_RE has 2 capture groups; both exist when matched.
|
|
190
|
-
const key = optMatch[1]!.trim().toLowerCase();
|
|
191
|
-
if (KNOWN_OPTIONS.has(key)) {
|
|
192
|
-
options[key] = optMatch[2]!.trim();
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
const removedMsg = REMOVED_BOOLEANS[trimmed.toLowerCase()];
|
|
197
|
-
if (removedMsg && !COLUMN_RE.test(trimmed)) {
|
|
198
|
-
warn(lineNumber, removedMsg);
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
if (
|
|
202
|
-
KNOWN_BOOLEANS.has(trimmed.toLowerCase()) &&
|
|
203
|
-
!COLUMN_RE.test(trimmed)
|
|
204
|
-
) {
|
|
205
|
-
options[trimmed.toLowerCase()] = 'on';
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Tag group entries (indented Value color under tag heading)
|
|
211
|
-
// First entry is the default unless another is marked `default`
|
|
212
|
-
if (currentTagGroup && !contentStarted) {
|
|
213
|
-
const indent = measureIndent(line);
|
|
214
|
-
if (indent > 0) {
|
|
215
|
-
const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
|
|
216
|
-
const { label, color } = extractColor(
|
|
217
|
-
cleanEntry,
|
|
218
|
-
palette,
|
|
219
|
-
result.diagnostics,
|
|
220
|
-
lineNumber
|
|
221
|
-
);
|
|
222
|
-
// Bare value (no explicit color) → keep it; finalized below.
|
|
223
|
-
if (isDefault) {
|
|
224
|
-
currentTagGroup.defaultValue = label;
|
|
225
|
-
} else if (currentTagGroup.entries.length === 0) {
|
|
226
|
-
currentTagGroup.defaultValue = label;
|
|
227
|
-
}
|
|
228
|
-
currentTagGroup.entries.push({
|
|
229
|
-
value: label,
|
|
230
|
-
color: color ?? AUTO_TAG_COLOR_SENTINEL,
|
|
231
|
-
lineNumber,
|
|
232
|
-
});
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
// Non-indented line after tag group — fall through
|
|
236
|
-
currentTagGroup = null;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// --- Content phase ---
|
|
240
|
-
|
|
241
|
-
const indent = measureIndent(line);
|
|
242
|
-
|
|
243
|
-
// [Column] header at indent 0
|
|
244
|
-
const columnMatch = indent === 0 ? trimmed.match(COLUMN_RE) : null;
|
|
245
|
-
if (columnMatch) {
|
|
246
|
-
contentStarted = true;
|
|
247
|
-
currentTagGroup = null;
|
|
248
|
-
|
|
249
|
-
// Finalize previous card's endLineNumber
|
|
250
|
-
if (currentCard) {
|
|
251
|
-
currentCard.endLineNumber = lineNumber - 1;
|
|
252
|
-
while (
|
|
253
|
-
currentCard.endLineNumber > currentCard.lineNumber &&
|
|
254
|
-
!lines[currentCard.endLineNumber - 1]!.trim()
|
|
255
|
-
) {
|
|
256
|
-
currentCard.endLineNumber--;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
currentCard = null;
|
|
260
|
-
|
|
261
|
-
columnCounter++;
|
|
262
|
-
const colName = columnMatch[1]!.trim();
|
|
263
|
-
let tail = (columnMatch[2] ?? '').trim();
|
|
264
|
-
|
|
265
|
-
// Parse tail in order: optional color word, optional `as <alias>`,
|
|
266
|
-
// optional same-line metadata (per §1.4) — with legacy `|` detection.
|
|
267
|
-
let colColor: string | undefined;
|
|
268
|
-
const colorMatch = tail.match(PALETTE_COLOR_WORD_RE);
|
|
269
|
-
if (colorMatch) {
|
|
270
|
-
colColor = resolveColorWithDiagnostic(
|
|
271
|
-
colorMatch[1]!,
|
|
272
|
-
lineNumber,
|
|
273
|
-
result.diagnostics,
|
|
274
|
-
palette
|
|
275
|
-
);
|
|
276
|
-
tail = tail.substring(colorMatch[0]!.length).trim();
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
let colAlias: string | undefined;
|
|
280
|
-
const aliasMatch = tail.match(AS_ALIAS_TOKEN_RE);
|
|
281
|
-
if (aliasMatch) {
|
|
282
|
-
colAlias = aliasMatch[1];
|
|
283
|
-
tail = tail.substring(aliasMatch[0]!.length).trim();
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// §1.4 unified metadata grammar — same-line cut on the tail (which
|
|
287
|
-
// is now `wip: 3, t: Sprint1` shape after color/alias peeled).
|
|
288
|
-
const columnMetadata: Record<string, string> = {};
|
|
289
|
-
let wipLimit: number | undefined;
|
|
290
|
-
if (tail.length > 0) {
|
|
291
|
-
const registry = withTagAliases(
|
|
292
|
-
KANBAN_REGISTRY,
|
|
293
|
-
new Set(metaAliasMap.keys())
|
|
294
|
-
);
|
|
295
|
-
// Build a virtual line so splitNameAndMeta sees the tail at offset 0.
|
|
296
|
-
const split = splitNameAndMeta(
|
|
297
|
-
tail,
|
|
298
|
-
registry,
|
|
299
|
-
metaAliasMap,
|
|
300
|
-
undefined,
|
|
301
|
-
result.diagnostics,
|
|
302
|
-
lineNumber
|
|
303
|
-
);
|
|
304
|
-
warnUnknownMetaKeys(
|
|
305
|
-
split.meta,
|
|
306
|
-
registry,
|
|
307
|
-
(msg) => warn(lineNumber, msg),
|
|
308
|
-
split.name
|
|
309
|
-
);
|
|
310
|
-
Object.assign(columnMetadata, split.meta);
|
|
311
|
-
}
|
|
312
|
-
if (columnMetadata['wip']) {
|
|
313
|
-
const wipVal = parseInt(columnMetadata['wip'], 10);
|
|
314
|
-
if (!isNaN(wipVal)) wipLimit = wipVal;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// `[Column] collapsed: true` view-state marker (mirrors gantt/sequence):
|
|
318
|
-
// a reserved same-line key seeding the column collapsed, extracted into a
|
|
319
|
-
// typed field and dropped from metadata.
|
|
320
|
-
let colCollapsed = false;
|
|
321
|
-
if (columnMetadata['collapsed']?.toLowerCase() === 'true') {
|
|
322
|
-
colCollapsed = true;
|
|
323
|
-
delete columnMetadata['collapsed'];
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
const colId = `col-${columnCounter}`;
|
|
327
|
-
if (colAlias) nameAliasMap.set(colAlias, colId);
|
|
328
|
-
currentColumn = {
|
|
329
|
-
id: colId,
|
|
330
|
-
name: colName,
|
|
331
|
-
...(wipLimit !== undefined && { wipLimit }),
|
|
332
|
-
...(colColor !== undefined && { color: colColor }),
|
|
333
|
-
...(colCollapsed && { collapsed: true }),
|
|
334
|
-
cards: [],
|
|
335
|
-
lineNumber,
|
|
336
|
-
metadata: columnMetadata,
|
|
337
|
-
};
|
|
338
|
-
result.columns.push(currentColumn);
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// If we hit a non-column, non-header line and haven't started content yet,
|
|
343
|
-
// skip silently (blank lines or whitespace between header and columns)
|
|
344
|
-
if (!contentStarted) {
|
|
345
|
-
continue;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
if (!currentColumn) {
|
|
349
|
-
warn(
|
|
350
|
-
lineNumber,
|
|
351
|
-
"Card line found before any column. Declare a column first with '[Column Name]', then indent cards beneath it. (§11)"
|
|
352
|
-
);
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Detail lines: indented deeper than the card
|
|
357
|
-
if (currentCard && indent > cardBaseIndent) {
|
|
358
|
-
currentCard.details.push(trimmed);
|
|
359
|
-
currentCard.endLineNumber = lineNumber;
|
|
360
|
-
continue;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Card line: indented under a [Column]
|
|
364
|
-
if (indent > 0) {
|
|
365
|
-
cardCounter++;
|
|
366
|
-
const card = parseCardLine(
|
|
367
|
-
trimmed,
|
|
368
|
-
lineNumber,
|
|
369
|
-
cardCounter,
|
|
370
|
-
metaAliasMap,
|
|
371
|
-
palette,
|
|
372
|
-
result.diagnostics
|
|
373
|
-
);
|
|
374
|
-
// Cascade column metadata to card tags (card overrides on conflict)
|
|
375
|
-
// Exclude 'wip' from cascading — it's a column-level property, not a card tag
|
|
376
|
-
if (currentColumn.metadata) {
|
|
377
|
-
const cardTags = card.tags as Record<string, string>;
|
|
378
|
-
for (const [key, value] of Object.entries(currentColumn.metadata)) {
|
|
379
|
-
if (key === 'wip') continue;
|
|
380
|
-
if (!(key in cardTags)) {
|
|
381
|
-
cardTags[key] = value;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
cardBaseIndent = indent;
|
|
386
|
-
currentCard = card as Writable<KanbanCard>;
|
|
387
|
-
currentColumn.cards.push(card);
|
|
388
|
-
continue;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Un-indented non-column line in content phase — stray text
|
|
392
|
-
warn(
|
|
393
|
-
lineNumber,
|
|
394
|
-
currentColumn
|
|
395
|
-
? `Unexpected line: '${trimmed}'. Expected an indented card name or column header like '[Column Name]'.`
|
|
396
|
-
: `Unexpected line: '${trimmed}'. Expected a column header like '[Column Name]'.`
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Finalize last card's endLineNumber
|
|
401
|
-
if (currentCard) {
|
|
402
|
-
// Already tracked via detail lines or card line itself
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// Build tag value sets for validation
|
|
406
|
-
for (const group of result.tagGroups) {
|
|
407
|
-
const values = new Set(group.entries.map((e) => e.value.toLowerCase()));
|
|
408
|
-
tagValueSets.set(tagAttrKey(group.name), values);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Validate WIP limits
|
|
412
|
-
for (const col of result.columns) {
|
|
413
|
-
if (col.wipLimit != null && col.cards.length > col.wipLimit) {
|
|
414
|
-
warn(
|
|
415
|
-
col.lineNumber,
|
|
416
|
-
`Column "${col.name}" has ${col.cards.length} cards but WIP limit is ${col.wipLimit}`
|
|
417
|
-
);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// Validate tag values on cards
|
|
422
|
-
for (const col of result.columns) {
|
|
423
|
-
for (const card of col.cards) {
|
|
424
|
-
for (const [tagKey, tagValue] of Object.entries(card.tags)) {
|
|
425
|
-
const groupKey =
|
|
426
|
-
metaAliasMap.get(tagKey.toLowerCase()) ?? tagKey.toLowerCase();
|
|
427
|
-
const validValues = tagValueSets.get(groupKey);
|
|
428
|
-
if (validValues && !validValues.has(tagValue.toLowerCase())) {
|
|
429
|
-
const entries = result.tagGroups
|
|
430
|
-
.find((g) => g.name.toLowerCase() === groupKey)
|
|
431
|
-
?.entries.map((e) => e.value);
|
|
432
|
-
let msg = `Unknown tag value "${tagValue}" for group "${groupKey}"`;
|
|
433
|
-
if (entries) {
|
|
434
|
-
const hint = suggest(tagValue, entries);
|
|
435
|
-
if (hint) msg += `. ${hint}`;
|
|
436
|
-
}
|
|
437
|
-
warn(card.lineNumber, msg);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
if (result.columns.length === 0 && !result.error) {
|
|
444
|
-
return fail(1, 'No columns found. Use [Column Name] to define columns');
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Assign palette colors to bare (colorless) tag values.
|
|
448
|
-
finalizeAutoTagColors(
|
|
449
|
-
result.tagGroups as Writable<KanbanTagGroup>[],
|
|
450
|
-
palette
|
|
451
|
-
);
|
|
452
|
-
|
|
453
|
-
validateTagGroupNames(result.tagGroups, warn, (line, msg) => {
|
|
454
|
-
const diag = makeDgmoError(line, msg);
|
|
455
|
-
result.diagnostics.push(diag);
|
|
456
|
-
if (!result.error) result.error = formatDgmoError(diag);
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
return result;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// ============================================================
|
|
463
|
-
// Card line parser
|
|
464
|
-
// ============================================================
|
|
465
|
-
|
|
466
|
-
function parseCardLine(
|
|
467
|
-
trimmed: string,
|
|
468
|
-
lineNumber: number,
|
|
469
|
-
counter: number,
|
|
470
|
-
metaAliasMap: Map<string, string>,
|
|
471
|
-
_palette?: PaletteColors,
|
|
472
|
-
diagnostics?: import('../diagnostics').DgmoError[]
|
|
473
|
-
): KanbanCard {
|
|
474
|
-
// §1.4 unified metadata grammar — same-line cut.
|
|
475
|
-
const registry = withTagAliases(
|
|
476
|
-
KANBAN_REGISTRY,
|
|
477
|
-
new Set(metaAliasMap.keys())
|
|
478
|
-
);
|
|
479
|
-
const split = splitNameAndMeta(
|
|
480
|
-
trimmed,
|
|
481
|
-
registry,
|
|
482
|
-
metaAliasMap,
|
|
483
|
-
undefined,
|
|
484
|
-
diagnostics,
|
|
485
|
-
lineNumber
|
|
486
|
-
);
|
|
487
|
-
warnUnknownMetaKeys(
|
|
488
|
-
split.meta,
|
|
489
|
-
registry,
|
|
490
|
-
(msg) => diagnostics?.push(makeDgmoError(lineNumber, msg, 'warning')),
|
|
491
|
-
split.name
|
|
492
|
-
);
|
|
493
|
-
// Cards don't have a color slot; the §1.5 trailing-token peel that
|
|
494
|
-
// splitNameAndMeta runs by default would strip `Urgent task red` to
|
|
495
|
-
// title `Urgent task`. Restore the trailing color word as part of the
|
|
496
|
-
// literal title for cards.
|
|
497
|
-
const title =
|
|
498
|
-
split.color !== undefined ? `${split.name} ${split.color}` : split.name;
|
|
499
|
-
const tags: Record<string, string> = { ...split.meta };
|
|
500
|
-
|
|
501
|
-
return {
|
|
502
|
-
id: `card-${counter}`,
|
|
503
|
-
title,
|
|
504
|
-
tags,
|
|
505
|
-
details: [],
|
|
506
|
-
lineNumber,
|
|
507
|
-
endLineNumber: lineNumber,
|
|
508
|
-
};
|
|
509
|
-
}
|