@diagrammo/dgmo 0.8.4 → 0.8.6
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/.claude/commands/dgmo.md +300 -0
- package/.cursorrules +20 -2
- package/.github/copilot-instructions.md +20 -2
- package/.windsurfrules +20 -2
- package/AGENTS.md +23 -3
- package/dist/cli.cjs +191 -189
- package/dist/editor.cjs +5 -18
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +5 -18
- package/dist/editor.js.map +1 -1
- package/dist/highlight.cjs +543 -0
- package/dist/highlight.cjs.map +1 -0
- package/dist/highlight.d.cts +32 -0
- package/dist/highlight.d.ts +32 -0
- package/dist/highlight.js +513 -0
- package/dist/highlight.js.map +1 -0
- package/dist/index.cjs +3253 -3356
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -56
- package/dist/index.d.ts +77 -56
- package/dist/index.js +3247 -3349
- package/dist/index.js.map +1 -1
- package/docs/ai-integration.md +1 -1
- package/docs/language-reference.md +113 -33
- package/gallery/fixtures/boxes-and-lines.dgmo +64 -0
- package/gallery/fixtures/slope.dgmo +7 -6
- package/package.json +26 -6
- package/src/boxes-and-lines/collapse.ts +78 -0
- package/src/boxes-and-lines/layout.ts +319 -0
- package/src/boxes-and-lines/parser.ts +694 -0
- package/src/boxes-and-lines/renderer.ts +848 -0
- package/src/boxes-and-lines/types.ts +40 -0
- package/src/c4/parser.ts +10 -5
- package/src/c4/renderer.ts +232 -56
- package/src/chart.ts +9 -4
- package/src/cli.ts +49 -6
- package/src/completion.ts +25 -33
- package/src/d3.ts +187 -46
- package/src/dgmo-router.ts +3 -7
- package/src/echarts.ts +38 -2
- package/src/editor/highlight-api.ts +444 -0
- package/src/editor/keywords.ts +6 -19
- package/src/er/parser.ts +10 -4
- package/src/gantt/parser.ts +7 -4
- package/src/gantt/renderer.ts +3 -5
- package/src/index.ts +106 -50
- package/src/infra/parser.ts +7 -5
- package/src/infra/renderer.ts +2 -2
- package/src/kanban/parser.ts +7 -5
- package/src/kanban/renderer.ts +43 -18
- package/src/org/parser.ts +7 -4
- package/src/org/renderer.ts +40 -29
- package/src/sequence/parser.ts +11 -5
- package/src/sequence/renderer.ts +114 -45
- package/src/sitemap/parser.ts +8 -4
- package/src/sitemap/renderer.ts +137 -57
- package/src/utils/legend-svg.ts +44 -20
- package/src/utils/parsing.ts +1 -1
- package/src/utils/tag-groups.ts +21 -1
- package/gallery/fixtures/initiative-status-full.dgmo +0 -46
- package/gallery/fixtures/initiative-status-phases.dgmo +0 -29
- package/gallery/fixtures/initiative-status.dgmo +0 -9
- package/src/initiative-status/collapse.ts +0 -76
- package/src/initiative-status/filter.ts +0 -63
- package/src/initiative-status/layout.ts +0 -650
- package/src/initiative-status/parser.ts +0 -629
- package/src/initiative-status/renderer.ts +0 -1199
- package/src/initiative-status/types.ts +0 -57
package/src/index.ts
CHANGED
|
@@ -27,13 +27,8 @@ export type { RenderCategory } from './dgmo-router';
|
|
|
27
27
|
// Parsers
|
|
28
28
|
// ============================================================
|
|
29
29
|
|
|
30
|
-
export { parseChart } from './chart';
|
|
31
|
-
export type {
|
|
32
|
-
ParsedChart,
|
|
33
|
-
ChartType,
|
|
34
|
-
ChartDataPoint,
|
|
35
|
-
ChartEra,
|
|
36
|
-
} from './chart';
|
|
30
|
+
export { parseChart, parseDataRowValues } from './chart';
|
|
31
|
+
export type { ParsedChart, ChartType, ChartDataPoint, ChartEra } from './chart';
|
|
37
32
|
|
|
38
33
|
export { parseExtendedChart } from './echarts';
|
|
39
34
|
export type { ParsedExtendedChart, ExtendedChartType } from './echarts';
|
|
@@ -46,7 +41,13 @@ export {
|
|
|
46
41
|
computeTimeTicks,
|
|
47
42
|
formatDateLabel,
|
|
48
43
|
} from './d3';
|
|
49
|
-
export type {
|
|
44
|
+
export type {
|
|
45
|
+
ParsedVisualization,
|
|
46
|
+
VisualizationType,
|
|
47
|
+
D3ExportDimensions,
|
|
48
|
+
ArcLink,
|
|
49
|
+
ArcNodeGroup,
|
|
50
|
+
} from './d3';
|
|
50
51
|
|
|
51
52
|
export {
|
|
52
53
|
parseSequenceDgmo,
|
|
@@ -99,7 +100,10 @@ export type {
|
|
|
99
100
|
ClassLayoutEdge,
|
|
100
101
|
} from './class/layout';
|
|
101
102
|
|
|
102
|
-
export {
|
|
103
|
+
export {
|
|
104
|
+
renderClassDiagram,
|
|
105
|
+
renderClassDiagramForExport,
|
|
106
|
+
} from './class/renderer';
|
|
103
107
|
|
|
104
108
|
export { parseERDiagram, looksLikeERDiagram } from './er/parser';
|
|
105
109
|
|
|
@@ -113,11 +117,7 @@ export type {
|
|
|
113
117
|
} from './er/types';
|
|
114
118
|
|
|
115
119
|
export { layoutERDiagram } from './er/layout';
|
|
116
|
-
export type {
|
|
117
|
-
ERLayoutResult,
|
|
118
|
-
ERLayoutNode,
|
|
119
|
-
ERLayoutEdge,
|
|
120
|
-
} from './er/layout';
|
|
120
|
+
export type { ERLayoutResult, ERLayoutNode, ERLayoutEdge } from './er/layout';
|
|
121
121
|
|
|
122
122
|
export { renderERDiagram, renderERDiagramForExport } from './er/renderer';
|
|
123
123
|
|
|
@@ -136,10 +136,7 @@ export { parseInlineMarkdown, truncateBareUrl } from './utils/inline-markdown';
|
|
|
136
136
|
export type { InlineSpan } from './utils/inline-markdown';
|
|
137
137
|
|
|
138
138
|
export { parseOrg } from './org/parser';
|
|
139
|
-
export type {
|
|
140
|
-
ParsedOrg,
|
|
141
|
-
OrgNode,
|
|
142
|
-
} from './org/parser';
|
|
139
|
+
export type { ParsedOrg, OrgNode } from './org/parser';
|
|
143
140
|
|
|
144
141
|
export { layoutOrg } from './org/layout';
|
|
145
142
|
export type {
|
|
@@ -159,7 +156,11 @@ export type {
|
|
|
159
156
|
KanbanTagGroup,
|
|
160
157
|
KanbanTagEntry,
|
|
161
158
|
} from './kanban/types';
|
|
162
|
-
export {
|
|
159
|
+
export {
|
|
160
|
+
computeCardMove,
|
|
161
|
+
computeCardArchive,
|
|
162
|
+
isArchiveColumn,
|
|
163
|
+
} from './kanban/mutations';
|
|
163
164
|
export { renderKanban, renderKanbanForExport } from './kanban/renderer';
|
|
164
165
|
|
|
165
166
|
export { parseC4 } from './c4/parser';
|
|
@@ -176,7 +177,13 @@ export type {
|
|
|
176
177
|
C4TagEntry,
|
|
177
178
|
} from './c4/types';
|
|
178
179
|
|
|
179
|
-
export {
|
|
180
|
+
export {
|
|
181
|
+
layoutC4Context,
|
|
182
|
+
layoutC4Containers,
|
|
183
|
+
layoutC4Components,
|
|
184
|
+
layoutC4Deployment,
|
|
185
|
+
rollUpContextRelationships,
|
|
186
|
+
} from './c4/layout';
|
|
180
187
|
export type {
|
|
181
188
|
C4LayoutResult,
|
|
182
189
|
C4LayoutNode,
|
|
@@ -197,30 +204,27 @@ export {
|
|
|
197
204
|
renderC4DeploymentForExport,
|
|
198
205
|
} from './c4/renderer';
|
|
199
206
|
|
|
200
|
-
export {
|
|
207
|
+
export { parseBoxesAndLines } from './boxes-and-lines/parser';
|
|
201
208
|
export type {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
} from './
|
|
208
|
-
|
|
209
|
-
export { layoutInitiativeStatus } from './initiative-status/layout';
|
|
209
|
+
ParsedBoxesAndLines,
|
|
210
|
+
BLNode,
|
|
211
|
+
BLEdge,
|
|
212
|
+
BLGroup,
|
|
213
|
+
} from './boxes-and-lines/types';
|
|
214
|
+
export { layoutBoxesAndLines } from './boxes-and-lines/layout';
|
|
210
215
|
export type {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
} from './
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
export { collapseInitiativeStatus } from './initiative-status/collapse';
|
|
221
|
-
export type { CollapseResult } from './initiative-status/collapse';
|
|
216
|
+
BLLayoutResult,
|
|
217
|
+
BLLayoutNode,
|
|
218
|
+
BLLayoutEdge,
|
|
219
|
+
BLLayoutGroup,
|
|
220
|
+
} from './boxes-and-lines/layout';
|
|
221
|
+
export {
|
|
222
|
+
renderBoxesAndLines,
|
|
223
|
+
renderBoxesAndLinesForExport,
|
|
224
|
+
} from './boxes-and-lines/renderer';
|
|
222
225
|
|
|
223
|
-
export {
|
|
226
|
+
export { collapseBoxesAndLines } from './boxes-and-lines/collapse';
|
|
227
|
+
export type { BLCollapseResult } from './boxes-and-lines/collapse';
|
|
224
228
|
|
|
225
229
|
export { parseSitemap, looksLikeSitemap } from './sitemap/parser';
|
|
226
230
|
|
|
@@ -247,16 +251,42 @@ export { collapseSitemapTree } from './sitemap/collapse';
|
|
|
247
251
|
|
|
248
252
|
// ── Infra Chart ────────────────────────────────────────────
|
|
249
253
|
export { parseInfra } from './infra/parser';
|
|
250
|
-
export type {
|
|
254
|
+
export type {
|
|
255
|
+
ParsedInfra,
|
|
256
|
+
InfraNode,
|
|
257
|
+
InfraEdge,
|
|
258
|
+
InfraGroup,
|
|
259
|
+
InfraTagGroup,
|
|
260
|
+
InfraProperty,
|
|
261
|
+
InfraDiagnostic,
|
|
262
|
+
InfraComputeParams,
|
|
263
|
+
InfraBehaviorKey,
|
|
264
|
+
} from './infra/types';
|
|
251
265
|
export { INFRA_BEHAVIOR_KEYS } from './infra/types';
|
|
252
266
|
export { computeInfra } from './infra/compute';
|
|
253
|
-
export type {
|
|
267
|
+
export type {
|
|
268
|
+
ComputedInfraModel,
|
|
269
|
+
ComputedInfraNode,
|
|
270
|
+
ComputedInfraEdge,
|
|
271
|
+
InfraLatencyPercentiles,
|
|
272
|
+
InfraAvailabilityPercentiles,
|
|
273
|
+
InfraCbState,
|
|
274
|
+
} from './infra/types';
|
|
254
275
|
export { validateInfra, validateComputed } from './infra/validation';
|
|
255
276
|
export { inferRoles, collectDiagramRoles } from './infra/roles';
|
|
256
277
|
export type { InfraRole } from './infra/roles';
|
|
257
278
|
export { layoutInfra } from './infra/layout';
|
|
258
|
-
export type {
|
|
259
|
-
|
|
279
|
+
export type {
|
|
280
|
+
InfraLayoutResult,
|
|
281
|
+
InfraLayoutNode,
|
|
282
|
+
InfraLayoutEdge,
|
|
283
|
+
InfraLayoutGroup,
|
|
284
|
+
} from './infra/layout';
|
|
285
|
+
export {
|
|
286
|
+
renderInfra,
|
|
287
|
+
parseAndLayoutInfra,
|
|
288
|
+
computeInfraLegendGroups,
|
|
289
|
+
} from './infra/renderer';
|
|
260
290
|
export type { InfraLegendGroup, InfraPlaybackState } from './infra/renderer';
|
|
261
291
|
export type { CollapsedSitemapResult } from './sitemap/collapse';
|
|
262
292
|
|
|
@@ -264,7 +294,13 @@ export type { CollapsedSitemapResult } from './sitemap/collapse';
|
|
|
264
294
|
export { parseGantt } from './gantt/parser';
|
|
265
295
|
export { calculateSchedule } from './gantt/calculator';
|
|
266
296
|
export { renderGantt, buildTagLaneRowList } from './gantt/renderer';
|
|
267
|
-
export type {
|
|
297
|
+
export type {
|
|
298
|
+
GanttInteractiveOptions,
|
|
299
|
+
GanttRow,
|
|
300
|
+
GanttGroupRow,
|
|
301
|
+
GanttTaskRow,
|
|
302
|
+
GanttLaneHeaderRow,
|
|
303
|
+
} from './gantt/renderer';
|
|
268
304
|
export { resolveTaskName, collectTasks } from './gantt/resolver';
|
|
269
305
|
export type {
|
|
270
306
|
ParsedGantt,
|
|
@@ -288,7 +324,11 @@ export { collapseOrgTree } from './org/collapse';
|
|
|
288
324
|
export type { CollapsedOrgResult } from './org/collapse';
|
|
289
325
|
|
|
290
326
|
export { resolveOrgImports } from './org/resolver';
|
|
291
|
-
export type {
|
|
327
|
+
export type {
|
|
328
|
+
ReadFileFn,
|
|
329
|
+
ResolveImportsResult,
|
|
330
|
+
ImportSource,
|
|
331
|
+
} from './org/resolver';
|
|
292
332
|
|
|
293
333
|
export { layoutGraph } from './graph/layout';
|
|
294
334
|
export type {
|
|
@@ -298,13 +338,23 @@ export type {
|
|
|
298
338
|
LayoutGroup,
|
|
299
339
|
} from './graph/layout';
|
|
300
340
|
|
|
301
|
-
export {
|
|
341
|
+
export {
|
|
342
|
+
renderFlowchart,
|
|
343
|
+
renderFlowchartForExport,
|
|
344
|
+
} from './graph/flowchart-renderer';
|
|
302
345
|
|
|
303
346
|
// ============================================================
|
|
304
347
|
// Config Builders (produce framework-specific config objects)
|
|
305
348
|
// ============================================================
|
|
306
349
|
|
|
307
|
-
export {
|
|
350
|
+
export {
|
|
351
|
+
buildExtendedChartOption,
|
|
352
|
+
buildSimpleChartOption,
|
|
353
|
+
renderExtendedChartForExport,
|
|
354
|
+
getExtendedChartLegendGroups,
|
|
355
|
+
getSimpleChartLegendGroups,
|
|
356
|
+
computeScatterLabelGraphics,
|
|
357
|
+
} from './echarts';
|
|
308
358
|
export type { ScatterLabelPoint } from './echarts';
|
|
309
359
|
export { renderLegendSvg, type LegendGroupData } from './utils/legend-svg';
|
|
310
360
|
export { LEGEND_HEIGHT } from './utils/legend-constants';
|
|
@@ -403,7 +453,13 @@ export {
|
|
|
403
453
|
PIPE_METADATA,
|
|
404
454
|
extractTagDeclarations,
|
|
405
455
|
} from './completion';
|
|
406
|
-
export type {
|
|
456
|
+
export type {
|
|
457
|
+
DiagramSymbols,
|
|
458
|
+
ExtractFn,
|
|
459
|
+
DirectiveSpec,
|
|
460
|
+
DirectiveValueSpec,
|
|
461
|
+
PipeKeySpec,
|
|
462
|
+
} from './completion';
|
|
407
463
|
|
|
408
464
|
export { parseFirstLine, ALL_CHART_TYPES } from './utils/parsing';
|
|
409
465
|
|
package/src/infra/parser.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
parseFirstLine,
|
|
13
13
|
OPTION_NOCOLON_RE,
|
|
14
14
|
} from '../utils/parsing';
|
|
15
|
-
import { matchTagBlockHeading } from '../utils/tag-groups';
|
|
15
|
+
import { matchTagBlockHeading, stripDefaultModifier } from '../utils/tag-groups';
|
|
16
16
|
import type {
|
|
17
17
|
ParsedInfra,
|
|
18
18
|
InfraNode,
|
|
@@ -338,17 +338,19 @@ export function parseInfra(content: string): ParsedInfra {
|
|
|
338
338
|
|
|
339
339
|
// ---- Indented lines ----
|
|
340
340
|
|
|
341
|
-
// Tag value inside tag group — first value is the default
|
|
341
|
+
// Tag value inside tag group — first value is the default unless another is marked `default`
|
|
342
342
|
if (currentTagGroup && indent > 0) {
|
|
343
|
-
const
|
|
343
|
+
const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
|
|
344
|
+
const tvMatch = cleanEntry.match(TAG_VALUE_RE);
|
|
344
345
|
if (tvMatch) {
|
|
345
346
|
const valueName = tvMatch[1].trim();
|
|
346
347
|
currentTagGroup.values.push({
|
|
347
348
|
name: valueName,
|
|
348
349
|
color: tvMatch[2]?.trim(),
|
|
349
350
|
});
|
|
350
|
-
|
|
351
|
-
|
|
351
|
+
if (isDefault) {
|
|
352
|
+
currentTagGroup.defaultValue = valueName;
|
|
353
|
+
} else if (currentTagGroup.values.length === 1) {
|
|
352
354
|
currentTagGroup.defaultValue = valueName;
|
|
353
355
|
}
|
|
354
356
|
continue;
|
package/src/infra/renderer.ts
CHANGED
|
@@ -2069,8 +2069,8 @@ function renderLegend(
|
|
|
2069
2069
|
}
|
|
2070
2070
|
|
|
2071
2071
|
const pillXOff = isActive ? LEGEND_CAPSULE_PAD : 0;
|
|
2072
|
-
const pillYOff =
|
|
2073
|
-
const pillH = LEGEND_HEIGHT -
|
|
2072
|
+
const pillYOff = LEGEND_CAPSULE_PAD;
|
|
2073
|
+
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
2074
2074
|
|
|
2075
2075
|
// Pill background
|
|
2076
2076
|
gEl
|
package/src/kanban/parser.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PaletteColors } from '../palettes';
|
|
2
2
|
import { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';
|
|
3
3
|
import { resolveColor } from '../colors';
|
|
4
|
-
import { matchTagBlockHeading } from '../utils/tag-groups';
|
|
4
|
+
import { matchTagBlockHeading, stripDefaultModifier } from '../utils/tag-groups';
|
|
5
5
|
import {
|
|
6
6
|
measureIndent,
|
|
7
7
|
extractColor,
|
|
@@ -166,11 +166,12 @@ export function parseKanban(
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
// Tag group entries (indented Value(color) under tag heading)
|
|
169
|
-
// First entry is
|
|
169
|
+
// First entry is the default unless another is marked `default`
|
|
170
170
|
if (currentTagGroup && !contentStarted) {
|
|
171
171
|
const indent = measureIndent(line);
|
|
172
172
|
if (indent > 0) {
|
|
173
|
-
const {
|
|
173
|
+
const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
|
|
174
|
+
const { label, color } = extractColor(cleanEntry, palette);
|
|
174
175
|
if (!color) {
|
|
175
176
|
warn(
|
|
176
177
|
lineNumber,
|
|
@@ -178,8 +179,9 @@ export function parseKanban(
|
|
|
178
179
|
);
|
|
179
180
|
continue;
|
|
180
181
|
}
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
if (isDefault) {
|
|
183
|
+
currentTagGroup.defaultValue = label;
|
|
184
|
+
} else if (currentTagGroup.entries.length === 0) {
|
|
183
185
|
currentTagGroup.defaultValue = label;
|
|
184
186
|
}
|
|
185
187
|
currentTagGroup.entries.push({
|
package/src/kanban/renderer.ts
CHANGED
|
@@ -7,7 +7,12 @@ import { FONT_FAMILY } from '../fonts';
|
|
|
7
7
|
import type { PaletteColors } from '../palettes';
|
|
8
8
|
import { mix } from '../palettes/color-utils';
|
|
9
9
|
import { renderInlineText } from '../utils/inline-markdown';
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
ParsedKanban,
|
|
12
|
+
KanbanColumn,
|
|
13
|
+
KanbanCard,
|
|
14
|
+
KanbanTagGroup,
|
|
15
|
+
} from './types';
|
|
11
16
|
import { parseKanban } from './parser';
|
|
12
17
|
import { isArchiveColumn } from './mutations';
|
|
13
18
|
import {
|
|
@@ -141,13 +146,18 @@ function computeLayout(
|
|
|
141
146
|
const metaCount = tagMeta.length + card.details.length;
|
|
142
147
|
const metaHeight =
|
|
143
148
|
metaCount > 0
|
|
144
|
-
? CARD_SEPARATOR_GAP +
|
|
149
|
+
? CARD_SEPARATOR_GAP +
|
|
150
|
+
1 +
|
|
151
|
+
CARD_PADDING_Y +
|
|
152
|
+
metaCount * CARD_META_LINE_HEIGHT
|
|
145
153
|
: 0;
|
|
146
154
|
const cardHeight = CARD_HEADER_HEIGHT + CARD_PADDING_Y + metaHeight;
|
|
147
155
|
|
|
148
156
|
// Account for meta label widths
|
|
149
157
|
for (const m of tagMeta) {
|
|
150
|
-
const metaW =
|
|
158
|
+
const metaW =
|
|
159
|
+
(m.label.length + 2 + m.value.length) * CARD_META_FONT_SIZE * 0.6 +
|
|
160
|
+
CARD_PADDING_X * 2;
|
|
151
161
|
maxCardTextWidth = Math.max(maxCardTextWidth, metaW);
|
|
152
162
|
}
|
|
153
163
|
|
|
@@ -162,7 +172,10 @@ function computeLayout(
|
|
|
162
172
|
cardY += cardHeight + CARD_GAP;
|
|
163
173
|
}
|
|
164
174
|
|
|
165
|
-
const colWidth = Math.max(
|
|
175
|
+
const colWidth = Math.max(
|
|
176
|
+
COLUMN_MIN_WIDTH,
|
|
177
|
+
maxCardTextWidth + COLUMN_PADDING * 2
|
|
178
|
+
);
|
|
166
179
|
|
|
167
180
|
// Set card widths
|
|
168
181
|
for (const cl of cardLayouts) {
|
|
@@ -269,7 +282,11 @@ export function renderKanban(
|
|
|
269
282
|
if (isActive) {
|
|
270
283
|
capsuleContentWidth += 4; // gap after pill
|
|
271
284
|
for (const entry of group.entries) {
|
|
272
|
-
capsuleContentWidth +=
|
|
285
|
+
capsuleContentWidth +=
|
|
286
|
+
LEGEND_DOT_R * 2 +
|
|
287
|
+
4 +
|
|
288
|
+
entry.value.length * LEGEND_ENTRY_FONT_SIZE * 0.6 +
|
|
289
|
+
8;
|
|
273
290
|
}
|
|
274
291
|
}
|
|
275
292
|
const capsuleWidth = capsuleContentWidth + capsulePad * 2;
|
|
@@ -293,10 +310,10 @@ export function renderKanban(
|
|
|
293
310
|
legendContainer
|
|
294
311
|
.append('rect')
|
|
295
312
|
.attr('x', pillX)
|
|
296
|
-
.attr('y', legendY +
|
|
313
|
+
.attr('y', legendY + capsulePad)
|
|
297
314
|
.attr('width', pillWidth)
|
|
298
|
-
.attr('height', LEGEND_HEIGHT -
|
|
299
|
-
.attr('rx', (LEGEND_HEIGHT -
|
|
315
|
+
.attr('height', LEGEND_HEIGHT - capsulePad * 2)
|
|
316
|
+
.attr('rx', (LEGEND_HEIGHT - capsulePad * 2) / 2)
|
|
300
317
|
.attr('fill', pillBg)
|
|
301
318
|
.attr('class', 'kanban-legend-group')
|
|
302
319
|
.attr('data-legend-group', group.name.toLowerCase());
|
|
@@ -345,12 +362,16 @@ export function renderKanban(
|
|
|
345
362
|
entryG
|
|
346
363
|
.append('text')
|
|
347
364
|
.attr('x', entryTextX)
|
|
348
|
-
.attr(
|
|
365
|
+
.attr(
|
|
366
|
+
'y',
|
|
367
|
+
legendY + LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1
|
|
368
|
+
)
|
|
349
369
|
.attr('font-size', LEGEND_ENTRY_FONT_SIZE)
|
|
350
370
|
.attr('fill', palette.textMuted)
|
|
351
371
|
.text(entry.value);
|
|
352
372
|
|
|
353
|
-
entryX =
|
|
373
|
+
entryX =
|
|
374
|
+
entryTextX + entry.value.length * LEGEND_ENTRY_FONT_SIZE * 0.6 + 8;
|
|
354
375
|
}
|
|
355
376
|
legendX += capsuleWidth + 12;
|
|
356
377
|
} else {
|
|
@@ -423,10 +444,7 @@ export function renderKanban(
|
|
|
423
444
|
.attr('x', colLayout.x + COLUMN_PADDING + nameWidth + 8)
|
|
424
445
|
.attr(
|
|
425
446
|
'y',
|
|
426
|
-
colLayout.y +
|
|
427
|
-
COLUMN_HEADER_HEIGHT / 2 +
|
|
428
|
-
WIP_FONT_SIZE / 2 -
|
|
429
|
-
1
|
|
447
|
+
colLayout.y + COLUMN_HEADER_HEIGHT / 2 + WIP_FONT_SIZE / 2 - 1
|
|
430
448
|
)
|
|
431
449
|
.attr('font-size', WIP_FONT_SIZE)
|
|
432
450
|
.attr('fill', wipExceeded ? palette.colors.red : palette.textMuted)
|
|
@@ -437,7 +455,11 @@ export function renderKanban(
|
|
|
437
455
|
// Cards
|
|
438
456
|
for (const cardLayout of colLayout.cardLayouts) {
|
|
439
457
|
const card = cardLayout.card;
|
|
440
|
-
const resolvedColor = resolveCardTagColor(
|
|
458
|
+
const resolvedColor = resolveCardTagColor(
|
|
459
|
+
card,
|
|
460
|
+
parsed.tagGroups,
|
|
461
|
+
activeTagGroup ?? null
|
|
462
|
+
);
|
|
441
463
|
const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
|
|
442
464
|
const hasMeta = tagMeta.length > 0 || card.details.length > 0;
|
|
443
465
|
|
|
@@ -481,7 +503,8 @@ export function renderKanban(
|
|
|
481
503
|
.attr('stroke-width', CARD_STROKE_WIDTH);
|
|
482
504
|
|
|
483
505
|
// Card title (inline markdown)
|
|
484
|
-
const titleEl = cg
|
|
506
|
+
const titleEl = cg
|
|
507
|
+
.append('text')
|
|
485
508
|
.attr('x', cx + CARD_PADDING_X)
|
|
486
509
|
.attr('y', cy + CARD_PADDING_Y + CARD_TITLE_FONT_SIZE)
|
|
487
510
|
.attr('font-size', CARD_TITLE_FONT_SIZE)
|
|
@@ -513,7 +536,8 @@ export function renderKanban(
|
|
|
513
536
|
.attr('fill', palette.textMuted)
|
|
514
537
|
.text(`${meta.label}: `);
|
|
515
538
|
|
|
516
|
-
const labelWidth =
|
|
539
|
+
const labelWidth =
|
|
540
|
+
(meta.label.length + 2) * CARD_META_FONT_SIZE * 0.6;
|
|
517
541
|
cg.append('text')
|
|
518
542
|
.attr('x', cx + CARD_PADDING_X + labelWidth)
|
|
519
543
|
.attr('y', metaY)
|
|
@@ -526,7 +550,8 @@ export function renderKanban(
|
|
|
526
550
|
|
|
527
551
|
// Detail lines (inline markdown)
|
|
528
552
|
for (const detail of card.details) {
|
|
529
|
-
const detailEl = cg
|
|
553
|
+
const detailEl = cg
|
|
554
|
+
.append('text')
|
|
530
555
|
.attr('x', cx + CARD_PADDING_X)
|
|
531
556
|
.attr('y', metaY)
|
|
532
557
|
.attr('font-size', CARD_META_FONT_SIZE)
|
package/src/org/parser.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
isTagBlockHeading,
|
|
7
7
|
matchTagBlockHeading,
|
|
8
8
|
validateTagValues,
|
|
9
|
+
stripDefaultModifier,
|
|
9
10
|
} from '../utils/tag-groups';
|
|
10
11
|
import {
|
|
11
12
|
measureIndent,
|
|
@@ -220,11 +221,12 @@ export function parseOrg(content: string, palette?: PaletteColors): ParsedOrg {
|
|
|
220
221
|
}
|
|
221
222
|
|
|
222
223
|
// Tag group entries (indented Value(color) under tag heading)
|
|
223
|
-
// First entry is
|
|
224
|
+
// First entry is the default unless another is marked `default`
|
|
224
225
|
if (currentTagGroup && !contentStarted) {
|
|
225
226
|
const indent = measureIndent(line);
|
|
226
227
|
if (indent > 0) {
|
|
227
|
-
const {
|
|
228
|
+
const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
|
|
229
|
+
const { label, color } = extractColor(cleanEntry, palette);
|
|
228
230
|
if (!color) {
|
|
229
231
|
pushError(
|
|
230
232
|
lineNumber,
|
|
@@ -232,8 +234,9 @@ export function parseOrg(content: string, palette?: PaletteColors): ParsedOrg {
|
|
|
232
234
|
);
|
|
233
235
|
continue;
|
|
234
236
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
+
if (isDefault) {
|
|
238
|
+
currentTagGroup.defaultValue = label;
|
|
239
|
+
} else if (currentTagGroup.entries.length === 0) {
|
|
237
240
|
currentTagGroup.defaultValue = label;
|
|
238
241
|
}
|
|
239
242
|
currentTagGroup.entries.push({
|