@nowline/export-mermaid 0.5.0 → 0.6.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/dist/index.d.ts.map +1 -1
- package/dist/index.js +97 -36
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +119 -36
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKzD,MAAM,WAAW,cAAc;IAC3B,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAuCD,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CA8DxF"}
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,20 @@
|
|
|
22
22
|
// ```
|
|
23
23
|
//
|
|
24
24
|
// <%% lossy comment %%>
|
|
25
|
+
//
|
|
26
|
+
// Every emitted task carries an explicit start token (`after <id>` or an
|
|
27
|
+
// absolute `YYYY-MM-DD` date). Mermaid's positional task parser strips a
|
|
28
|
+
// leading status keyword (`done`/`active`/`crit`/`milestone`) and then reads
|
|
29
|
+
// the remaining comma fields as `[start, duration]` (2 fields) or
|
|
30
|
+
// `[id, start, duration]` (3 fields). A task that named an id but omitted the
|
|
31
|
+
// start (`:done, my-id, 2w`) collapses to two fields after the status strip,
|
|
32
|
+
// so Mermaid mis-reads the id as a start date and throws `Invalid date: my-id`
|
|
33
|
+
// at render time. To keep an explicit id we therefore MUST emit a start token:
|
|
34
|
+
// - declared `after:` deps -> `after <ids>`
|
|
35
|
+
// - otherwise a lane follower -> `after <previous item in the lane>`
|
|
36
|
+
// - otherwise a lane/track leader -> the roadmap start date
|
|
37
|
+
// This mirrors Nowline's default "each item starts after the preceding item in
|
|
38
|
+
// its lane" semantics (specs/rendering.md § Item Bars).
|
|
25
39
|
import { displayLabel, getProp, getProps, hasProp, roadmapTitle } from '@nowline/export-core';
|
|
26
40
|
import { durationToMermaid } from './duration.js';
|
|
27
41
|
function emptyCounts() {
|
|
@@ -41,6 +55,7 @@ function emptyCounts() {
|
|
|
41
55
|
export function exportMermaid(inputs, options = {}) {
|
|
42
56
|
const ast = inputs.ast;
|
|
43
57
|
const title = roadmapTitle(ast.roadmapDecl ?? undefined);
|
|
58
|
+
const startDate = resolveStartDate(inputs);
|
|
44
59
|
const drops = emptyCounts();
|
|
45
60
|
const out = [];
|
|
46
61
|
out.push(`# ${title}`);
|
|
@@ -56,27 +71,24 @@ export function exportMermaid(inputs, options = {}) {
|
|
|
56
71
|
if (anchors.length > 0) {
|
|
57
72
|
out.push(' section Anchors');
|
|
58
73
|
for (const anchor of anchors) {
|
|
59
|
-
|
|
74
|
+
// Anchors are date markers; fall back to the roadmap start when an
|
|
75
|
+
// anchor omits `date:` so Mermaid always sees a valid start token.
|
|
76
|
+
const date = getProp(anchor, 'date') ?? startDate;
|
|
60
77
|
const id = anchor.name ?? slugify(displayLabel(anchor));
|
|
61
|
-
|
|
62
|
-
out.push(` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, ${date}, 0d`);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
out.push(` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, after , 0d`);
|
|
66
|
-
}
|
|
78
|
+
out.push(` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, ${date}, 0d`);
|
|
67
79
|
}
|
|
68
80
|
}
|
|
69
81
|
// Swimlanes → sections; their items become tasks.
|
|
70
82
|
const swimlanes = ast.roadmapEntries.filter((e) => e.$type === 'SwimlaneDeclaration');
|
|
71
83
|
for (const lane of swimlanes) {
|
|
72
|
-
emitSwimlane(lane, [lane.name ?? slugify(displayLabel(lane))], drops, out);
|
|
84
|
+
emitSwimlane(lane, [lane.name ?? slugify(displayLabel(lane))], drops, out, startDate);
|
|
73
85
|
}
|
|
74
86
|
// Top-level milestones.
|
|
75
87
|
const milestones = ast.roadmapEntries.filter((e) => e.$type === 'MilestoneDeclaration');
|
|
76
88
|
if (milestones.length > 0) {
|
|
77
89
|
out.push(' section Milestones');
|
|
78
90
|
for (const m of milestones) {
|
|
79
|
-
emitMilestone(m, drops, out);
|
|
91
|
+
emitMilestone(m, drops, out, startDate);
|
|
80
92
|
}
|
|
81
93
|
}
|
|
82
94
|
out.push('```');
|
|
@@ -89,30 +101,33 @@ export function exportMermaid(inputs, options = {}) {
|
|
|
89
101
|
}
|
|
90
102
|
return out.join('\n');
|
|
91
103
|
}
|
|
92
|
-
function emitSwimlane(lane, breadcrumb, drops, out) {
|
|
104
|
+
function emitSwimlane(lane, breadcrumb, drops, out, startDate) {
|
|
93
105
|
const sectionLabel = breadcrumb.join('.');
|
|
94
106
|
out.push(` section ${escapeMermaidText(sectionLabel)}`);
|
|
107
|
+
// Each lane starts its own sequential chain; the first non-`after` item
|
|
108
|
+
// anchors at the roadmap start date.
|
|
109
|
+
const chain = { prevId: null };
|
|
95
110
|
for (const child of lane.content) {
|
|
96
|
-
emitSwimlaneChild(child, breadcrumb, drops, out);
|
|
111
|
+
emitSwimlaneChild(child, breadcrumb, drops, out, chain, startDate);
|
|
97
112
|
}
|
|
98
113
|
// Nested swimlanes — count for the lossy report.
|
|
99
114
|
// SwimlaneContent doesn't include nested swimlanes per the grammar, so
|
|
100
115
|
// there's nothing to recurse into here. If `nested` lives on the
|
|
101
116
|
// roadmap-level layout model, that's a separate count tracked elsewhere.
|
|
102
117
|
}
|
|
103
|
-
function emitSwimlaneChild(child, breadcrumb, drops, out) {
|
|
118
|
+
function emitSwimlaneChild(child, breadcrumb, drops, out, chain, startDate) {
|
|
104
119
|
if (child.$type === 'ItemDeclaration') {
|
|
105
|
-
emitItem(child, drops, out);
|
|
120
|
+
emitItem(child, drops, out, chain, startDate);
|
|
106
121
|
return;
|
|
107
122
|
}
|
|
108
123
|
if (child.$type === 'GroupBlock') {
|
|
109
124
|
drops.group += 1;
|
|
110
|
-
emitGroup(child, breadcrumb, drops, out);
|
|
125
|
+
emitGroup(child, breadcrumb, drops, out, chain, startDate);
|
|
111
126
|
return;
|
|
112
127
|
}
|
|
113
128
|
if (child.$type === 'ParallelBlock') {
|
|
114
129
|
drops.parallel += 1;
|
|
115
|
-
emitParallel(child, breadcrumb, drops, out);
|
|
130
|
+
emitParallel(child, breadcrumb, drops, out, chain, startDate);
|
|
116
131
|
return;
|
|
117
132
|
}
|
|
118
133
|
if (child.$type === 'DescriptionDirective') {
|
|
@@ -120,68 +135,114 @@ function emitSwimlaneChild(child, breadcrumb, drops, out) {
|
|
|
120
135
|
return;
|
|
121
136
|
}
|
|
122
137
|
}
|
|
123
|
-
function emitGroup(group, breadcrumb, drops, out) {
|
|
138
|
+
function emitGroup(group, breadcrumb, drops, out, chain, startDate) {
|
|
139
|
+
// A group is a visual container within a lane — its items continue the
|
|
140
|
+
// lane's sequential chain.
|
|
124
141
|
for (const child of group.content) {
|
|
125
142
|
if (child.$type === 'ItemDeclaration') {
|
|
126
|
-
emitItem(child, drops, out);
|
|
143
|
+
emitItem(child, drops, out, chain, startDate);
|
|
127
144
|
}
|
|
128
145
|
else if (child.$type === 'GroupBlock') {
|
|
129
146
|
drops.group += 1;
|
|
130
|
-
emitGroup(child, breadcrumb, drops, out);
|
|
147
|
+
emitGroup(child, breadcrumb, drops, out, chain, startDate);
|
|
131
148
|
}
|
|
132
149
|
else if (child.$type === 'ParallelBlock') {
|
|
133
150
|
drops.parallel += 1;
|
|
134
|
-
emitParallel(child, breadcrumb, drops, out);
|
|
151
|
+
emitParallel(child, breadcrumb, drops, out, chain, startDate);
|
|
135
152
|
}
|
|
136
153
|
else if (child.$type === 'DescriptionDirective') {
|
|
137
154
|
drops.description += 1;
|
|
138
155
|
}
|
|
139
156
|
}
|
|
140
157
|
}
|
|
141
|
-
function emitParallel(parallel, breadcrumb, drops, out) {
|
|
158
|
+
function emitParallel(parallel, breadcrumb, drops, out, chain, startDate) {
|
|
159
|
+
// Tracks run concurrently: each starts from the parallel's entry point
|
|
160
|
+
// (the lane cursor as it was on entry), not after the previous track.
|
|
161
|
+
const entryId = chain.prevId;
|
|
162
|
+
let lastTrackEnd = entryId;
|
|
142
163
|
for (const child of parallel.content) {
|
|
143
164
|
if (child.$type === 'ItemDeclaration') {
|
|
144
|
-
|
|
165
|
+
const trackChain = { prevId: entryId };
|
|
166
|
+
emitItem(child, drops, out, trackChain, startDate);
|
|
167
|
+
lastTrackEnd = trackChain.prevId;
|
|
145
168
|
}
|
|
146
169
|
else if (child.$type === 'GroupBlock') {
|
|
147
170
|
drops.group += 1;
|
|
148
|
-
|
|
171
|
+
const trackChain = { prevId: entryId };
|
|
172
|
+
emitGroup(child, breadcrumb, drops, out, trackChain, startDate);
|
|
173
|
+
lastTrackEnd = trackChain.prevId;
|
|
149
174
|
}
|
|
150
175
|
else if (child.$type === 'DescriptionDirective') {
|
|
151
176
|
drops.description += 1;
|
|
152
177
|
}
|
|
153
178
|
}
|
|
179
|
+
// After the block, the lane continues from the last track (lossy — Mermaid
|
|
180
|
+
// can't express "after the latest of N tracks").
|
|
181
|
+
chain.prevId = lastTrackEnd;
|
|
154
182
|
}
|
|
155
|
-
function emitItem(item, drops, out) {
|
|
183
|
+
function emitItem(item, drops, out, chain, startDate) {
|
|
156
184
|
countDrops(item, drops);
|
|
157
185
|
const id = item.name ?? slugify(displayLabel(item));
|
|
158
186
|
const status = mapStatus(getProp(item, 'status'));
|
|
159
187
|
const after = getProps(item, 'after');
|
|
160
188
|
const duration = durationToMermaid(getProp(item, 'duration') ?? getProp(item, 'size')) ?? '1d';
|
|
161
|
-
const
|
|
162
|
-
const meta = [status, id,
|
|
163
|
-
.filter((s) => s !== '')
|
|
164
|
-
.join(', ');
|
|
189
|
+
const start = startTokenFor(after, chain, startDate);
|
|
190
|
+
const meta = [status, id, start, duration].filter((s) => s !== '').join(', ');
|
|
165
191
|
out.push(` ${escapeTaskName(displayLabel(item))} :${meta}`);
|
|
192
|
+
// Advance the lane cursor so the next sequential item chains after this one.
|
|
193
|
+
chain.prevId = id;
|
|
166
194
|
}
|
|
167
|
-
function emitMilestone(milestone, drops, out) {
|
|
195
|
+
function emitMilestone(milestone, drops, out, startDate) {
|
|
168
196
|
const id = milestone.name ?? slugify(displayLabel(milestone));
|
|
169
197
|
const date = getProp(milestone, 'date');
|
|
198
|
+
const after = getProps(milestone, 'after');
|
|
199
|
+
let start;
|
|
170
200
|
if (date) {
|
|
171
|
-
|
|
201
|
+
start = date;
|
|
202
|
+
}
|
|
203
|
+
else if (after.length > 0) {
|
|
204
|
+
start = `after ${after.join(' ')}`;
|
|
172
205
|
}
|
|
173
206
|
else {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, 0d`);
|
|
180
|
-
}
|
|
207
|
+
// A milestone with neither a date nor predecessors still needs a start
|
|
208
|
+
// token; anchor it at the roadmap start so Mermaid renders it.
|
|
209
|
+
start = startDate;
|
|
181
210
|
}
|
|
211
|
+
out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, ${start}, 0d`);
|
|
182
212
|
if (hasProp(milestone, 'style'))
|
|
183
213
|
drops.style += 1;
|
|
184
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Start token for a task: declared `after:` deps win, otherwise chain after the
|
|
217
|
+
* previous item in the lane, otherwise anchor the lane/track leader at the
|
|
218
|
+
* roadmap start date. Always non-empty so Mermaid never mis-reads the task id
|
|
219
|
+
* as a start date.
|
|
220
|
+
*/
|
|
221
|
+
function startTokenFor(after, chain, startDate) {
|
|
222
|
+
if (after.length > 0)
|
|
223
|
+
return `after ${after.join(' ')}`;
|
|
224
|
+
if (chain.prevId)
|
|
225
|
+
return `after ${chain.prevId}`;
|
|
226
|
+
return startDate;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Absolute anchor date (`YYYY-MM-DD`) for lane leaders. Prefers the roadmap's
|
|
230
|
+
* declared `start:`, falling back to the layout-computed timeline start (always
|
|
231
|
+
* present) so the export renders even when the source omits `start:`.
|
|
232
|
+
*/
|
|
233
|
+
function resolveStartDate(inputs) {
|
|
234
|
+
const decl = inputs.ast.roadmapDecl;
|
|
235
|
+
const declared = decl ? getProp(decl, 'start') : undefined;
|
|
236
|
+
if (declared && /^\d{4}-\d{2}-\d{2}$/.test(declared.trim()))
|
|
237
|
+
return declared.trim();
|
|
238
|
+
return formatIsoDate(inputs.model.timeline.startDate);
|
|
239
|
+
}
|
|
240
|
+
function formatIsoDate(d) {
|
|
241
|
+
const y = d.getUTCFullYear();
|
|
242
|
+
const m = String(d.getUTCMonth() + 1).padStart(2, '0');
|
|
243
|
+
const day = String(d.getUTCDate()).padStart(2, '0');
|
|
244
|
+
return `${y}-${m}-${day}`;
|
|
245
|
+
}
|
|
185
246
|
function countDrops(item, drops) {
|
|
186
247
|
if (getProps(item, 'labels').length > 0)
|
|
187
248
|
drops.labels += 1;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nowline/export-mermaid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Nowline Mermaid exporter — Markdown+Mermaid gantt transpilation",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"src/"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@nowline/core": "0.
|
|
25
|
-
"@nowline/
|
|
26
|
-
"@nowline/
|
|
24
|
+
"@nowline/core": "0.6.0",
|
|
25
|
+
"@nowline/export-core": "0.6.0",
|
|
26
|
+
"@nowline/layout": "0.6.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^25.9.1",
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,20 @@
|
|
|
22
22
|
// ```
|
|
23
23
|
//
|
|
24
24
|
// <%% lossy comment %%>
|
|
25
|
+
//
|
|
26
|
+
// Every emitted task carries an explicit start token (`after <id>` or an
|
|
27
|
+
// absolute `YYYY-MM-DD` date). Mermaid's positional task parser strips a
|
|
28
|
+
// leading status keyword (`done`/`active`/`crit`/`milestone`) and then reads
|
|
29
|
+
// the remaining comma fields as `[start, duration]` (2 fields) or
|
|
30
|
+
// `[id, start, duration]` (3 fields). A task that named an id but omitted the
|
|
31
|
+
// start (`:done, my-id, 2w`) collapses to two fields after the status strip,
|
|
32
|
+
// so Mermaid mis-reads the id as a start date and throws `Invalid date: my-id`
|
|
33
|
+
// at render time. To keep an explicit id we therefore MUST emit a start token:
|
|
34
|
+
// - declared `after:` deps -> `after <ids>`
|
|
35
|
+
// - otherwise a lane follower -> `after <previous item in the lane>`
|
|
36
|
+
// - otherwise a lane/track leader -> the roadmap start date
|
|
37
|
+
// This mirrors Nowline's default "each item starts after the preceding item in
|
|
38
|
+
// its lane" semantics (specs/rendering.md § Item Bars).
|
|
25
39
|
|
|
26
40
|
import type {
|
|
27
41
|
AnchorDeclaration,
|
|
@@ -71,9 +85,19 @@ function emptyCounts(): DropCounts {
|
|
|
71
85
|
};
|
|
72
86
|
}
|
|
73
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Mutable per-lane chaining cursor. `prevId` is the id the NEXT sequential
|
|
90
|
+
* task should start after; `null` means "anchor at the roadmap start date"
|
|
91
|
+
* (lane / parallel-track leader).
|
|
92
|
+
*/
|
|
93
|
+
interface Chain {
|
|
94
|
+
prevId: string | null;
|
|
95
|
+
}
|
|
96
|
+
|
|
74
97
|
export function exportMermaid(inputs: ExportInputs, options: MermaidOptions = {}): string {
|
|
75
98
|
const ast = inputs.ast;
|
|
76
99
|
const title = roadmapTitle(ast.roadmapDecl ?? undefined);
|
|
100
|
+
const startDate = resolveStartDate(inputs);
|
|
77
101
|
const drops = emptyCounts();
|
|
78
102
|
|
|
79
103
|
const out: string[] = [];
|
|
@@ -94,17 +118,11 @@ export function exportMermaid(inputs: ExportInputs, options: MermaidOptions = {}
|
|
|
94
118
|
if (anchors.length > 0) {
|
|
95
119
|
out.push(' section Anchors');
|
|
96
120
|
for (const anchor of anchors) {
|
|
97
|
-
|
|
121
|
+
// Anchors are date markers; fall back to the roadmap start when an
|
|
122
|
+
// anchor omits `date:` so Mermaid always sees a valid start token.
|
|
123
|
+
const date = getProp(anchor, 'date') ?? startDate;
|
|
98
124
|
const id = anchor.name ?? slugify(displayLabel(anchor));
|
|
99
|
-
|
|
100
|
-
out.push(
|
|
101
|
-
` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, ${date}, 0d`,
|
|
102
|
-
);
|
|
103
|
-
} else {
|
|
104
|
-
out.push(
|
|
105
|
-
` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, after , 0d`,
|
|
106
|
-
);
|
|
107
|
-
}
|
|
125
|
+
out.push(` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, ${date}, 0d`);
|
|
108
126
|
}
|
|
109
127
|
}
|
|
110
128
|
|
|
@@ -113,7 +131,7 @@ export function exportMermaid(inputs: ExportInputs, options: MermaidOptions = {}
|
|
|
113
131
|
(e): e is SwimlaneDeclaration => e.$type === 'SwimlaneDeclaration',
|
|
114
132
|
);
|
|
115
133
|
for (const lane of swimlanes) {
|
|
116
|
-
emitSwimlane(lane, [lane.name ?? slugify(displayLabel(lane))], drops, out);
|
|
134
|
+
emitSwimlane(lane, [lane.name ?? slugify(displayLabel(lane))], drops, out, startDate);
|
|
117
135
|
}
|
|
118
136
|
|
|
119
137
|
// Top-level milestones.
|
|
@@ -123,7 +141,7 @@ export function exportMermaid(inputs: ExportInputs, options: MermaidOptions = {}
|
|
|
123
141
|
if (milestones.length > 0) {
|
|
124
142
|
out.push(' section Milestones');
|
|
125
143
|
for (const m of milestones) {
|
|
126
|
-
emitMilestone(m, drops, out);
|
|
144
|
+
emitMilestone(m, drops, out, startDate);
|
|
127
145
|
}
|
|
128
146
|
}
|
|
129
147
|
|
|
@@ -145,11 +163,15 @@ function emitSwimlane(
|
|
|
145
163
|
breadcrumb: readonly string[],
|
|
146
164
|
drops: DropCounts,
|
|
147
165
|
out: string[],
|
|
166
|
+
startDate: string,
|
|
148
167
|
): void {
|
|
149
168
|
const sectionLabel = breadcrumb.join('.');
|
|
150
169
|
out.push(` section ${escapeMermaidText(sectionLabel)}`);
|
|
170
|
+
// Each lane starts its own sequential chain; the first non-`after` item
|
|
171
|
+
// anchors at the roadmap start date.
|
|
172
|
+
const chain: Chain = { prevId: null };
|
|
151
173
|
for (const child of lane.content) {
|
|
152
|
-
emitSwimlaneChild(child, breadcrumb, drops, out);
|
|
174
|
+
emitSwimlaneChild(child, breadcrumb, drops, out, chain, startDate);
|
|
153
175
|
}
|
|
154
176
|
// Nested swimlanes — count for the lossy report.
|
|
155
177
|
// SwimlaneContent doesn't include nested swimlanes per the grammar, so
|
|
@@ -162,19 +184,21 @@ function emitSwimlaneChild(
|
|
|
162
184
|
breadcrumb: readonly string[],
|
|
163
185
|
drops: DropCounts,
|
|
164
186
|
out: string[],
|
|
187
|
+
chain: Chain,
|
|
188
|
+
startDate: string,
|
|
165
189
|
): void {
|
|
166
190
|
if (child.$type === 'ItemDeclaration') {
|
|
167
|
-
emitItem(child, drops, out);
|
|
191
|
+
emitItem(child, drops, out, chain, startDate);
|
|
168
192
|
return;
|
|
169
193
|
}
|
|
170
194
|
if (child.$type === 'GroupBlock') {
|
|
171
195
|
drops.group += 1;
|
|
172
|
-
emitGroup(child, breadcrumb, drops, out);
|
|
196
|
+
emitGroup(child, breadcrumb, drops, out, chain, startDate);
|
|
173
197
|
return;
|
|
174
198
|
}
|
|
175
199
|
if (child.$type === 'ParallelBlock') {
|
|
176
200
|
drops.parallel += 1;
|
|
177
|
-
emitParallel(child, breadcrumb, drops, out);
|
|
201
|
+
emitParallel(child, breadcrumb, drops, out, chain, startDate);
|
|
178
202
|
return;
|
|
179
203
|
}
|
|
180
204
|
if (child.$type === 'DescriptionDirective') {
|
|
@@ -188,16 +212,20 @@ function emitGroup(
|
|
|
188
212
|
breadcrumb: readonly string[],
|
|
189
213
|
drops: DropCounts,
|
|
190
214
|
out: string[],
|
|
215
|
+
chain: Chain,
|
|
216
|
+
startDate: string,
|
|
191
217
|
): void {
|
|
218
|
+
// A group is a visual container within a lane — its items continue the
|
|
219
|
+
// lane's sequential chain.
|
|
192
220
|
for (const child of group.content as GroupContent[]) {
|
|
193
221
|
if (child.$type === 'ItemDeclaration') {
|
|
194
|
-
emitItem(child, drops, out);
|
|
222
|
+
emitItem(child, drops, out, chain, startDate);
|
|
195
223
|
} else if (child.$type === 'GroupBlock') {
|
|
196
224
|
drops.group += 1;
|
|
197
|
-
emitGroup(child, breadcrumb, drops, out);
|
|
225
|
+
emitGroup(child, breadcrumb, drops, out, chain, startDate);
|
|
198
226
|
} else if (child.$type === 'ParallelBlock') {
|
|
199
227
|
drops.parallel += 1;
|
|
200
|
-
emitParallel(child, breadcrumb, drops, out);
|
|
228
|
+
emitParallel(child, breadcrumb, drops, out, chain, startDate);
|
|
201
229
|
} else if (child.$type === 'DescriptionDirective') {
|
|
202
230
|
drops.description += 1;
|
|
203
231
|
}
|
|
@@ -209,51 +237,106 @@ function emitParallel(
|
|
|
209
237
|
breadcrumb: readonly string[],
|
|
210
238
|
drops: DropCounts,
|
|
211
239
|
out: string[],
|
|
240
|
+
chain: Chain,
|
|
241
|
+
startDate: string,
|
|
212
242
|
): void {
|
|
243
|
+
// Tracks run concurrently: each starts from the parallel's entry point
|
|
244
|
+
// (the lane cursor as it was on entry), not after the previous track.
|
|
245
|
+
const entryId = chain.prevId;
|
|
246
|
+
let lastTrackEnd = entryId;
|
|
213
247
|
for (const child of parallel.content) {
|
|
214
248
|
if (child.$type === 'ItemDeclaration') {
|
|
215
|
-
|
|
249
|
+
const trackChain: Chain = { prevId: entryId };
|
|
250
|
+
emitItem(child, drops, out, trackChain, startDate);
|
|
251
|
+
lastTrackEnd = trackChain.prevId;
|
|
216
252
|
} else if (child.$type === 'GroupBlock') {
|
|
217
253
|
drops.group += 1;
|
|
218
|
-
|
|
254
|
+
const trackChain: Chain = { prevId: entryId };
|
|
255
|
+
emitGroup(child, breadcrumb, drops, out, trackChain, startDate);
|
|
256
|
+
lastTrackEnd = trackChain.prevId;
|
|
219
257
|
} else if (child.$type === 'DescriptionDirective') {
|
|
220
258
|
drops.description += 1;
|
|
221
259
|
}
|
|
222
260
|
}
|
|
261
|
+
// After the block, the lane continues from the last track (lossy — Mermaid
|
|
262
|
+
// can't express "after the latest of N tracks").
|
|
263
|
+
chain.prevId = lastTrackEnd;
|
|
223
264
|
}
|
|
224
265
|
|
|
225
|
-
function emitItem(
|
|
266
|
+
function emitItem(
|
|
267
|
+
item: ItemDeclaration,
|
|
268
|
+
drops: DropCounts,
|
|
269
|
+
out: string[],
|
|
270
|
+
chain: Chain,
|
|
271
|
+
startDate: string,
|
|
272
|
+
): void {
|
|
226
273
|
countDrops(item, drops);
|
|
227
274
|
const id = item.name ?? slugify(displayLabel(item));
|
|
228
275
|
const status = mapStatus(getProp(item, 'status'));
|
|
229
276
|
const after = getProps(item, 'after');
|
|
230
277
|
const duration = durationToMermaid(getProp(item, 'duration') ?? getProp(item, 'size')) ?? '1d';
|
|
231
|
-
const
|
|
278
|
+
const start = startTokenFor(after, chain, startDate);
|
|
232
279
|
|
|
233
|
-
const meta = [status, id,
|
|
234
|
-
.filter((s) => s !== '')
|
|
235
|
-
.join(', ');
|
|
280
|
+
const meta = [status, id, start, duration].filter((s) => s !== '').join(', ');
|
|
236
281
|
out.push(` ${escapeTaskName(displayLabel(item))} :${meta}`);
|
|
282
|
+
// Advance the lane cursor so the next sequential item chains after this one.
|
|
283
|
+
chain.prevId = id;
|
|
237
284
|
}
|
|
238
285
|
|
|
239
|
-
function emitMilestone(
|
|
286
|
+
function emitMilestone(
|
|
287
|
+
milestone: MilestoneDeclaration,
|
|
288
|
+
drops: DropCounts,
|
|
289
|
+
out: string[],
|
|
290
|
+
startDate: string,
|
|
291
|
+
): void {
|
|
240
292
|
const id = milestone.name ?? slugify(displayLabel(milestone));
|
|
241
293
|
const date = getProp(milestone, 'date');
|
|
294
|
+
const after = getProps(milestone, 'after');
|
|
295
|
+
let start: string;
|
|
242
296
|
if (date) {
|
|
243
|
-
|
|
297
|
+
start = date;
|
|
298
|
+
} else if (after.length > 0) {
|
|
299
|
+
start = `after ${after.join(' ')}`;
|
|
244
300
|
} else {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, after ${after.join(' ')}, 0d`,
|
|
249
|
-
);
|
|
250
|
-
} else {
|
|
251
|
-
out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, 0d`);
|
|
252
|
-
}
|
|
301
|
+
// A milestone with neither a date nor predecessors still needs a start
|
|
302
|
+
// token; anchor it at the roadmap start so Mermaid renders it.
|
|
303
|
+
start = startDate;
|
|
253
304
|
}
|
|
305
|
+
out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, ${start}, 0d`);
|
|
254
306
|
if (hasProp(milestone, 'style')) drops.style += 1;
|
|
255
307
|
}
|
|
256
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Start token for a task: declared `after:` deps win, otherwise chain after the
|
|
311
|
+
* previous item in the lane, otherwise anchor the lane/track leader at the
|
|
312
|
+
* roadmap start date. Always non-empty so Mermaid never mis-reads the task id
|
|
313
|
+
* as a start date.
|
|
314
|
+
*/
|
|
315
|
+
function startTokenFor(after: readonly string[], chain: Chain, startDate: string): string {
|
|
316
|
+
if (after.length > 0) return `after ${after.join(' ')}`;
|
|
317
|
+
if (chain.prevId) return `after ${chain.prevId}`;
|
|
318
|
+
return startDate;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Absolute anchor date (`YYYY-MM-DD`) for lane leaders. Prefers the roadmap's
|
|
323
|
+
* declared `start:`, falling back to the layout-computed timeline start (always
|
|
324
|
+
* present) so the export renders even when the source omits `start:`.
|
|
325
|
+
*/
|
|
326
|
+
function resolveStartDate(inputs: ExportInputs): string {
|
|
327
|
+
const decl = inputs.ast.roadmapDecl;
|
|
328
|
+
const declared = decl ? getProp(decl, 'start') : undefined;
|
|
329
|
+
if (declared && /^\d{4}-\d{2}-\d{2}$/.test(declared.trim())) return declared.trim();
|
|
330
|
+
return formatIsoDate(inputs.model.timeline.startDate);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function formatIsoDate(d: Date): string {
|
|
334
|
+
const y = d.getUTCFullYear();
|
|
335
|
+
const m = String(d.getUTCMonth() + 1).padStart(2, '0');
|
|
336
|
+
const day = String(d.getUTCDate()).padStart(2, '0');
|
|
337
|
+
return `${y}-${m}-${day}`;
|
|
338
|
+
}
|
|
339
|
+
|
|
257
340
|
function countDrops(item: ItemDeclaration, drops: DropCounts): void {
|
|
258
341
|
if (getProps(item, 'labels').length > 0) drops.labels += 1;
|
|
259
342
|
if (hasProp(item, 'remaining')) drops.remaining += 1;
|