@diagrammo/dgmo 0.2.27 → 0.3.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/.claude/skills/dgmo-chart/SKILL.md +107 -0
- package/.claude/skills/dgmo-flowchart/SKILL.md +61 -0
- package/.claude/skills/dgmo-generate/SKILL.md +58 -0
- package/.claude/skills/dgmo-sequence/SKILL.md +83 -0
- package/.cursorrules +117 -0
- package/.github/copilot-instructions.md +117 -0
- package/.windsurfrules +117 -0
- package/README.md +10 -3
- package/dist/cli.cjs +366 -918
- package/dist/index.cjs +581 -396
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -24
- package/dist/index.d.ts +39 -24
- package/dist/index.js +578 -395
- package/dist/index.js.map +1 -1
- package/docs/ai-integration.md +125 -0
- package/docs/language-reference.md +786 -0
- package/package.json +15 -8
- package/src/c4/parser.ts +90 -74
- package/src/c4/renderer.ts +13 -12
- package/src/c4/types.ts +6 -4
- package/src/chart.ts +3 -2
- package/src/class/layout.ts +17 -12
- package/src/class/parser.ts +22 -52
- package/src/class/renderer.ts +44 -46
- package/src/class/types.ts +1 -1
- package/src/cli.ts +130 -19
- package/src/d3.ts +1 -1
- package/src/dgmo-mermaid.ts +1 -1
- package/src/dgmo-router.ts +1 -1
- package/src/echarts.ts +33 -13
- package/src/er/parser.ts +34 -43
- package/src/er/types.ts +1 -1
- package/src/graph/flowchart-parser.ts +2 -25
- package/src/graph/types.ts +1 -1
- package/src/index.ts +5 -0
- package/src/initiative-status/parser.ts +36 -7
- package/src/initiative-status/types.ts +1 -1
- package/src/kanban/parser.ts +32 -53
- package/src/kanban/renderer.ts +9 -8
- package/src/kanban/types.ts +6 -14
- package/src/org/parser.ts +47 -87
- package/src/org/resolver.ts +11 -12
- package/src/sequence/parser.ts +97 -15
- package/src/sequence/renderer.ts +62 -69
- package/src/utils/arrows.ts +75 -0
- package/src/utils/inline-markdown.ts +75 -0
- package/src/utils/parsing.ts +67 -0
- package/src/utils/tag-groups.ts +76 -0
package/dist/index.js
CHANGED
|
@@ -1527,6 +1527,96 @@ var init_participant_inference = __esm({
|
|
|
1527
1527
|
}
|
|
1528
1528
|
});
|
|
1529
1529
|
|
|
1530
|
+
// src/utils/arrows.ts
|
|
1531
|
+
function parseArrow(line7) {
|
|
1532
|
+
const patterns = [
|
|
1533
|
+
{ re: BIDI_SYNC_LABELED_RE, async: false, bidirectional: true },
|
|
1534
|
+
{ re: BIDI_ASYNC_LABELED_RE, async: true, bidirectional: true },
|
|
1535
|
+
{ re: SYNC_LABELED_RE, async: false, bidirectional: false },
|
|
1536
|
+
{ re: ASYNC_LABELED_RE, async: true, bidirectional: false }
|
|
1537
|
+
];
|
|
1538
|
+
for (const { re, async: isAsync, bidirectional } of patterns) {
|
|
1539
|
+
const m = line7.match(re);
|
|
1540
|
+
if (!m) continue;
|
|
1541
|
+
const label = m[2].trim();
|
|
1542
|
+
if (!label) return null;
|
|
1543
|
+
for (const arrow of ARROW_CHARS) {
|
|
1544
|
+
if (label.includes(arrow)) {
|
|
1545
|
+
return {
|
|
1546
|
+
error: "Arrow characters (->, ~>) are not allowed inside labels"
|
|
1547
|
+
};
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
return {
|
|
1551
|
+
from: m[1],
|
|
1552
|
+
to: m[3],
|
|
1553
|
+
label,
|
|
1554
|
+
async: isAsync,
|
|
1555
|
+
bidirectional
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
return null;
|
|
1559
|
+
}
|
|
1560
|
+
var BIDI_SYNC_LABELED_RE, BIDI_ASYNC_LABELED_RE, SYNC_LABELED_RE, ASYNC_LABELED_RE, ARROW_CHARS;
|
|
1561
|
+
var init_arrows = __esm({
|
|
1562
|
+
"src/utils/arrows.ts"() {
|
|
1563
|
+
"use strict";
|
|
1564
|
+
BIDI_SYNC_LABELED_RE = /^(\S+)\s+<-(.+)->\s+(\S+)$/;
|
|
1565
|
+
BIDI_ASYNC_LABELED_RE = /^(\S+)\s+<~(.+)~>\s+(\S+)$/;
|
|
1566
|
+
SYNC_LABELED_RE = /^(\S+)\s+-(.+)->\s+(\S+)$/;
|
|
1567
|
+
ASYNC_LABELED_RE = /^(\S+)\s+~(.+)~>\s+(\S+)$/;
|
|
1568
|
+
ARROW_CHARS = ["->", "~>", "<->", "<~>"];
|
|
1569
|
+
}
|
|
1570
|
+
});
|
|
1571
|
+
|
|
1572
|
+
// src/utils/parsing.ts
|
|
1573
|
+
function measureIndent(line7) {
|
|
1574
|
+
let indent = 0;
|
|
1575
|
+
for (const ch of line7) {
|
|
1576
|
+
if (ch === " ") indent++;
|
|
1577
|
+
else if (ch === " ") indent += 4;
|
|
1578
|
+
else break;
|
|
1579
|
+
}
|
|
1580
|
+
return indent;
|
|
1581
|
+
}
|
|
1582
|
+
function extractColor(label, palette) {
|
|
1583
|
+
const m = label.match(COLOR_SUFFIX_RE);
|
|
1584
|
+
if (!m) return { label };
|
|
1585
|
+
const colorName = m[1].trim();
|
|
1586
|
+
return {
|
|
1587
|
+
label: label.substring(0, m.index).trim(),
|
|
1588
|
+
color: resolveColor(colorName, palette)
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
function parsePipeMetadata(segments, aliasMap = /* @__PURE__ */ new Map()) {
|
|
1592
|
+
const metadata = {};
|
|
1593
|
+
for (let j = 1; j < segments.length; j++) {
|
|
1594
|
+
for (const part of segments[j].split(",")) {
|
|
1595
|
+
const trimmedPart = part.trim();
|
|
1596
|
+
if (!trimmedPart) continue;
|
|
1597
|
+
const colonIdx = trimmedPart.indexOf(":");
|
|
1598
|
+
if (colonIdx > 0) {
|
|
1599
|
+
const rawKey = trimmedPart.substring(0, colonIdx).trim().toLowerCase();
|
|
1600
|
+
const key = aliasMap.get(rawKey) ?? rawKey;
|
|
1601
|
+
const value = trimmedPart.substring(colonIdx + 1).trim();
|
|
1602
|
+
metadata[key] = value;
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
return metadata;
|
|
1607
|
+
}
|
|
1608
|
+
var COLOR_SUFFIX_RE, CHART_TYPE_RE, TITLE_RE, OPTION_RE;
|
|
1609
|
+
var init_parsing = __esm({
|
|
1610
|
+
"src/utils/parsing.ts"() {
|
|
1611
|
+
"use strict";
|
|
1612
|
+
init_colors();
|
|
1613
|
+
COLOR_SUFFIX_RE = /\(([^)]+)\)\s*$/;
|
|
1614
|
+
CHART_TYPE_RE = /^chart\s*:\s*(.+)/i;
|
|
1615
|
+
TITLE_RE = /^title\s*:\s*(.+)/i;
|
|
1616
|
+
OPTION_RE = /^([a-z][a-z0-9-]*)\s*:\s*(.+)$/i;
|
|
1617
|
+
}
|
|
1618
|
+
});
|
|
1619
|
+
|
|
1530
1620
|
// src/sequence/parser.ts
|
|
1531
1621
|
var parser_exports = {};
|
|
1532
1622
|
__export(parser_exports, {
|
|
@@ -1568,15 +1658,6 @@ function parseReturnLabel(rawLabel) {
|
|
|
1568
1658
|
}
|
|
1569
1659
|
return { label: rawLabel };
|
|
1570
1660
|
}
|
|
1571
|
-
function measureIndent(line7) {
|
|
1572
|
-
let indent = 0;
|
|
1573
|
-
for (const ch of line7) {
|
|
1574
|
-
if (ch === " ") indent++;
|
|
1575
|
-
else if (ch === " ") indent += 4;
|
|
1576
|
-
else break;
|
|
1577
|
-
}
|
|
1578
|
-
return indent;
|
|
1579
|
-
}
|
|
1580
1661
|
function parseSequenceDgmo(content) {
|
|
1581
1662
|
const result = {
|
|
1582
1663
|
title: null,
|
|
@@ -1798,6 +1879,86 @@ function parseSequenceDgmo(content) {
|
|
|
1798
1879
|
pushError(lineNumber, "Use ~> for async messages: A ~> B: message");
|
|
1799
1880
|
continue;
|
|
1800
1881
|
}
|
|
1882
|
+
const labeledArrow = parseArrow(trimmed);
|
|
1883
|
+
if (labeledArrow && "error" in labeledArrow) {
|
|
1884
|
+
pushError(lineNumber, labeledArrow.error);
|
|
1885
|
+
continue;
|
|
1886
|
+
}
|
|
1887
|
+
if (labeledArrow) {
|
|
1888
|
+
contentStarted = true;
|
|
1889
|
+
const { from, to, label, async: isAsync2, bidirectional } = labeledArrow;
|
|
1890
|
+
lastMsgFrom = from;
|
|
1891
|
+
const msg = {
|
|
1892
|
+
from,
|
|
1893
|
+
to,
|
|
1894
|
+
label,
|
|
1895
|
+
returnLabel: void 0,
|
|
1896
|
+
lineNumber,
|
|
1897
|
+
...isAsync2 ? { async: true } : {},
|
|
1898
|
+
...bidirectional ? { bidirectional: true } : {}
|
|
1899
|
+
};
|
|
1900
|
+
result.messages.push(msg);
|
|
1901
|
+
currentContainer().push(msg);
|
|
1902
|
+
if (!result.participants.some((p) => p.id === from)) {
|
|
1903
|
+
result.participants.push({
|
|
1904
|
+
id: from,
|
|
1905
|
+
label: from,
|
|
1906
|
+
type: inferParticipantType(from),
|
|
1907
|
+
lineNumber
|
|
1908
|
+
});
|
|
1909
|
+
}
|
|
1910
|
+
if (!result.participants.some((p) => p.id === to)) {
|
|
1911
|
+
result.participants.push({
|
|
1912
|
+
id: to,
|
|
1913
|
+
label: to,
|
|
1914
|
+
type: inferParticipantType(to),
|
|
1915
|
+
lineNumber
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
continue;
|
|
1919
|
+
}
|
|
1920
|
+
const bidiSyncMatch = trimmed.match(
|
|
1921
|
+
/^(\S+)\s*<->\s*([^\s:]+)\s*(?::\s*(.+))?$/
|
|
1922
|
+
);
|
|
1923
|
+
const bidiAsyncMatch = trimmed.match(
|
|
1924
|
+
/^(\S+)\s*<~>\s*([^\s:]+)\s*(?::\s*(.+))?$/
|
|
1925
|
+
);
|
|
1926
|
+
const bidiMatch = bidiSyncMatch || bidiAsyncMatch;
|
|
1927
|
+
if (bidiMatch) {
|
|
1928
|
+
contentStarted = true;
|
|
1929
|
+
const from = bidiMatch[1];
|
|
1930
|
+
const to = bidiMatch[2];
|
|
1931
|
+
lastMsgFrom = from;
|
|
1932
|
+
const rawLabel = bidiMatch[3]?.trim() || "";
|
|
1933
|
+
const isBidiAsync = !!bidiAsyncMatch;
|
|
1934
|
+
const msg = {
|
|
1935
|
+
from,
|
|
1936
|
+
to,
|
|
1937
|
+
label: rawLabel,
|
|
1938
|
+
lineNumber,
|
|
1939
|
+
bidirectional: true,
|
|
1940
|
+
...isBidiAsync ? { async: true } : {}
|
|
1941
|
+
};
|
|
1942
|
+
result.messages.push(msg);
|
|
1943
|
+
currentContainer().push(msg);
|
|
1944
|
+
if (!result.participants.some((p) => p.id === from)) {
|
|
1945
|
+
result.participants.push({
|
|
1946
|
+
id: from,
|
|
1947
|
+
label: from,
|
|
1948
|
+
type: inferParticipantType(from),
|
|
1949
|
+
lineNumber
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
1952
|
+
if (!result.participants.some((p) => p.id === to)) {
|
|
1953
|
+
result.participants.push({
|
|
1954
|
+
id: to,
|
|
1955
|
+
label: to,
|
|
1956
|
+
type: inferParticipantType(to),
|
|
1957
|
+
lineNumber
|
|
1958
|
+
});
|
|
1959
|
+
}
|
|
1960
|
+
continue;
|
|
1961
|
+
}
|
|
1801
1962
|
let isAsync = false;
|
|
1802
1963
|
const asyncArrowMatch = trimmed.match(
|
|
1803
1964
|
/^(\S+)\s*~>\s*([^\s:]+)\s*(?::\s*(.+))?$/
|
|
@@ -2035,6 +2196,8 @@ var init_parser = __esm({
|
|
|
2035
2196
|
"use strict";
|
|
2036
2197
|
init_participant_inference();
|
|
2037
2198
|
init_diagnostics();
|
|
2199
|
+
init_arrows();
|
|
2200
|
+
init_parsing();
|
|
2038
2201
|
VALID_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
|
|
2039
2202
|
"service",
|
|
2040
2203
|
"database",
|
|
@@ -2050,7 +2213,7 @@ var init_parser = __esm({
|
|
|
2050
2213
|
POSITION_ONLY_PATTERN = /^(\S+)\s+position\s+(-?\d+)$/i;
|
|
2051
2214
|
GROUP_HEADING_PATTERN = /^##\s+(.+?)(?:\(([^)]+)\))?\s*$/;
|
|
2052
2215
|
SECTION_PATTERN = /^==\s+(.+?)(?:\s*==)?\s*$/;
|
|
2053
|
-
ARROW_PATTERN = /\S+\s*(
|
|
2216
|
+
ARROW_PATTERN = /\S+\s*(?:<->|<~>|->|~>|-\S+->|~\S+~>|<-\S+->|<~\S+~>)\s*\S+/;
|
|
2054
2217
|
ARROW_RETURN_PATTERN = /^(.+?)\s*<-\s*(.+)$/;
|
|
2055
2218
|
UML_RETURN_PATTERN = /^(\w+\([^)]*\))\s*:\s*(.+)$/;
|
|
2056
2219
|
NOTE_SINGLE = /^note(?:\s+(right|left)\s+of\s+(\S+))?\s*:\s*(.+)$/i;
|
|
@@ -2064,27 +2227,9 @@ __export(flowchart_parser_exports, {
|
|
|
2064
2227
|
looksLikeFlowchart: () => looksLikeFlowchart,
|
|
2065
2228
|
parseFlowchart: () => parseFlowchart
|
|
2066
2229
|
});
|
|
2067
|
-
function measureIndent2(line7) {
|
|
2068
|
-
let indent = 0;
|
|
2069
|
-
for (const ch of line7) {
|
|
2070
|
-
if (ch === " ") indent++;
|
|
2071
|
-
else if (ch === " ") indent += 4;
|
|
2072
|
-
else break;
|
|
2073
|
-
}
|
|
2074
|
-
return indent;
|
|
2075
|
-
}
|
|
2076
2230
|
function nodeId(shape, label) {
|
|
2077
2231
|
return `${shape}:${label.toLowerCase().trim()}`;
|
|
2078
2232
|
}
|
|
2079
|
-
function extractColor(label, palette) {
|
|
2080
|
-
const m = label.match(COLOR_SUFFIX_RE);
|
|
2081
|
-
if (!m) return { label };
|
|
2082
|
-
const colorName = m[1].trim();
|
|
2083
|
-
return {
|
|
2084
|
-
label: label.substring(0, m.index).trim(),
|
|
2085
|
-
color: resolveColor(colorName, palette)
|
|
2086
|
-
};
|
|
2087
|
-
}
|
|
2088
2233
|
function parseNodeRef(text, palette) {
|
|
2089
2234
|
const t = text.trim();
|
|
2090
2235
|
if (!t) return null;
|
|
@@ -2199,7 +2344,8 @@ function parseFlowchart(content, palette) {
|
|
|
2199
2344
|
nodes: [],
|
|
2200
2345
|
edges: [],
|
|
2201
2346
|
options: {},
|
|
2202
|
-
diagnostics: []
|
|
2347
|
+
diagnostics: [],
|
|
2348
|
+
error: null
|
|
2203
2349
|
};
|
|
2204
2350
|
const fail = (line7, message) => {
|
|
2205
2351
|
const diag = makeDgmoError(line7, message);
|
|
@@ -2301,7 +2447,7 @@ function parseFlowchart(content, palette) {
|
|
|
2301
2447
|
const raw = lines[i];
|
|
2302
2448
|
const trimmed = raw.trim();
|
|
2303
2449
|
const lineNumber = i + 1;
|
|
2304
|
-
const indent =
|
|
2450
|
+
const indent = measureIndent(raw);
|
|
2305
2451
|
if (!trimmed) continue;
|
|
2306
2452
|
if (trimmed.startsWith("//")) continue;
|
|
2307
2453
|
const groupMatch = trimmed.match(GROUP_HEADING_RE);
|
|
@@ -2378,13 +2524,13 @@ function looksLikeFlowchart(content) {
|
|
|
2378
2524
|
/->[ \t]*[\[(<\/]/.test(content);
|
|
2379
2525
|
return shapeNearArrow;
|
|
2380
2526
|
}
|
|
2381
|
-
var
|
|
2527
|
+
var GROUP_HEADING_RE;
|
|
2382
2528
|
var init_flowchart_parser = __esm({
|
|
2383
2529
|
"src/graph/flowchart-parser.ts"() {
|
|
2384
2530
|
"use strict";
|
|
2385
2531
|
init_colors();
|
|
2386
2532
|
init_diagnostics();
|
|
2387
|
-
|
|
2533
|
+
init_parsing();
|
|
2388
2534
|
GROUP_HEADING_RE = /^##\s+(.+?)(?:\(([^)]+)\))?\s*$/;
|
|
2389
2535
|
}
|
|
2390
2536
|
});
|
|
@@ -2395,15 +2541,6 @@ __export(parser_exports2, {
|
|
|
2395
2541
|
looksLikeClassDiagram: () => looksLikeClassDiagram,
|
|
2396
2542
|
parseClassDiagram: () => parseClassDiagram
|
|
2397
2543
|
});
|
|
2398
|
-
function measureIndent3(line7) {
|
|
2399
|
-
let indent = 0;
|
|
2400
|
-
for (const ch of line7) {
|
|
2401
|
-
if (ch === " ") indent++;
|
|
2402
|
-
else if (ch === " ") indent += 4;
|
|
2403
|
-
else break;
|
|
2404
|
-
}
|
|
2405
|
-
return indent;
|
|
2406
|
-
}
|
|
2407
2544
|
function classId(name) {
|
|
2408
2545
|
return name.toLowerCase().trim();
|
|
2409
2546
|
}
|
|
@@ -2478,7 +2615,8 @@ function parseClassDiagram(content, palette) {
|
|
|
2478
2615
|
classes: [],
|
|
2479
2616
|
relationships: [],
|
|
2480
2617
|
options: {},
|
|
2481
|
-
diagnostics: []
|
|
2618
|
+
diagnostics: [],
|
|
2619
|
+
error: null
|
|
2482
2620
|
};
|
|
2483
2621
|
const fail = (line7, message) => {
|
|
2484
2622
|
const diag = makeDgmoError(line7, message);
|
|
@@ -2507,7 +2645,7 @@ function parseClassDiagram(content, palette) {
|
|
|
2507
2645
|
const raw = lines[i];
|
|
2508
2646
|
const trimmed = raw.trim();
|
|
2509
2647
|
const lineNumber = i + 1;
|
|
2510
|
-
const indent =
|
|
2648
|
+
const indent = measureIndent(raw);
|
|
2511
2649
|
if (!trimmed) {
|
|
2512
2650
|
if (indent === 0) currentClass = null;
|
|
2513
2651
|
continue;
|
|
@@ -2550,23 +2688,6 @@ function parseClassDiagram(content, palette) {
|
|
|
2550
2688
|
}
|
|
2551
2689
|
currentClass = null;
|
|
2552
2690
|
contentStarted = true;
|
|
2553
|
-
const relKeyword = trimmed.match(REL_KEYWORD_RE);
|
|
2554
|
-
if (relKeyword) {
|
|
2555
|
-
const sourceName = relKeyword[1];
|
|
2556
|
-
const keyword = relKeyword[2].toLowerCase();
|
|
2557
|
-
const targetName = relKeyword[3];
|
|
2558
|
-
const label = relKeyword[4]?.trim();
|
|
2559
|
-
getOrCreateClass(sourceName, lineNumber);
|
|
2560
|
-
getOrCreateClass(targetName, lineNumber);
|
|
2561
|
-
result.relationships.push({
|
|
2562
|
-
source: classId(sourceName),
|
|
2563
|
-
target: classId(targetName),
|
|
2564
|
-
type: KEYWORD_TO_TYPE[keyword],
|
|
2565
|
-
...label && { label },
|
|
2566
|
-
lineNumber
|
|
2567
|
-
});
|
|
2568
|
-
continue;
|
|
2569
|
-
}
|
|
2570
2691
|
const relArrow = trimmed.match(REL_ARROW_RE);
|
|
2571
2692
|
if (relArrow) {
|
|
2572
2693
|
const sourceName = relArrow[1];
|
|
@@ -2587,13 +2708,24 @@ function parseClassDiagram(content, palette) {
|
|
|
2587
2708
|
const classDecl = trimmed.match(CLASS_DECL_RE);
|
|
2588
2709
|
if (classDecl) {
|
|
2589
2710
|
const name = classDecl[1];
|
|
2590
|
-
const
|
|
2591
|
-
const
|
|
2711
|
+
const relKeyword = classDecl[2];
|
|
2712
|
+
const parentName = classDecl[3];
|
|
2713
|
+
const modifier = classDecl[4];
|
|
2714
|
+
const colorName = classDecl[5]?.trim();
|
|
2592
2715
|
const color = colorName ? resolveColor(colorName, palette) : void 0;
|
|
2593
2716
|
const node = getOrCreateClass(name, lineNumber);
|
|
2594
2717
|
if (modifier) node.modifier = modifier;
|
|
2595
2718
|
if (color) node.color = color;
|
|
2596
2719
|
node.lineNumber = lineNumber;
|
|
2720
|
+
if (relKeyword && parentName) {
|
|
2721
|
+
getOrCreateClass(parentName, lineNumber);
|
|
2722
|
+
result.relationships.push({
|
|
2723
|
+
source: classId(name),
|
|
2724
|
+
target: classId(parentName),
|
|
2725
|
+
type: relKeyword,
|
|
2726
|
+
lineNumber
|
|
2727
|
+
});
|
|
2728
|
+
}
|
|
2597
2729
|
currentClass = node;
|
|
2598
2730
|
continue;
|
|
2599
2731
|
}
|
|
@@ -2627,14 +2759,15 @@ function looksLikeClassDiagram(content) {
|
|
|
2627
2759
|
const trimmed = line7.trim();
|
|
2628
2760
|
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
2629
2761
|
if (/^(chart|title)\s*:/i.test(trimmed)) continue;
|
|
2630
|
-
const indent =
|
|
2762
|
+
const indent = measureIndent(line7);
|
|
2631
2763
|
if (indent === 0) {
|
|
2632
2764
|
if (/^[A-Z][A-Za-z0-9_]*\s+\[(abstract|interface|enum)\]/i.test(trimmed)) {
|
|
2633
2765
|
hasModifier = true;
|
|
2634
2766
|
hasClassDecl = true;
|
|
2635
2767
|
}
|
|
2636
|
-
if (
|
|
2768
|
+
if (/^[A-Z][A-Za-z0-9_]*\s+(extends|implements)\s+[A-Z]/.test(trimmed)) {
|
|
2637
2769
|
hasRelationship = true;
|
|
2770
|
+
hasClassDecl = true;
|
|
2638
2771
|
}
|
|
2639
2772
|
if (REL_ARROW_RE.test(trimmed)) {
|
|
2640
2773
|
hasRelationship = true;
|
|
@@ -2652,26 +2785,19 @@ function looksLikeClassDiagram(content) {
|
|
|
2652
2785
|
if (hasRelationship && hasClassDecl && hasIndentedMember) return true;
|
|
2653
2786
|
return false;
|
|
2654
2787
|
}
|
|
2655
|
-
var CLASS_DECL_RE,
|
|
2788
|
+
var CLASS_DECL_RE, REL_ARROW_RE, VISIBILITY_RE, STATIC_SUFFIX_RE, METHOD_RE, FIELD_RE, ARROW_TO_TYPE;
|
|
2656
2789
|
var init_parser2 = __esm({
|
|
2657
2790
|
"src/class/parser.ts"() {
|
|
2658
2791
|
"use strict";
|
|
2659
2792
|
init_colors();
|
|
2660
2793
|
init_diagnostics();
|
|
2661
|
-
|
|
2662
|
-
|
|
2794
|
+
init_parsing();
|
|
2795
|
+
CLASS_DECL_RE = /^([A-Z][A-Za-z0-9_]*)(?:\s+(extends|implements)\s+([A-Z][A-Za-z0-9_]*))?(?:\s+\[(abstract|interface|enum)\])?(?:\s+\(([^)]+)\))?\s*$/;
|
|
2663
2796
|
REL_ARROW_RE = /^([A-Z][A-Za-z0-9_]*)\s+(--\|>|\.\.\|>|\*--|o--|\.\.\>|->)\s+([A-Z][A-Za-z0-9_]*)(?:\s*:\s*(.+))?$/;
|
|
2664
2797
|
VISIBILITY_RE = /^([+\-#])\s*/;
|
|
2665
2798
|
STATIC_SUFFIX_RE = /\{static\}\s*$/;
|
|
2666
2799
|
METHOD_RE = /^(.+?)\(([^)]*)\)(?:\s*:\s*(.+))?$/;
|
|
2667
2800
|
FIELD_RE = /^(.+?)\s*:\s*(.+)$/;
|
|
2668
|
-
KEYWORD_TO_TYPE = {
|
|
2669
|
-
extends: "extends",
|
|
2670
|
-
implements: "implements",
|
|
2671
|
-
contains: "composes",
|
|
2672
|
-
has: "aggregates",
|
|
2673
|
-
uses: "depends"
|
|
2674
|
-
};
|
|
2675
2801
|
ARROW_TO_TYPE = {
|
|
2676
2802
|
"--|>": "extends",
|
|
2677
2803
|
"..|>": "implements",
|
|
@@ -2689,22 +2815,14 @@ __export(parser_exports3, {
|
|
|
2689
2815
|
looksLikeERDiagram: () => looksLikeERDiagram,
|
|
2690
2816
|
parseERDiagram: () => parseERDiagram
|
|
2691
2817
|
});
|
|
2692
|
-
function measureIndent4(line7) {
|
|
2693
|
-
let indent = 0;
|
|
2694
|
-
for (const ch of line7) {
|
|
2695
|
-
if (ch === " ") indent++;
|
|
2696
|
-
else if (ch === " ") indent += 4;
|
|
2697
|
-
else break;
|
|
2698
|
-
}
|
|
2699
|
-
return indent;
|
|
2700
|
-
}
|
|
2701
2818
|
function tableId(name) {
|
|
2702
2819
|
return name.toLowerCase().trim();
|
|
2703
2820
|
}
|
|
2704
2821
|
function parseCardSide(token) {
|
|
2705
|
-
|
|
2822
|
+
if (token === "1" || token === "*" || token === "?") return token;
|
|
2823
|
+
return null;
|
|
2706
2824
|
}
|
|
2707
|
-
function parseRelationship(trimmed) {
|
|
2825
|
+
function parseRelationship(trimmed, lineNumber, pushError) {
|
|
2708
2826
|
const sym = trimmed.match(REL_SYMBOLIC_RE);
|
|
2709
2827
|
if (sym) {
|
|
2710
2828
|
const fromCard = parseCardSide(sym[2]);
|
|
@@ -2719,19 +2837,15 @@ function parseRelationship(trimmed) {
|
|
|
2719
2837
|
};
|
|
2720
2838
|
}
|
|
2721
2839
|
}
|
|
2722
|
-
const kw = trimmed.match(
|
|
2840
|
+
const kw = trimmed.match(REL_KEYWORD_RE);
|
|
2723
2841
|
if (kw) {
|
|
2724
|
-
const
|
|
2725
|
-
const
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
to: toCard,
|
|
2732
|
-
label: kw[5]?.trim()
|
|
2733
|
-
};
|
|
2734
|
-
}
|
|
2842
|
+
const fromSym = KEYWORD_TO_SYMBOL[kw[2].toLowerCase()] ?? kw[2];
|
|
2843
|
+
const toSym = KEYWORD_TO_SYMBOL[kw[3].toLowerCase()] ?? kw[3];
|
|
2844
|
+
pushError(
|
|
2845
|
+
lineNumber,
|
|
2846
|
+
`Use symbolic cardinality (1--*, ?--1, *--*) instead of "${kw[2]}-to-${kw[3]}". Example: ${kw[1]} ${fromSym}--${toSym} ${kw[4]}`
|
|
2847
|
+
);
|
|
2848
|
+
return null;
|
|
2735
2849
|
}
|
|
2736
2850
|
return null;
|
|
2737
2851
|
}
|
|
@@ -2751,7 +2865,8 @@ function parseERDiagram(content, palette) {
|
|
|
2751
2865
|
options: {},
|
|
2752
2866
|
tables: [],
|
|
2753
2867
|
relationships: [],
|
|
2754
|
-
diagnostics: []
|
|
2868
|
+
diagnostics: [],
|
|
2869
|
+
error: null
|
|
2755
2870
|
};
|
|
2756
2871
|
const fail = (line7, message) => {
|
|
2757
2872
|
const diag = makeDgmoError(line7, message);
|
|
@@ -2759,6 +2874,11 @@ function parseERDiagram(content, palette) {
|
|
|
2759
2874
|
result.error = formatDgmoError(diag);
|
|
2760
2875
|
return result;
|
|
2761
2876
|
};
|
|
2877
|
+
const pushError = (line7, message) => {
|
|
2878
|
+
const diag = makeDgmoError(line7, message);
|
|
2879
|
+
result.diagnostics.push(diag);
|
|
2880
|
+
if (!result.error) result.error = formatDgmoError(diag);
|
|
2881
|
+
};
|
|
2762
2882
|
const tableMap = /* @__PURE__ */ new Map();
|
|
2763
2883
|
let currentTable = null;
|
|
2764
2884
|
let contentStarted = false;
|
|
@@ -2780,7 +2900,7 @@ function parseERDiagram(content, palette) {
|
|
|
2780
2900
|
const raw = lines[i];
|
|
2781
2901
|
const trimmed = raw.trim();
|
|
2782
2902
|
const lineNumber = i + 1;
|
|
2783
|
-
const indent =
|
|
2903
|
+
const indent = measureIndent(raw);
|
|
2784
2904
|
if (!trimmed) {
|
|
2785
2905
|
if (indent === 0) currentTable = null;
|
|
2786
2906
|
continue;
|
|
@@ -2829,7 +2949,7 @@ function parseERDiagram(content, palette) {
|
|
|
2829
2949
|
}
|
|
2830
2950
|
currentTable = null;
|
|
2831
2951
|
contentStarted = true;
|
|
2832
|
-
const rel = parseRelationship(trimmed);
|
|
2952
|
+
const rel = parseRelationship(trimmed, lineNumber, pushError);
|
|
2833
2953
|
if (rel) {
|
|
2834
2954
|
getOrCreateTable(rel.source, lineNumber);
|
|
2835
2955
|
getOrCreateTable(rel.target, lineNumber);
|
|
@@ -2882,7 +3002,7 @@ function looksLikeERDiagram(content) {
|
|
|
2882
3002
|
const trimmed = line7.trim();
|
|
2883
3003
|
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
2884
3004
|
if (/^(chart|title|notation)\s*:/i.test(trimmed)) continue;
|
|
2885
|
-
const indent =
|
|
3005
|
+
const indent = measureIndent(line7);
|
|
2886
3006
|
if (indent > 0) {
|
|
2887
3007
|
if (/\[(pk|fk)\]/i.test(trimmed)) {
|
|
2888
3008
|
hasConstraint = true;
|
|
@@ -2891,7 +3011,7 @@ function looksLikeERDiagram(content) {
|
|
|
2891
3011
|
if (TABLE_DECL_RE.test(trimmed)) {
|
|
2892
3012
|
hasTableDecl = true;
|
|
2893
3013
|
}
|
|
2894
|
-
if (REL_SYMBOLIC_RE.test(trimmed)
|
|
3014
|
+
if (REL_SYMBOLIC_RE.test(trimmed)) {
|
|
2895
3015
|
hasRelationship = true;
|
|
2896
3016
|
}
|
|
2897
3017
|
}
|
|
@@ -2900,12 +3020,13 @@ function looksLikeERDiagram(content) {
|
|
|
2900
3020
|
if (hasRelationship && hasTableDecl && hasConstraint) return true;
|
|
2901
3021
|
return false;
|
|
2902
3022
|
}
|
|
2903
|
-
var TABLE_DECL_RE, COLUMN_RE, CONSTRAINT_MAP,
|
|
3023
|
+
var TABLE_DECL_RE, COLUMN_RE, CONSTRAINT_MAP, REL_SYMBOLIC_RE, REL_KEYWORD_RE, KEYWORD_TO_SYMBOL;
|
|
2904
3024
|
var init_parser3 = __esm({
|
|
2905
3025
|
"src/er/parser.ts"() {
|
|
2906
3026
|
"use strict";
|
|
2907
3027
|
init_colors();
|
|
2908
3028
|
init_diagnostics();
|
|
3029
|
+
init_parsing();
|
|
2909
3030
|
TABLE_DECL_RE = /^([a-zA-Z_]\w*)(?:\s+\(([^)]+)\))?\s*$/;
|
|
2910
3031
|
COLUMN_RE = /^(\w+)(?:\s*:\s*(\w[\w()]*(?:\s*\[\])?))?(?:\s+\[([^\]]+)\])?\s*$/;
|
|
2911
3032
|
CONSTRAINT_MAP = {
|
|
@@ -2914,16 +3035,13 @@ var init_parser3 = __esm({
|
|
|
2914
3035
|
unique: "unique",
|
|
2915
3036
|
nullable: "nullable"
|
|
2916
3037
|
};
|
|
2917
|
-
|
|
3038
|
+
REL_SYMBOLIC_RE = /^([a-zA-Z_]\w*)\s+([1*?])\s*-{1,2}\s*([1*?])\s+([a-zA-Z_]\w*)(?:\s*:\s*(.+))?$/;
|
|
3039
|
+
REL_KEYWORD_RE = /^([a-zA-Z_]\w*)\s+(one|many|zero)[- ]to[- ](one|many|zero)\s+([a-zA-Z_]\w*)(?:\s*:\s*(.+))?$/i;
|
|
3040
|
+
KEYWORD_TO_SYMBOL = {
|
|
2918
3041
|
one: "1",
|
|
2919
3042
|
many: "*",
|
|
2920
|
-
"1": "1",
|
|
2921
|
-
"*": "*",
|
|
2922
|
-
"?": "?",
|
|
2923
3043
|
zero: "?"
|
|
2924
3044
|
};
|
|
2925
|
-
REL_SYMBOLIC_RE = /^([a-zA-Z_]\w*)\s+([1*?])\s*-{1,2}\s*([1*?])\s+([a-zA-Z_]\w*)(?:\s*:\s*(.+))?$/;
|
|
2926
|
-
REL_KEYWORD_RE2 = /^([a-zA-Z_]\w*)\s+(one|many|zero|1|\*|\?)[- ]to[- ](one|many|zero|1|\*|\?)\s+([a-zA-Z_]\w*)(?:\s*:\s*(.+))?$/i;
|
|
2927
3045
|
}
|
|
2928
3046
|
});
|
|
2929
3047
|
|
|
@@ -2933,7 +3051,8 @@ function parseChart(content, palette) {
|
|
|
2933
3051
|
const result = {
|
|
2934
3052
|
type: "bar",
|
|
2935
3053
|
data: [],
|
|
2936
|
-
diagnostics: []
|
|
3054
|
+
diagnostics: [],
|
|
3055
|
+
error: null
|
|
2937
3056
|
};
|
|
2938
3057
|
const fail = (line7, message) => {
|
|
2939
3058
|
const diag = makeDgmoError(line7, message);
|
|
@@ -2946,7 +3065,7 @@ function parseChart(content, palette) {
|
|
|
2946
3065
|
const lineNumber = i + 1;
|
|
2947
3066
|
if (!trimmed) continue;
|
|
2948
3067
|
if (/^#{2,}\s+/.test(trimmed)) continue;
|
|
2949
|
-
if (trimmed.startsWith("
|
|
3068
|
+
if (trimmed.startsWith("//")) continue;
|
|
2950
3069
|
const colonIndex = trimmed.indexOf(":");
|
|
2951
3070
|
if (colonIndex === -1) continue;
|
|
2952
3071
|
const key = trimmed.substring(0, colonIndex).trim().toLowerCase();
|
|
@@ -3105,7 +3224,8 @@ function parseEChart(content, palette) {
|
|
|
3105
3224
|
const result = {
|
|
3106
3225
|
type: "scatter",
|
|
3107
3226
|
data: [],
|
|
3108
|
-
diagnostics: []
|
|
3227
|
+
diagnostics: [],
|
|
3228
|
+
error: null
|
|
3109
3229
|
};
|
|
3110
3230
|
let currentCategory = "Default";
|
|
3111
3231
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -3125,7 +3245,7 @@ function parseEChart(content, palette) {
|
|
|
3125
3245
|
currentCategory = catName;
|
|
3126
3246
|
continue;
|
|
3127
3247
|
}
|
|
3128
|
-
if (trimmed.startsWith("
|
|
3248
|
+
if (trimmed.startsWith("//")) continue;
|
|
3129
3249
|
const categoryMatch = trimmed.match(/^\[(.+)\]$/);
|
|
3130
3250
|
if (categoryMatch) {
|
|
3131
3251
|
currentCategory = categoryMatch[1].trim();
|
|
@@ -3754,7 +3874,7 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
|
|
|
3754
3874
|
}
|
|
3755
3875
|
},
|
|
3756
3876
|
grid: {
|
|
3757
|
-
left: parsed.ylabel ? "
|
|
3877
|
+
left: parsed.ylabel ? "12%" : "3%",
|
|
3758
3878
|
right: "4%",
|
|
3759
3879
|
bottom: hasCategories ? "15%" : parsed.xlabel ? "10%" : "3%",
|
|
3760
3880
|
top: parsed.title ? "15%" : "5%",
|
|
@@ -4026,17 +4146,26 @@ function resolveAxisLabels(parsed) {
|
|
|
4026
4146
|
yLabel: parsed.ylabel ?? (isHorizontal ? void 0 : parsed.label)
|
|
4027
4147
|
};
|
|
4028
4148
|
}
|
|
4029
|
-
function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacity, label, data) {
|
|
4149
|
+
function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacity, label, data, nameGapOverride) {
|
|
4150
|
+
const defaultGap = type === "value" ? 75 : 40;
|
|
4030
4151
|
return {
|
|
4031
4152
|
type,
|
|
4032
4153
|
...data && { data },
|
|
4033
4154
|
axisLine: { lineStyle: { color: axisLineColor } },
|
|
4034
|
-
axisLabel: {
|
|
4155
|
+
axisLabel: {
|
|
4156
|
+
color: textColor,
|
|
4157
|
+
fontSize: type === "category" && data ? data.length > 10 ? 11 : data.length > 5 ? 12 : 16 : 16,
|
|
4158
|
+
fontFamily: FONT_FAMILY,
|
|
4159
|
+
...type === "category" && {
|
|
4160
|
+
interval: 0,
|
|
4161
|
+
formatter: (value) => value.replace(/([a-z])([A-Z])/g, "$1\n$2").replace(/ /g, "\n")
|
|
4162
|
+
}
|
|
4163
|
+
},
|
|
4035
4164
|
splitLine: { lineStyle: { color: splitLineColor, opacity: gridOpacity } },
|
|
4036
4165
|
...label && {
|
|
4037
4166
|
name: label,
|
|
4038
4167
|
nameLocation: "middle",
|
|
4039
|
-
nameGap:
|
|
4168
|
+
nameGap: nameGapOverride ?? defaultGap,
|
|
4040
4169
|
nameTextStyle: { color: textColor, fontSize: 18, fontFamily: FONT_FAMILY }
|
|
4041
4170
|
}
|
|
4042
4171
|
};
|
|
@@ -4091,7 +4220,8 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOp
|
|
|
4091
4220
|
value: d.value,
|
|
4092
4221
|
itemStyle: { color: d.color ?? colors[i % colors.length] }
|
|
4093
4222
|
}));
|
|
4094
|
-
const
|
|
4223
|
+
const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
|
|
4224
|
+
const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap);
|
|
4095
4225
|
const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
|
|
4096
4226
|
return {
|
|
4097
4227
|
backgroundColor: "transparent",
|
|
@@ -4103,7 +4233,7 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOp
|
|
|
4103
4233
|
axisPointer: { type: "shadow" }
|
|
4104
4234
|
},
|
|
4105
4235
|
grid: {
|
|
4106
|
-
left: yLabel ? "
|
|
4236
|
+
left: yLabel ? "12%" : "3%",
|
|
4107
4237
|
right: "4%",
|
|
4108
4238
|
bottom: xLabel ? "10%" : "3%",
|
|
4109
4239
|
top: parsed.title ? "15%" : "5%",
|
|
@@ -4138,7 +4268,7 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
4138
4268
|
axisPointer: { type: "line" }
|
|
4139
4269
|
},
|
|
4140
4270
|
grid: {
|
|
4141
|
-
left: yLabel ? "
|
|
4271
|
+
left: yLabel ? "12%" : "3%",
|
|
4142
4272
|
right: "4%",
|
|
4143
4273
|
bottom: xLabel ? "10%" : "3%",
|
|
4144
4274
|
top: parsed.title ? "15%" : "5%",
|
|
@@ -4200,7 +4330,7 @@ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor,
|
|
|
4200
4330
|
textStyle: { color: textColor }
|
|
4201
4331
|
},
|
|
4202
4332
|
grid: {
|
|
4203
|
-
left: yLabel ? "
|
|
4333
|
+
left: yLabel ? "12%" : "3%",
|
|
4204
4334
|
right: "4%",
|
|
4205
4335
|
bottom: "15%",
|
|
4206
4336
|
top: parsed.title ? "15%" : "5%",
|
|
@@ -4226,7 +4356,7 @@ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
4226
4356
|
axisPointer: { type: "line" }
|
|
4227
4357
|
},
|
|
4228
4358
|
grid: {
|
|
4229
|
-
left: yLabel ? "
|
|
4359
|
+
left: yLabel ? "12%" : "3%",
|
|
4230
4360
|
right: "4%",
|
|
4231
4361
|
bottom: xLabel ? "10%" : "3%",
|
|
4232
4362
|
top: parsed.title ? "15%" : "5%",
|
|
@@ -4423,7 +4553,8 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
|
|
|
4423
4553
|
}
|
|
4424
4554
|
};
|
|
4425
4555
|
});
|
|
4426
|
-
const
|
|
4556
|
+
const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
|
|
4557
|
+
const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap);
|
|
4427
4558
|
const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
|
|
4428
4559
|
return {
|
|
4429
4560
|
backgroundColor: "transparent",
|
|
@@ -4440,7 +4571,7 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
|
|
|
4440
4571
|
textStyle: { color: textColor }
|
|
4441
4572
|
},
|
|
4442
4573
|
grid: {
|
|
4443
|
-
left: yLabel ? "
|
|
4574
|
+
left: yLabel ? "12%" : "3%",
|
|
4444
4575
|
right: "4%",
|
|
4445
4576
|
bottom: "15%",
|
|
4446
4577
|
top: parsed.title ? "15%" : "5%",
|
|
@@ -4518,35 +4649,51 @@ var init_echarts = __esm({
|
|
|
4518
4649
|
}
|
|
4519
4650
|
});
|
|
4520
4651
|
|
|
4652
|
+
// src/utils/tag-groups.ts
|
|
4653
|
+
function isTagBlockHeading(trimmed) {
|
|
4654
|
+
return TAG_BLOCK_RE.test(trimmed) || GROUP_HEADING_RE2.test(trimmed);
|
|
4655
|
+
}
|
|
4656
|
+
function matchTagBlockHeading(trimmed) {
|
|
4657
|
+
const tagMatch = trimmed.match(TAG_BLOCK_RE);
|
|
4658
|
+
if (tagMatch) {
|
|
4659
|
+
return {
|
|
4660
|
+
name: tagMatch[1].trim(),
|
|
4661
|
+
alias: tagMatch[2] || void 0,
|
|
4662
|
+
colorHint: tagMatch[3] || void 0,
|
|
4663
|
+
deprecated: false
|
|
4664
|
+
};
|
|
4665
|
+
}
|
|
4666
|
+
const groupMatch = trimmed.match(GROUP_HEADING_RE2);
|
|
4667
|
+
if (groupMatch) {
|
|
4668
|
+
return {
|
|
4669
|
+
name: groupMatch[1].trim(),
|
|
4670
|
+
alias: groupMatch[2] || void 0,
|
|
4671
|
+
colorHint: groupMatch[3] || void 0,
|
|
4672
|
+
deprecated: true
|
|
4673
|
+
};
|
|
4674
|
+
}
|
|
4675
|
+
return null;
|
|
4676
|
+
}
|
|
4677
|
+
var TAG_BLOCK_RE, GROUP_HEADING_RE2;
|
|
4678
|
+
var init_tag_groups = __esm({
|
|
4679
|
+
"src/utils/tag-groups.ts"() {
|
|
4680
|
+
"use strict";
|
|
4681
|
+
TAG_BLOCK_RE = /^tag:\s+(.+?)(?:\s+alias\s+(\w+))?(?:\s*\(([^)]+)\))?\s*$/i;
|
|
4682
|
+
GROUP_HEADING_RE2 = /^##\s+(.+?)(?:\s+alias\s+(\w+))?(?:\s*\(([^)]+)\))?\s*$/;
|
|
4683
|
+
}
|
|
4684
|
+
});
|
|
4685
|
+
|
|
4521
4686
|
// src/org/parser.ts
|
|
4522
4687
|
var parser_exports4 = {};
|
|
4523
4688
|
__export(parser_exports4, {
|
|
4524
4689
|
looksLikeOrg: () => looksLikeOrg,
|
|
4525
4690
|
parseOrg: () => parseOrg
|
|
4526
4691
|
});
|
|
4527
|
-
function measureIndent5(line7) {
|
|
4528
|
-
let indent = 0;
|
|
4529
|
-
for (const ch of line7) {
|
|
4530
|
-
if (ch === " ") indent++;
|
|
4531
|
-
else if (ch === " ") indent += 4;
|
|
4532
|
-
else break;
|
|
4533
|
-
}
|
|
4534
|
-
return indent;
|
|
4535
|
-
}
|
|
4536
|
-
function extractColor2(label, palette) {
|
|
4537
|
-
const m = label.match(COLOR_SUFFIX_RE2);
|
|
4538
|
-
if (!m) return { label };
|
|
4539
|
-
const colorName = m[1].trim();
|
|
4540
|
-
return {
|
|
4541
|
-
label: label.substring(0, m.index).trim(),
|
|
4542
|
-
color: resolveColor(colorName, palette)
|
|
4543
|
-
};
|
|
4544
|
-
}
|
|
4545
4692
|
function looksLikeOrg(content) {
|
|
4546
4693
|
for (const line7 of content.split("\n")) {
|
|
4547
4694
|
const trimmed = line7.trim();
|
|
4548
4695
|
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
4549
|
-
if (
|
|
4696
|
+
if (isTagBlockHeading(trimmed)) return true;
|
|
4550
4697
|
}
|
|
4551
4698
|
return false;
|
|
4552
4699
|
}
|
|
@@ -4571,6 +4718,9 @@ function parseOrg(content, palette) {
|
|
|
4571
4718
|
result.diagnostics.push(diag);
|
|
4572
4719
|
if (!result.error) result.error = formatDgmoError(diag);
|
|
4573
4720
|
};
|
|
4721
|
+
const pushWarning = (line7, message) => {
|
|
4722
|
+
result.diagnostics.push(makeDgmoError(line7, message, "warning"));
|
|
4723
|
+
};
|
|
4574
4724
|
if (!content || !content.trim()) {
|
|
4575
4725
|
return fail(0, "No content provided");
|
|
4576
4726
|
}
|
|
@@ -4614,42 +4764,43 @@ function parseOrg(content, palette) {
|
|
|
4614
4764
|
continue;
|
|
4615
4765
|
}
|
|
4616
4766
|
}
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
if (optMatch && !trimmed.startsWith("##")) {
|
|
4620
|
-
const key = optMatch[1].trim().toLowerCase();
|
|
4621
|
-
if (key !== "chart" && key !== "title") {
|
|
4622
|
-
result.options[key] = optMatch[2].trim();
|
|
4623
|
-
continue;
|
|
4624
|
-
}
|
|
4625
|
-
}
|
|
4626
|
-
}
|
|
4627
|
-
const groupMatch = trimmed.match(GROUP_HEADING_RE2);
|
|
4628
|
-
if (groupMatch) {
|
|
4767
|
+
const tagBlockMatch = matchTagBlockHeading(trimmed);
|
|
4768
|
+
if (tagBlockMatch) {
|
|
4629
4769
|
if (contentStarted) {
|
|
4630
|
-
pushError(lineNumber, "Tag groups
|
|
4770
|
+
pushError(lineNumber, "Tag groups must appear before org content");
|
|
4631
4771
|
continue;
|
|
4632
4772
|
}
|
|
4633
|
-
|
|
4634
|
-
|
|
4773
|
+
if (tagBlockMatch.deprecated) {
|
|
4774
|
+
pushWarning(lineNumber, `'## ${tagBlockMatch.name}' is deprecated for tag groups \u2014 use 'tag: ${tagBlockMatch.name}' instead`);
|
|
4775
|
+
}
|
|
4635
4776
|
currentTagGroup = {
|
|
4636
|
-
name:
|
|
4637
|
-
alias,
|
|
4777
|
+
name: tagBlockMatch.name,
|
|
4778
|
+
alias: tagBlockMatch.alias,
|
|
4638
4779
|
entries: [],
|
|
4639
4780
|
lineNumber
|
|
4640
4781
|
};
|
|
4641
|
-
if (alias) {
|
|
4642
|
-
aliasMap.set(alias.toLowerCase(),
|
|
4782
|
+
if (tagBlockMatch.alias) {
|
|
4783
|
+
aliasMap.set(tagBlockMatch.alias.toLowerCase(), tagBlockMatch.name.toLowerCase());
|
|
4643
4784
|
}
|
|
4644
4785
|
result.tagGroups.push(currentTagGroup);
|
|
4645
4786
|
continue;
|
|
4646
4787
|
}
|
|
4788
|
+
if (!contentStarted && !currentTagGroup && measureIndent(line7) === 0) {
|
|
4789
|
+
const optMatch = trimmed.match(OPTION_RE);
|
|
4790
|
+
if (optMatch) {
|
|
4791
|
+
const key = optMatch[1].trim().toLowerCase();
|
|
4792
|
+
if (key !== "chart" && key !== "title") {
|
|
4793
|
+
result.options[key] = optMatch[2].trim();
|
|
4794
|
+
continue;
|
|
4795
|
+
}
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4647
4798
|
if (currentTagGroup && !contentStarted) {
|
|
4648
|
-
const indent2 =
|
|
4799
|
+
const indent2 = measureIndent(line7);
|
|
4649
4800
|
if (indent2 > 0) {
|
|
4650
4801
|
const isDefault = /\bdefault\s*$/.test(trimmed);
|
|
4651
4802
|
const entryText = isDefault ? trimmed.replace(/\s+default\s*$/, "").trim() : trimmed;
|
|
4652
|
-
const { label, color } =
|
|
4803
|
+
const { label, color } = extractColor(entryText, palette);
|
|
4653
4804
|
if (!color) {
|
|
4654
4805
|
pushError(lineNumber, `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`);
|
|
4655
4806
|
continue;
|
|
@@ -4668,12 +4819,12 @@ function parseOrg(content, palette) {
|
|
|
4668
4819
|
}
|
|
4669
4820
|
contentStarted = true;
|
|
4670
4821
|
currentTagGroup = null;
|
|
4671
|
-
const indent =
|
|
4822
|
+
const indent = measureIndent(line7);
|
|
4672
4823
|
const containerMatch = trimmed.match(CONTAINER_RE);
|
|
4673
4824
|
const metadataMatch = trimmed.includes("|") ? null : trimmed.match(METADATA_RE);
|
|
4674
4825
|
if (containerMatch) {
|
|
4675
4826
|
const rawLabel = containerMatch[1].trim();
|
|
4676
|
-
const { label, color } =
|
|
4827
|
+
const { label, color } = extractColor(rawLabel, palette);
|
|
4677
4828
|
containerCounter++;
|
|
4678
4829
|
const node = {
|
|
4679
4830
|
id: `container-${containerCounter}`,
|
|
@@ -4718,24 +4869,8 @@ function parseOrg(content, palette) {
|
|
|
4718
4869
|
function parseNodeLabel(trimmed, _indent, lineNumber, palette, counter, aliasMap = /* @__PURE__ */ new Map()) {
|
|
4719
4870
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
4720
4871
|
let rawLabel = segments[0];
|
|
4721
|
-
const { label, color } =
|
|
4722
|
-
const metadata =
|
|
4723
|
-
const metaParts = [];
|
|
4724
|
-
for (let j = 1; j < segments.length; j++) {
|
|
4725
|
-
for (const part of segments[j].split(",")) {
|
|
4726
|
-
const trimmedPart = part.trim();
|
|
4727
|
-
if (trimmedPart) metaParts.push(trimmedPart);
|
|
4728
|
-
}
|
|
4729
|
-
}
|
|
4730
|
-
for (const part of metaParts) {
|
|
4731
|
-
const colonIdx = part.indexOf(":");
|
|
4732
|
-
if (colonIdx > 0) {
|
|
4733
|
-
const rawKey = part.substring(0, colonIdx).trim().toLowerCase();
|
|
4734
|
-
const key = aliasMap.get(rawKey) ?? rawKey;
|
|
4735
|
-
const value = part.substring(colonIdx + 1).trim();
|
|
4736
|
-
metadata[key] = value;
|
|
4737
|
-
}
|
|
4738
|
-
}
|
|
4872
|
+
const { label, color } = extractColor(rawLabel, palette);
|
|
4873
|
+
const metadata = parsePipeMetadata(segments, aliasMap);
|
|
4739
4874
|
return {
|
|
4740
4875
|
id: `node-${counter}`,
|
|
4741
4876
|
label,
|
|
@@ -4773,19 +4908,15 @@ function findMetadataParent(indent, indentStack) {
|
|
|
4773
4908
|
}
|
|
4774
4909
|
return null;
|
|
4775
4910
|
}
|
|
4776
|
-
var
|
|
4911
|
+
var CONTAINER_RE, METADATA_RE;
|
|
4777
4912
|
var init_parser4 = __esm({
|
|
4778
4913
|
"src/org/parser.ts"() {
|
|
4779
4914
|
"use strict";
|
|
4780
|
-
init_colors();
|
|
4781
4915
|
init_diagnostics();
|
|
4782
|
-
|
|
4783
|
-
|
|
4916
|
+
init_tag_groups();
|
|
4917
|
+
init_parsing();
|
|
4784
4918
|
CONTAINER_RE = /^\[([^\]]+)\]$/;
|
|
4785
4919
|
METADATA_RE = /^([^:]+):\s*(.+)$/;
|
|
4786
|
-
CHART_TYPE_RE = /^chart\s*:\s*(.+)/i;
|
|
4787
|
-
TITLE_RE = /^title\s*:\s*(.+)/i;
|
|
4788
|
-
OPTION_RE = /^([a-z][a-z0-9-]*)\s*:\s*(.+)$/i;
|
|
4789
4920
|
}
|
|
4790
4921
|
});
|
|
4791
4922
|
|
|
@@ -4794,31 +4925,14 @@ var parser_exports5 = {};
|
|
|
4794
4925
|
__export(parser_exports5, {
|
|
4795
4926
|
parseKanban: () => parseKanban
|
|
4796
4927
|
});
|
|
4797
|
-
function measureIndent6(line7) {
|
|
4798
|
-
let indent = 0;
|
|
4799
|
-
for (const ch of line7) {
|
|
4800
|
-
if (ch === " ") indent++;
|
|
4801
|
-
else if (ch === " ") indent += 4;
|
|
4802
|
-
else break;
|
|
4803
|
-
}
|
|
4804
|
-
return indent;
|
|
4805
|
-
}
|
|
4806
|
-
function extractColor3(label, palette) {
|
|
4807
|
-
const m = label.match(COLOR_SUFFIX_RE3);
|
|
4808
|
-
if (!m) return { label };
|
|
4809
|
-
const colorName = m[1].trim();
|
|
4810
|
-
return {
|
|
4811
|
-
label: label.substring(0, m.index).trim(),
|
|
4812
|
-
color: resolveColor(colorName, palette)
|
|
4813
|
-
};
|
|
4814
|
-
}
|
|
4815
4928
|
function parseKanban(content, palette) {
|
|
4816
4929
|
const result = {
|
|
4817
4930
|
type: "kanban",
|
|
4818
4931
|
columns: [],
|
|
4819
4932
|
tagGroups: [],
|
|
4820
4933
|
options: {},
|
|
4821
|
-
diagnostics: []
|
|
4934
|
+
diagnostics: [],
|
|
4935
|
+
error: null
|
|
4822
4936
|
};
|
|
4823
4937
|
const fail = (line7, message) => {
|
|
4824
4938
|
const diag = makeDgmoError(line7, message);
|
|
@@ -4851,7 +4965,7 @@ function parseKanban(content, palette) {
|
|
|
4851
4965
|
}
|
|
4852
4966
|
if (trimmed.startsWith("//")) continue;
|
|
4853
4967
|
if (!contentStarted && !currentTagGroup) {
|
|
4854
|
-
const chartMatch = trimmed.match(
|
|
4968
|
+
const chartMatch = trimmed.match(CHART_TYPE_RE);
|
|
4855
4969
|
if (chartMatch) {
|
|
4856
4970
|
const chartType = chartMatch[1].trim().toLowerCase();
|
|
4857
4971
|
if (chartType !== "kanban") {
|
|
@@ -4875,16 +4989,35 @@ function parseKanban(content, palette) {
|
|
|
4875
4989
|
}
|
|
4876
4990
|
}
|
|
4877
4991
|
if (!contentStarted && !currentTagGroup) {
|
|
4878
|
-
const titleMatch = trimmed.match(
|
|
4992
|
+
const titleMatch = trimmed.match(TITLE_RE);
|
|
4879
4993
|
if (titleMatch) {
|
|
4880
4994
|
result.title = titleMatch[1].trim();
|
|
4881
4995
|
result.titleLineNumber = lineNumber;
|
|
4882
4996
|
continue;
|
|
4883
4997
|
}
|
|
4884
4998
|
}
|
|
4885
|
-
if (!contentStarted
|
|
4886
|
-
const
|
|
4887
|
-
if (
|
|
4999
|
+
if (!contentStarted) {
|
|
5000
|
+
const tagBlockMatch = matchTagBlockHeading(trimmed);
|
|
5001
|
+
if (tagBlockMatch) {
|
|
5002
|
+
if (tagBlockMatch.deprecated) {
|
|
5003
|
+
warn(lineNumber, `'## ${tagBlockMatch.name}' is deprecated for tag groups \u2014 use 'tag: ${tagBlockMatch.name}' instead`);
|
|
5004
|
+
}
|
|
5005
|
+
currentTagGroup = {
|
|
5006
|
+
name: tagBlockMatch.name,
|
|
5007
|
+
alias: tagBlockMatch.alias,
|
|
5008
|
+
entries: [],
|
|
5009
|
+
lineNumber
|
|
5010
|
+
};
|
|
5011
|
+
if (tagBlockMatch.alias) {
|
|
5012
|
+
aliasMap.set(tagBlockMatch.alias.toLowerCase(), tagBlockMatch.name.toLowerCase());
|
|
5013
|
+
}
|
|
5014
|
+
result.tagGroups.push(currentTagGroup);
|
|
5015
|
+
continue;
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
if (!contentStarted && !currentTagGroup && measureIndent(line7) === 0) {
|
|
5019
|
+
const optMatch = trimmed.match(OPTION_RE);
|
|
5020
|
+
if (optMatch && !COLUMN_RE2.test(trimmed)) {
|
|
4888
5021
|
const key = optMatch[1].trim().toLowerCase();
|
|
4889
5022
|
if (key !== "chart" && key !== "title") {
|
|
4890
5023
|
result.options[key] = optMatch[2].trim();
|
|
@@ -4892,28 +5025,12 @@ function parseKanban(content, palette) {
|
|
|
4892
5025
|
}
|
|
4893
5026
|
}
|
|
4894
5027
|
}
|
|
4895
|
-
const groupMatch = trimmed.match(GROUP_HEADING_RE3);
|
|
4896
|
-
if (groupMatch && !contentStarted) {
|
|
4897
|
-
const groupName = groupMatch[1].trim();
|
|
4898
|
-
const alias = groupMatch[2] || void 0;
|
|
4899
|
-
currentTagGroup = {
|
|
4900
|
-
name: groupName,
|
|
4901
|
-
alias,
|
|
4902
|
-
entries: [],
|
|
4903
|
-
lineNumber
|
|
4904
|
-
};
|
|
4905
|
-
if (alias) {
|
|
4906
|
-
aliasMap.set(alias.toLowerCase(), groupName.toLowerCase());
|
|
4907
|
-
}
|
|
4908
|
-
result.tagGroups.push(currentTagGroup);
|
|
4909
|
-
continue;
|
|
4910
|
-
}
|
|
4911
5028
|
if (currentTagGroup && !contentStarted) {
|
|
4912
|
-
const indent2 =
|
|
5029
|
+
const indent2 = measureIndent(line7);
|
|
4913
5030
|
if (indent2 > 0) {
|
|
4914
5031
|
const isDefault = /\bdefault\s*$/.test(trimmed);
|
|
4915
5032
|
const entryText = isDefault ? trimmed.replace(/\s+default\s*$/, "").trim() : trimmed;
|
|
4916
|
-
const { label, color } =
|
|
5033
|
+
const { label, color } = extractColor(entryText, palette);
|
|
4917
5034
|
if (!color) {
|
|
4918
5035
|
warn(
|
|
4919
5036
|
lineNumber,
|
|
@@ -4947,7 +5064,7 @@ function parseKanban(content, palette) {
|
|
|
4947
5064
|
columnCounter++;
|
|
4948
5065
|
const rawColName = columnMatch[1].trim();
|
|
4949
5066
|
const wipStr = columnMatch[2];
|
|
4950
|
-
const { label: colName, color: colColor } =
|
|
5067
|
+
const { label: colName, color: colColor } = extractColor(
|
|
4951
5068
|
rawColName,
|
|
4952
5069
|
palette
|
|
4953
5070
|
);
|
|
@@ -4969,7 +5086,7 @@ function parseKanban(content, palette) {
|
|
|
4969
5086
|
warn(lineNumber, "Card line found before any column");
|
|
4970
5087
|
continue;
|
|
4971
5088
|
}
|
|
4972
|
-
const indent =
|
|
5089
|
+
const indent = measureIndent(line7);
|
|
4973
5090
|
if (indent > 0 && currentCard) {
|
|
4974
5091
|
currentCard.details.push(trimmed);
|
|
4975
5092
|
currentCard.endLineNumber = lineNumber;
|
|
@@ -5034,7 +5151,7 @@ function parseCardLine(trimmed, lineNumber, counter, aliasMap, palette) {
|
|
|
5034
5151
|
} else {
|
|
5035
5152
|
rawTitle = trimmed;
|
|
5036
5153
|
}
|
|
5037
|
-
const { label: title, color } =
|
|
5154
|
+
const { label: title, color } = extractColor(rawTitle, palette);
|
|
5038
5155
|
const tags = {};
|
|
5039
5156
|
if (tagsStr) {
|
|
5040
5157
|
for (const part of tagsStr.split(",")) {
|
|
@@ -5057,18 +5174,14 @@ function parseCardLine(trimmed, lineNumber, counter, aliasMap, palette) {
|
|
|
5057
5174
|
color
|
|
5058
5175
|
};
|
|
5059
5176
|
}
|
|
5060
|
-
var
|
|
5177
|
+
var COLUMN_RE2;
|
|
5061
5178
|
var init_parser5 = __esm({
|
|
5062
5179
|
"src/kanban/parser.ts"() {
|
|
5063
5180
|
"use strict";
|
|
5064
|
-
init_colors();
|
|
5065
5181
|
init_diagnostics();
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
OPTION_RE2 = /^([a-z][a-z0-9-]*)\s*:\s*(.+)$/i;
|
|
5069
|
-
GROUP_HEADING_RE3 = /^##\s+(.+?)(?:\s+alias\s+(\w+))?(?:\s*\(([^)]+)\))?\s*$/;
|
|
5182
|
+
init_tag_groups();
|
|
5183
|
+
init_parsing();
|
|
5070
5184
|
COLUMN_RE2 = /^==\s+(.+?)\s*(?:\[wip:\s*(\d+)\])?\s*==$/;
|
|
5071
|
-
COLOR_SUFFIX_RE3 = /\(([^)]+)\)\s*$/;
|
|
5072
5185
|
}
|
|
5073
5186
|
});
|
|
5074
5187
|
|
|
@@ -5077,24 +5190,6 @@ var parser_exports6 = {};
|
|
|
5077
5190
|
__export(parser_exports6, {
|
|
5078
5191
|
parseC4: () => parseC4
|
|
5079
5192
|
});
|
|
5080
|
-
function measureIndent7(line7) {
|
|
5081
|
-
let indent = 0;
|
|
5082
|
-
for (const ch of line7) {
|
|
5083
|
-
if (ch === " ") indent++;
|
|
5084
|
-
else if (ch === " ") indent += 4;
|
|
5085
|
-
else break;
|
|
5086
|
-
}
|
|
5087
|
-
return indent;
|
|
5088
|
-
}
|
|
5089
|
-
function extractColor4(label, palette) {
|
|
5090
|
-
const m = label.match(COLOR_SUFFIX_RE4);
|
|
5091
|
-
if (!m) return { label };
|
|
5092
|
-
const colorName = m[1].trim();
|
|
5093
|
-
return {
|
|
5094
|
-
label: label.substring(0, m.index).trim(),
|
|
5095
|
-
color: resolveColor(colorName, palette)
|
|
5096
|
-
};
|
|
5097
|
-
}
|
|
5098
5193
|
function participantTypeToC4Shape(pType) {
|
|
5099
5194
|
switch (pType) {
|
|
5100
5195
|
case "database":
|
|
@@ -5151,23 +5246,6 @@ function parseRelationshipBody(body) {
|
|
|
5151
5246
|
}
|
|
5152
5247
|
return { target, label: rest };
|
|
5153
5248
|
}
|
|
5154
|
-
function parsePipeMetadata(segments, aliasMap) {
|
|
5155
|
-
const metadata = {};
|
|
5156
|
-
for (let j = 1; j < segments.length; j++) {
|
|
5157
|
-
for (const part of segments[j].split(",")) {
|
|
5158
|
-
const trimmedPart = part.trim();
|
|
5159
|
-
if (!trimmedPart) continue;
|
|
5160
|
-
const colonIdx = trimmedPart.indexOf(":");
|
|
5161
|
-
if (colonIdx > 0) {
|
|
5162
|
-
const rawKey = trimmedPart.substring(0, colonIdx).trim().toLowerCase();
|
|
5163
|
-
const key = aliasMap.get(rawKey) ?? rawKey;
|
|
5164
|
-
const value = trimmedPart.substring(colonIdx + 1).trim();
|
|
5165
|
-
metadata[key] = value;
|
|
5166
|
-
}
|
|
5167
|
-
}
|
|
5168
|
-
}
|
|
5169
|
-
return metadata;
|
|
5170
|
-
}
|
|
5171
5249
|
function parseC4(content, palette) {
|
|
5172
5250
|
const result = {
|
|
5173
5251
|
title: null,
|
|
@@ -5213,7 +5291,7 @@ function parseC4(content, palette) {
|
|
|
5213
5291
|
}
|
|
5214
5292
|
if (trimmed.startsWith("//")) continue;
|
|
5215
5293
|
if (!contentStarted) {
|
|
5216
|
-
const chartMatch = trimmed.match(
|
|
5294
|
+
const chartMatch = trimmed.match(CHART_TYPE_RE);
|
|
5217
5295
|
if (chartMatch) {
|
|
5218
5296
|
const chartType = chartMatch[1].trim().toLowerCase();
|
|
5219
5297
|
if (chartType !== "c4") {
|
|
@@ -5227,49 +5305,50 @@ function parseC4(content, palette) {
|
|
|
5227
5305
|
}
|
|
5228
5306
|
}
|
|
5229
5307
|
if (!contentStarted) {
|
|
5230
|
-
const titleMatch = trimmed.match(
|
|
5308
|
+
const titleMatch = trimmed.match(TITLE_RE);
|
|
5231
5309
|
if (titleMatch) {
|
|
5232
5310
|
result.title = titleMatch[1].trim();
|
|
5233
5311
|
result.titleLineNumber = lineNumber;
|
|
5234
5312
|
continue;
|
|
5235
5313
|
}
|
|
5236
5314
|
}
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
if (optMatch && !trimmed.startsWith("##")) {
|
|
5240
|
-
const key = optMatch[1].trim().toLowerCase();
|
|
5241
|
-
if (key !== "chart" && key !== "title") {
|
|
5242
|
-
result.options[key] = optMatch[2].trim();
|
|
5243
|
-
continue;
|
|
5244
|
-
}
|
|
5245
|
-
}
|
|
5246
|
-
}
|
|
5247
|
-
const groupMatch = trimmed.match(GROUP_HEADING_RE4);
|
|
5248
|
-
if (groupMatch) {
|
|
5315
|
+
const tagBlockMatch = matchTagBlockHeading(trimmed);
|
|
5316
|
+
if (tagBlockMatch) {
|
|
5249
5317
|
if (contentStarted) {
|
|
5250
|
-
pushError(lineNumber, "Tag groups
|
|
5318
|
+
pushError(lineNumber, "Tag groups must appear before content");
|
|
5251
5319
|
continue;
|
|
5252
5320
|
}
|
|
5253
|
-
|
|
5254
|
-
|
|
5321
|
+
if (tagBlockMatch.deprecated) {
|
|
5322
|
+
pushError(lineNumber, `'## ${tagBlockMatch.name}' is deprecated for tag groups \u2014 use 'tag: ${tagBlockMatch.name}' instead`, "warning");
|
|
5323
|
+
}
|
|
5255
5324
|
currentTagGroup = {
|
|
5256
|
-
name:
|
|
5257
|
-
alias,
|
|
5325
|
+
name: tagBlockMatch.name,
|
|
5326
|
+
alias: tagBlockMatch.alias,
|
|
5258
5327
|
entries: [],
|
|
5259
5328
|
lineNumber
|
|
5260
5329
|
};
|
|
5261
|
-
if (alias) {
|
|
5262
|
-
aliasMap.set(alias.toLowerCase(),
|
|
5330
|
+
if (tagBlockMatch.alias) {
|
|
5331
|
+
aliasMap.set(tagBlockMatch.alias.toLowerCase(), tagBlockMatch.name.toLowerCase());
|
|
5263
5332
|
}
|
|
5264
5333
|
result.tagGroups.push(currentTagGroup);
|
|
5265
5334
|
continue;
|
|
5266
5335
|
}
|
|
5336
|
+
if (!contentStarted && !currentTagGroup && measureIndent(line7) === 0) {
|
|
5337
|
+
const optMatch = trimmed.match(OPTION_RE);
|
|
5338
|
+
if (optMatch) {
|
|
5339
|
+
const key = optMatch[1].trim().toLowerCase();
|
|
5340
|
+
if (key !== "chart" && key !== "title") {
|
|
5341
|
+
result.options[key] = optMatch[2].trim();
|
|
5342
|
+
continue;
|
|
5343
|
+
}
|
|
5344
|
+
}
|
|
5345
|
+
}
|
|
5267
5346
|
if (currentTagGroup && !contentStarted) {
|
|
5268
|
-
const indent2 =
|
|
5347
|
+
const indent2 = measureIndent(line7);
|
|
5269
5348
|
if (indent2 > 0) {
|
|
5270
5349
|
const isDefault = /\bdefault\s*$/.test(trimmed);
|
|
5271
5350
|
const entryText = isDefault ? trimmed.replace(/\s+default\s*$/, "").trim() : trimmed;
|
|
5272
|
-
const { label, color } =
|
|
5351
|
+
const { label, color } = extractColor(entryText, palette);
|
|
5273
5352
|
if (!color) {
|
|
5274
5353
|
pushError(
|
|
5275
5354
|
lineNumber,
|
|
@@ -5294,7 +5373,7 @@ function parseC4(content, palette) {
|
|
|
5294
5373
|
if (!sawChartType) {
|
|
5295
5374
|
return fail(lineNumber, 'Missing "chart: c4" header');
|
|
5296
5375
|
}
|
|
5297
|
-
const indent =
|
|
5376
|
+
const indent = measureIndent(line7);
|
|
5298
5377
|
if (inDeployment) {
|
|
5299
5378
|
while (deployStack.length > 0) {
|
|
5300
5379
|
const top = deployStack[deployStack.length - 1];
|
|
@@ -5389,6 +5468,45 @@ function parseC4(content, palette) {
|
|
|
5389
5468
|
}
|
|
5390
5469
|
continue;
|
|
5391
5470
|
}
|
|
5471
|
+
{
|
|
5472
|
+
const labeledPatterns = [
|
|
5473
|
+
{ re: C4_LABELED_BIDI_SYNC_RE, arrowType: "bidirectional" },
|
|
5474
|
+
{ re: C4_LABELED_BIDI_ASYNC_RE, arrowType: "bidirectional-async" },
|
|
5475
|
+
{ re: C4_LABELED_SYNC_RE, arrowType: "sync" },
|
|
5476
|
+
{ re: C4_LABELED_ASYNC_RE, arrowType: "async" }
|
|
5477
|
+
];
|
|
5478
|
+
let labeledHandled = false;
|
|
5479
|
+
for (const { re, arrowType } of labeledPatterns) {
|
|
5480
|
+
const m = trimmed.match(re);
|
|
5481
|
+
if (!m) continue;
|
|
5482
|
+
const rawLabel = m[1].trim();
|
|
5483
|
+
const targetBody = m[2].trim();
|
|
5484
|
+
if (!rawLabel) break;
|
|
5485
|
+
let label = rawLabel;
|
|
5486
|
+
let technology;
|
|
5487
|
+
const techMatch = rawLabel.match(/\[([^\]]+)\]\s*$/);
|
|
5488
|
+
if (techMatch) {
|
|
5489
|
+
label = rawLabel.substring(0, techMatch.index).trim() || void 0;
|
|
5490
|
+
technology = techMatch[1].trim();
|
|
5491
|
+
}
|
|
5492
|
+
const rel = {
|
|
5493
|
+
target: targetBody,
|
|
5494
|
+
label,
|
|
5495
|
+
technology,
|
|
5496
|
+
arrowType,
|
|
5497
|
+
lineNumber
|
|
5498
|
+
};
|
|
5499
|
+
const parentEntry = findParentElement(indent, stack);
|
|
5500
|
+
if (parentEntry) {
|
|
5501
|
+
parentEntry.element.relationships.push(rel);
|
|
5502
|
+
} else {
|
|
5503
|
+
result.relationships.push(rel);
|
|
5504
|
+
}
|
|
5505
|
+
labeledHandled = true;
|
|
5506
|
+
break;
|
|
5507
|
+
}
|
|
5508
|
+
if (labeledHandled) continue;
|
|
5509
|
+
}
|
|
5392
5510
|
const relMatch = trimmed.match(RELATIONSHIP_RE);
|
|
5393
5511
|
if (relMatch) {
|
|
5394
5512
|
const arrowType = parseArrowType(relMatch[1]);
|
|
@@ -5578,22 +5696,22 @@ function validateDeploymentRefs(result, knownNames, pushWarning) {
|
|
|
5578
5696
|
}
|
|
5579
5697
|
walkDeploy(result.deployment);
|
|
5580
5698
|
}
|
|
5581
|
-
var
|
|
5699
|
+
var CONTAINER_RE2, ELEMENT_RE, IS_A_RE, RELATIONSHIP_RE, C4_LABELED_SYNC_RE, C4_LABELED_ASYNC_RE, C4_LABELED_BIDI_SYNC_RE, C4_LABELED_BIDI_ASYNC_RE, SECTION_HEADER_RE, CONTAINER_REF_RE, METADATA_RE2, VALID_ELEMENT_TYPES, VALID_SHAPES, ALL_CHART_TYPES;
|
|
5582
5700
|
var init_parser6 = __esm({
|
|
5583
5701
|
"src/c4/parser.ts"() {
|
|
5584
5702
|
"use strict";
|
|
5585
|
-
init_colors();
|
|
5586
5703
|
init_diagnostics();
|
|
5704
|
+
init_tag_groups();
|
|
5587
5705
|
init_participant_inference();
|
|
5588
|
-
|
|
5589
|
-
TITLE_RE3 = /^title\s*:\s*(.+)/i;
|
|
5590
|
-
OPTION_RE3 = /^([a-z][a-z0-9-]*)\s*:\s*(.+)$/i;
|
|
5591
|
-
GROUP_HEADING_RE4 = /^##\s+(.+?)(?:\s+alias\s+(\w+))?(?:\s*\(([^)]+)\))?\s*$/;
|
|
5592
|
-
COLOR_SUFFIX_RE4 = /\(([^)]+)\)\s*$/;
|
|
5706
|
+
init_parsing();
|
|
5593
5707
|
CONTAINER_RE2 = /^\[([^\]]+)\]$/;
|
|
5594
5708
|
ELEMENT_RE = /^(person|system|container|component)\s+(.+)$/i;
|
|
5595
5709
|
IS_A_RE = /\s+is\s+a(?:n)?\s+(\w+)\s*$/i;
|
|
5596
5710
|
RELATIONSHIP_RE = /^(<?-?>|<?~?>)\s+(.+)$/;
|
|
5711
|
+
C4_LABELED_SYNC_RE = /^-(.+)->\s+(.+)$/;
|
|
5712
|
+
C4_LABELED_ASYNC_RE = /^~(.+)~>\s+(.+)$/;
|
|
5713
|
+
C4_LABELED_BIDI_SYNC_RE = /^<-(.+)->\s+(.+)$/;
|
|
5714
|
+
C4_LABELED_BIDI_ASYNC_RE = /^<~(.+)~>\s+(.+)$/;
|
|
5597
5715
|
SECTION_HEADER_RE = /^(containers|components|deployment)\s*:\s*$/i;
|
|
5598
5716
|
CONTAINER_REF_RE = /^container\s+(.+)$/i;
|
|
5599
5717
|
METADATA_RE2 = /^([^:]+):\s*(.+)$/;
|
|
@@ -5654,13 +5772,13 @@ function looksLikeInitiativeStatus(content) {
|
|
|
5654
5772
|
let hasIndentedArrow = false;
|
|
5655
5773
|
for (const line7 of lines) {
|
|
5656
5774
|
const trimmed = line7.trim();
|
|
5657
|
-
if (!trimmed || trimmed.startsWith("
|
|
5775
|
+
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
5658
5776
|
if (trimmed.match(/^chart\s*:/i)) continue;
|
|
5659
5777
|
if (trimmed.match(/^title\s*:/i)) continue;
|
|
5660
5778
|
if (trimmed.includes("->")) hasArrow = true;
|
|
5661
5779
|
if (/\|\s*(done|wip|todo|na)\s*$/i.test(trimmed)) hasStatus = true;
|
|
5662
5780
|
const isIndented = line7.length > 0 && line7 !== trimmed && /^\s/.test(line7);
|
|
5663
|
-
if (isIndented && trimmed.startsWith("->")) hasIndentedArrow = true;
|
|
5781
|
+
if (isIndented && (trimmed.startsWith("->") || /^-[^>].*->/.test(trimmed))) hasIndentedArrow = true;
|
|
5664
5782
|
if (hasArrow && hasStatus) return true;
|
|
5665
5783
|
}
|
|
5666
5784
|
return hasIndentedArrow;
|
|
@@ -5684,7 +5802,7 @@ function parseInitiativeStatus(content) {
|
|
|
5684
5802
|
groups: [],
|
|
5685
5803
|
options: {},
|
|
5686
5804
|
diagnostics: [],
|
|
5687
|
-
error:
|
|
5805
|
+
error: null
|
|
5688
5806
|
};
|
|
5689
5807
|
const lines = content.split("\n");
|
|
5690
5808
|
const nodeLabels = /* @__PURE__ */ new Set();
|
|
@@ -5694,7 +5812,7 @@ function parseInitiativeStatus(content) {
|
|
|
5694
5812
|
const lineNum = i + 1;
|
|
5695
5813
|
const raw = lines[i];
|
|
5696
5814
|
const trimmed = raw.trim();
|
|
5697
|
-
if (!trimmed || trimmed.startsWith("
|
|
5815
|
+
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
5698
5816
|
const chartMatch = trimmed.match(/^chart\s*:\s*(.+)/i);
|
|
5699
5817
|
if (chartMatch) {
|
|
5700
5818
|
const chartType = chartMatch[1].trim().toLowerCase();
|
|
@@ -5727,7 +5845,7 @@ function parseInitiativeStatus(content) {
|
|
|
5727
5845
|
}
|
|
5728
5846
|
if (trimmed.includes("->")) {
|
|
5729
5847
|
let edgeText = trimmed;
|
|
5730
|
-
if (trimmed.startsWith("->")) {
|
|
5848
|
+
if (trimmed.startsWith("->") || /^-[^>].*->/.test(trimmed)) {
|
|
5731
5849
|
if (!lastNodeLabel) {
|
|
5732
5850
|
result.diagnostics.push(
|
|
5733
5851
|
makeDgmoError(lineNum, "Indented edge has no preceding node to use as source", "warning")
|
|
@@ -5793,6 +5911,27 @@ function parseNodeLine(trimmed, lineNum, diagnostics) {
|
|
|
5793
5911
|
return { label: trimmed, status: "na", shape: inferParticipantType(trimmed), lineNumber: lineNum };
|
|
5794
5912
|
}
|
|
5795
5913
|
function parseEdgeLine(trimmed, lineNum, diagnostics) {
|
|
5914
|
+
const labeledMatch = trimmed.match(/^(\S+)\s+-(.+)->\s+(.+)$/);
|
|
5915
|
+
if (labeledMatch) {
|
|
5916
|
+
const source2 = labeledMatch[1];
|
|
5917
|
+
const label2 = labeledMatch[2].trim();
|
|
5918
|
+
let targetRest = labeledMatch[3].trim();
|
|
5919
|
+
if (label2) {
|
|
5920
|
+
let status2 = "na";
|
|
5921
|
+
const lastPipe2 = targetRest.lastIndexOf("|");
|
|
5922
|
+
if (lastPipe2 >= 0) {
|
|
5923
|
+
const statusRaw = targetRest.slice(lastPipe2 + 1).trim();
|
|
5924
|
+
status2 = parseStatus(statusRaw, lineNum, diagnostics);
|
|
5925
|
+
targetRest = targetRest.slice(0, lastPipe2).trim();
|
|
5926
|
+
}
|
|
5927
|
+
const target2 = targetRest.trim();
|
|
5928
|
+
if (!target2) {
|
|
5929
|
+
diagnostics.push(makeDgmoError(lineNum, "Edge is missing target"));
|
|
5930
|
+
return null;
|
|
5931
|
+
}
|
|
5932
|
+
return { source: source2, target: target2, label: label2, status: status2, lineNumber: lineNum };
|
|
5933
|
+
}
|
|
5934
|
+
}
|
|
5796
5935
|
const arrowIdx = trimmed.indexOf("->");
|
|
5797
5936
|
if (arrowIdx < 0) return null;
|
|
5798
5937
|
const source = trimmed.slice(0, arrowIdx).trim();
|
|
@@ -5847,7 +5986,7 @@ function parseDgmoChartType(content) {
|
|
|
5847
5986
|
const lines = content.split("\n");
|
|
5848
5987
|
for (const line7 of lines) {
|
|
5849
5988
|
const trimmed = line7.trim();
|
|
5850
|
-
if (!trimmed || trimmed.startsWith("
|
|
5989
|
+
if (!trimmed || trimmed.startsWith("//"))
|
|
5851
5990
|
continue;
|
|
5852
5991
|
const match = trimmed.match(/^chart\s*:\s*(.+)/i);
|
|
5853
5992
|
if (match) return match[1].trim().toLowerCase();
|
|
@@ -7109,6 +7248,58 @@ var init_renderer = __esm({
|
|
|
7109
7248
|
}
|
|
7110
7249
|
});
|
|
7111
7250
|
|
|
7251
|
+
// src/utils/inline-markdown.ts
|
|
7252
|
+
function parseInlineMarkdown(text) {
|
|
7253
|
+
const spans = [];
|
|
7254
|
+
const regex = /\*\*(.+?)\*\*|__(.+?)__|\*(.+?)\*|_(.+?)_|`(.+?)`|\[(.+?)\]\((.+?)\)|(https?:\/\/[^\s)>\]]+|www\.[^\s)>\]]+)|([^*_`[]+?(?=https?:\/\/|www\.|$)|[^*_`[]+)/g;
|
|
7255
|
+
let match;
|
|
7256
|
+
while ((match = regex.exec(text)) !== null) {
|
|
7257
|
+
if (match[1]) spans.push({ text: match[1], bold: true });
|
|
7258
|
+
else if (match[2]) spans.push({ text: match[2], bold: true });
|
|
7259
|
+
else if (match[3]) spans.push({ text: match[3], italic: true });
|
|
7260
|
+
else if (match[4]) spans.push({ text: match[4], italic: true });
|
|
7261
|
+
else if (match[5]) spans.push({ text: match[5], code: true });
|
|
7262
|
+
else if (match[6]) spans.push({ text: match[6], href: match[7] });
|
|
7263
|
+
else if (match[8]) {
|
|
7264
|
+
const url = match[8];
|
|
7265
|
+
const href = url.startsWith("www.") ? `https://${url}` : url;
|
|
7266
|
+
spans.push({ text: url, href });
|
|
7267
|
+
} else if (match[9]) spans.push({ text: match[9] });
|
|
7268
|
+
}
|
|
7269
|
+
return spans;
|
|
7270
|
+
}
|
|
7271
|
+
function truncateBareUrl(url) {
|
|
7272
|
+
const stripped = url.replace(/^https?:\/\//, "").replace(/^www\./, "");
|
|
7273
|
+
if (stripped.length <= BARE_URL_MAX_DISPLAY) return stripped;
|
|
7274
|
+
return stripped.slice(0, BARE_URL_MAX_DISPLAY - 1) + "\u2026";
|
|
7275
|
+
}
|
|
7276
|
+
function renderInlineText(textEl, text, palette, fontSize) {
|
|
7277
|
+
const spans = parseInlineMarkdown(text);
|
|
7278
|
+
for (const span of spans) {
|
|
7279
|
+
if (span.href) {
|
|
7280
|
+
const isBareUrl = span.text === span.href || `https://${span.text}` === span.href;
|
|
7281
|
+
const display = isBareUrl ? truncateBareUrl(span.text) : span.text;
|
|
7282
|
+
const a = textEl.append("a").attr("href", span.href);
|
|
7283
|
+
a.append("tspan").text(display).attr("fill", palette.primary).style("text-decoration", "underline");
|
|
7284
|
+
} else {
|
|
7285
|
+
const tspan = textEl.append("tspan").text(span.text);
|
|
7286
|
+
if (span.bold) tspan.attr("font-weight", "bold");
|
|
7287
|
+
if (span.italic) tspan.attr("font-style", "italic");
|
|
7288
|
+
if (span.code) {
|
|
7289
|
+
tspan.attr("font-family", "monospace");
|
|
7290
|
+
if (fontSize) tspan.attr("font-size", fontSize - 1);
|
|
7291
|
+
}
|
|
7292
|
+
}
|
|
7293
|
+
}
|
|
7294
|
+
}
|
|
7295
|
+
var BARE_URL_MAX_DISPLAY;
|
|
7296
|
+
var init_inline_markdown = __esm({
|
|
7297
|
+
"src/utils/inline-markdown.ts"() {
|
|
7298
|
+
"use strict";
|
|
7299
|
+
BARE_URL_MAX_DISPLAY = 35;
|
|
7300
|
+
}
|
|
7301
|
+
});
|
|
7302
|
+
|
|
7112
7303
|
// src/kanban/mutations.ts
|
|
7113
7304
|
function computeCardMove(content, parsed, cardId, targetColumnId, targetIndex) {
|
|
7114
7305
|
let sourceCard = null;
|
|
@@ -7431,7 +7622,8 @@ function renderKanban(container, parsed, palette, isDark, _onNavigateToLine, exp
|
|
|
7431
7622
|
const cx = colLayout.x + cardLayout.x;
|
|
7432
7623
|
const cy = colLayout.y + cardLayout.y;
|
|
7433
7624
|
cg.append("rect").attr("x", cx).attr("y", cy).attr("width", cardLayout.width).attr("height", cardLayout.height).attr("rx", CARD_RADIUS2).attr("fill", cardFill).attr("stroke", cardStroke).attr("stroke-width", CARD_STROKE_WIDTH);
|
|
7434
|
-
cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", cy + CARD_PADDING_Y + CARD_TITLE_FONT_SIZE).attr("font-size", CARD_TITLE_FONT_SIZE).attr("font-weight", "500").attr("fill", palette.text)
|
|
7625
|
+
const titleEl = cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", cy + CARD_PADDING_Y + CARD_TITLE_FONT_SIZE).attr("font-size", CARD_TITLE_FONT_SIZE).attr("font-weight", "500").attr("fill", palette.text);
|
|
7626
|
+
renderInlineText(titleEl, card.title, palette, CARD_TITLE_FONT_SIZE);
|
|
7435
7627
|
if (hasMeta) {
|
|
7436
7628
|
const separatorY = cy + CARD_HEADER_HEIGHT;
|
|
7437
7629
|
cg.append("line").attr("x1", cx).attr("y1", separatorY).attr("x2", cx + cardLayout.width).attr("y2", separatorY).attr("stroke", cardStroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
|
|
@@ -7443,7 +7635,8 @@ function renderKanban(container, parsed, palette, isDark, _onNavigateToLine, exp
|
|
|
7443
7635
|
metaY += CARD_META_LINE_HEIGHT;
|
|
7444
7636
|
}
|
|
7445
7637
|
for (const detail of card.details) {
|
|
7446
|
-
cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", metaY).attr("font-size", CARD_META_FONT_SIZE).attr("fill", palette.textMuted)
|
|
7638
|
+
const detailEl = cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", metaY).attr("font-size", CARD_META_FONT_SIZE).attr("fill", palette.textMuted);
|
|
7639
|
+
renderInlineText(detailEl, detail, palette, CARD_META_FONT_SIZE);
|
|
7447
7640
|
metaY += CARD_META_LINE_HEIGHT;
|
|
7448
7641
|
}
|
|
7449
7642
|
}
|
|
@@ -7468,6 +7661,7 @@ var init_renderer2 = __esm({
|
|
|
7468
7661
|
"src/kanban/renderer.ts"() {
|
|
7469
7662
|
"use strict";
|
|
7470
7663
|
init_fonts();
|
|
7664
|
+
init_inline_markdown();
|
|
7471
7665
|
init_parser5();
|
|
7472
7666
|
init_mutations();
|
|
7473
7667
|
DIAGRAM_PADDING2 = 20;
|
|
@@ -7525,22 +7719,30 @@ function computeNodeDimensions(node) {
|
|
|
7525
7719
|
}
|
|
7526
7720
|
const width = Math.max(MIN_WIDTH, maxTextLen * CHAR_WIDTH2 + PADDING_X);
|
|
7527
7721
|
const headerHeight = HEADER_BASE + (node.modifier ? MODIFIER_BADGE : 0);
|
|
7528
|
-
let fieldsHeight
|
|
7722
|
+
let fieldsHeight;
|
|
7529
7723
|
if (isEnum) {
|
|
7530
7724
|
const enumValues = node.members;
|
|
7531
7725
|
if (enumValues.length > 0) {
|
|
7532
7726
|
fieldsHeight = COMPARTMENT_PADDING_Y * 2 + enumValues.length * MEMBER_LINE_HEIGHT + SEPARATOR_HEIGHT;
|
|
7727
|
+
} else {
|
|
7728
|
+
fieldsHeight = SEPARATOR_HEIGHT + COMPARTMENT_PADDING_Y;
|
|
7533
7729
|
}
|
|
7534
7730
|
} else {
|
|
7535
7731
|
if (fields.length > 0) {
|
|
7536
7732
|
fieldsHeight = COMPARTMENT_PADDING_Y * 2 + fields.length * MEMBER_LINE_HEIGHT + SEPARATOR_HEIGHT;
|
|
7733
|
+
} else {
|
|
7734
|
+
fieldsHeight = SEPARATOR_HEIGHT + COMPARTMENT_PADDING_Y;
|
|
7537
7735
|
}
|
|
7538
7736
|
}
|
|
7539
7737
|
let methodsHeight = 0;
|
|
7540
|
-
if (!isEnum
|
|
7541
|
-
|
|
7738
|
+
if (!isEnum) {
|
|
7739
|
+
if (methods.length > 0) {
|
|
7740
|
+
methodsHeight = COMPARTMENT_PADDING_Y * 2 + methods.length * MEMBER_LINE_HEIGHT + SEPARATOR_HEIGHT;
|
|
7741
|
+
} else {
|
|
7742
|
+
methodsHeight = SEPARATOR_HEIGHT + COMPARTMENT_PADDING_Y;
|
|
7743
|
+
}
|
|
7542
7744
|
}
|
|
7543
|
-
const height = headerHeight + fieldsHeight + methodsHeight
|
|
7745
|
+
const height = headerHeight + fieldsHeight + methodsHeight;
|
|
7544
7746
|
return { width, height, headerHeight, fieldsHeight, methodsHeight };
|
|
7545
7747
|
}
|
|
7546
7748
|
function layoutClassDiagram(parsed) {
|
|
@@ -7794,17 +7996,15 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
7794
7996
|
const fields = node.members.filter((m) => !m.isMethod);
|
|
7795
7997
|
const methods = node.members.filter((m) => m.isMethod);
|
|
7796
7998
|
if (isEnum) {
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
memberY += MEMBER_LINE_HEIGHT2;
|
|
7803
|
-
}
|
|
7999
|
+
nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
|
|
8000
|
+
let memberY = yPos + COMPARTMENT_PADDING_Y2;
|
|
8001
|
+
for (const member of node.members) {
|
|
8002
|
+
nodeG.append("text").attr("x", -w / 2 + MEMBER_PADDING_X).attr("y", memberY + MEMBER_LINE_HEIGHT2 / 2).attr("dominant-baseline", "central").attr("fill", palette.text).attr("font-size", MEMBER_FONT_SIZE).text(member.name);
|
|
8003
|
+
memberY += MEMBER_LINE_HEIGHT2;
|
|
7804
8004
|
}
|
|
7805
8005
|
} else {
|
|
8006
|
+
nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
|
|
7806
8007
|
if (fields.length > 0) {
|
|
7807
|
-
nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
|
|
7808
8008
|
let memberY = yPos + COMPARTMENT_PADDING_Y2;
|
|
7809
8009
|
for (const field of fields) {
|
|
7810
8010
|
const vis = visibilitySymbol(field.visibility);
|
|
@@ -7817,10 +8017,10 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
7817
8017
|
textEl.text(text);
|
|
7818
8018
|
memberY += MEMBER_LINE_HEIGHT2;
|
|
7819
8019
|
}
|
|
7820
|
-
yPos += node.fieldsHeight;
|
|
7821
8020
|
}
|
|
8021
|
+
yPos += node.fieldsHeight;
|
|
8022
|
+
nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
|
|
7822
8023
|
if (methods.length > 0) {
|
|
7823
|
-
nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
|
|
7824
8024
|
let memberY = yPos + COMPARTMENT_PADDING_Y2;
|
|
7825
8025
|
for (const method of methods) {
|
|
7826
8026
|
const vis = visibilitySymbol(method.visibility);
|
|
@@ -10615,7 +10815,8 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
|
|
|
10615
10815
|
const contentWidth = w - CARD_H_PAD3 * 2;
|
|
10616
10816
|
const lines = wrapText2(node.description, contentWidth, DESC_CHAR_WIDTH2);
|
|
10617
10817
|
for (const line7 of lines) {
|
|
10618
|
-
nodeG.append("text").attr("x", 0).attr("y", yPos + DESC_FONT_SIZE / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.textMuted).attr("font-size", DESC_FONT_SIZE)
|
|
10818
|
+
const textEl = nodeG.append("text").attr("x", 0).attr("y", yPos + DESC_FONT_SIZE / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.textMuted).attr("font-size", DESC_FONT_SIZE);
|
|
10819
|
+
renderInlineText(textEl, line7, palette, DESC_FONT_SIZE);
|
|
10619
10820
|
yPos += DESC_LINE_HEIGHT2;
|
|
10620
10821
|
}
|
|
10621
10822
|
}
|
|
@@ -11101,7 +11302,8 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
|
|
|
11101
11302
|
const contentWidth = w - CARD_H_PAD3 * 2;
|
|
11102
11303
|
const lines = wrapText2(node.description, contentWidth, DESC_CHAR_WIDTH2);
|
|
11103
11304
|
for (const line7 of lines) {
|
|
11104
|
-
nodeG.append("text").attr("x", 0).attr("y", yPos + DESC_FONT_SIZE / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.textMuted).attr("font-size", DESC_FONT_SIZE)
|
|
11305
|
+
const textEl = nodeG.append("text").attr("x", 0).attr("y", yPos + DESC_FONT_SIZE / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.textMuted).attr("font-size", DESC_FONT_SIZE);
|
|
11306
|
+
renderInlineText(textEl, line7, palette, DESC_FONT_SIZE);
|
|
11105
11307
|
yPos += DESC_LINE_HEIGHT2;
|
|
11106
11308
|
}
|
|
11107
11309
|
}
|
|
@@ -11124,7 +11326,8 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
|
|
|
11124
11326
|
const contentWidth = w - CARD_H_PAD3 * 2;
|
|
11125
11327
|
const lines = wrapText2(node.description, contentWidth, DESC_CHAR_WIDTH2);
|
|
11126
11328
|
for (const line7 of lines) {
|
|
11127
|
-
nodeG.append("text").attr("x", 0).attr("y", yPos + DESC_FONT_SIZE / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.textMuted).attr("font-size", DESC_FONT_SIZE)
|
|
11329
|
+
const textEl = nodeG.append("text").attr("x", 0).attr("y", yPos + DESC_FONT_SIZE / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.textMuted).attr("font-size", DESC_FONT_SIZE);
|
|
11330
|
+
renderInlineText(textEl, line7, palette, DESC_FONT_SIZE);
|
|
11128
11331
|
yPos += DESC_LINE_HEIGHT2;
|
|
11129
11332
|
}
|
|
11130
11333
|
}
|
|
@@ -11243,6 +11446,7 @@ var init_renderer6 = __esm({
|
|
|
11243
11446
|
"src/c4/renderer.ts"() {
|
|
11244
11447
|
"use strict";
|
|
11245
11448
|
init_fonts();
|
|
11449
|
+
init_inline_markdown();
|
|
11246
11450
|
init_parser6();
|
|
11247
11451
|
init_layout5();
|
|
11248
11452
|
DIAGRAM_PADDING6 = 20;
|
|
@@ -11741,49 +11945,6 @@ __export(renderer_exports7, {
|
|
|
11741
11945
|
truncateBareUrl: () => truncateBareUrl
|
|
11742
11946
|
});
|
|
11743
11947
|
import * as d3Selection8 from "d3-selection";
|
|
11744
|
-
function parseInlineMarkdown(text) {
|
|
11745
|
-
const spans = [];
|
|
11746
|
-
const regex = /\*\*(.+?)\*\*|__(.+?)__|\*(.+?)\*|_(.+?)_|`(.+?)`|\[(.+?)\]\((.+?)\)|(https?:\/\/[^\s)>\]]+|www\.[^\s)>\]]+)|([^*_`[]+?(?=https?:\/\/|www\.|$)|[^*_`[]+)/g;
|
|
11747
|
-
let match;
|
|
11748
|
-
while ((match = regex.exec(text)) !== null) {
|
|
11749
|
-
if (match[1]) spans.push({ text: match[1], bold: true });
|
|
11750
|
-
else if (match[2]) spans.push({ text: match[2], bold: true });
|
|
11751
|
-
else if (match[3]) spans.push({ text: match[3], italic: true });
|
|
11752
|
-
else if (match[4]) spans.push({ text: match[4], italic: true });
|
|
11753
|
-
else if (match[5]) spans.push({ text: match[5], code: true });
|
|
11754
|
-
else if (match[6]) spans.push({ text: match[6], href: match[7] });
|
|
11755
|
-
else if (match[8]) {
|
|
11756
|
-
const url = match[8];
|
|
11757
|
-
const href = url.startsWith("www.") ? `https://${url}` : url;
|
|
11758
|
-
spans.push({ text: url, href });
|
|
11759
|
-
} else if (match[9]) spans.push({ text: match[9] });
|
|
11760
|
-
}
|
|
11761
|
-
return spans;
|
|
11762
|
-
}
|
|
11763
|
-
function truncateBareUrl(url) {
|
|
11764
|
-
const stripped = url.replace(/^https?:\/\//, "").replace(/^www\./, "");
|
|
11765
|
-
if (stripped.length <= BARE_URL_MAX_DISPLAY) return stripped;
|
|
11766
|
-
return stripped.slice(0, BARE_URL_MAX_DISPLAY - 1) + "\u2026";
|
|
11767
|
-
}
|
|
11768
|
-
function renderInlineText(textEl, text, palette, fontSize) {
|
|
11769
|
-
const spans = parseInlineMarkdown(text);
|
|
11770
|
-
for (const span of spans) {
|
|
11771
|
-
if (span.href) {
|
|
11772
|
-
const isBareUrl = span.text === span.href || `https://${span.text}` === span.href;
|
|
11773
|
-
const display = isBareUrl ? truncateBareUrl(span.text) : span.text;
|
|
11774
|
-
const a = textEl.append("a").attr("href", span.href);
|
|
11775
|
-
a.append("tspan").text(display).attr("fill", palette.primary).style("text-decoration", "underline");
|
|
11776
|
-
} else {
|
|
11777
|
-
const tspan = textEl.append("tspan").text(span.text);
|
|
11778
|
-
if (span.bold) tspan.attr("font-weight", "bold");
|
|
11779
|
-
if (span.italic) tspan.attr("font-style", "italic");
|
|
11780
|
-
if (span.code) {
|
|
11781
|
-
tspan.attr("font-family", "monospace");
|
|
11782
|
-
if (fontSize) tspan.attr("font-size", fontSize - 1);
|
|
11783
|
-
}
|
|
11784
|
-
}
|
|
11785
|
-
}
|
|
11786
|
-
}
|
|
11787
11948
|
function wrapTextLines(text, maxChars) {
|
|
11788
11949
|
const rawLines = text.split("\n");
|
|
11789
11950
|
const wrapped = [];
|
|
@@ -11964,8 +12125,12 @@ function buildRenderSequence(messages) {
|
|
|
11964
12125
|
to: msg.to,
|
|
11965
12126
|
label: msg.label,
|
|
11966
12127
|
messageIndex: mi,
|
|
11967
|
-
...msg.async ? { async: true } : {}
|
|
12128
|
+
...msg.async ? { async: true } : {},
|
|
12129
|
+
...msg.bidirectional ? { bidirectional: true } : {}
|
|
11968
12130
|
});
|
|
12131
|
+
if (msg.bidirectional) {
|
|
12132
|
+
continue;
|
|
12133
|
+
}
|
|
11969
12134
|
if (msg.async) {
|
|
11970
12135
|
continue;
|
|
11971
12136
|
}
|
|
@@ -12457,6 +12622,14 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
12457
12622
|
"points",
|
|
12458
12623
|
`0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`
|
|
12459
12624
|
).attr("fill", "none").attr("stroke", palette.text).attr("stroke-width", 1.2);
|
|
12625
|
+
defs.append("marker").attr("id", "seq-arrowhead-reverse").attr("viewBox", `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`).attr("refX", 0).attr("refY", ARROWHEAD_SIZE / 2).attr("markerWidth", ARROWHEAD_SIZE).attr("markerHeight", ARROWHEAD_SIZE).attr("orient", "auto").append("polygon").attr(
|
|
12626
|
+
"points",
|
|
12627
|
+
`${ARROWHEAD_SIZE},0 0,${ARROWHEAD_SIZE / 2} ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE}`
|
|
12628
|
+
).attr("fill", palette.text);
|
|
12629
|
+
defs.append("marker").attr("id", "seq-arrowhead-async-reverse").attr("viewBox", `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`).attr("refX", 0).attr("refY", ARROWHEAD_SIZE / 2).attr("markerWidth", ARROWHEAD_SIZE).attr("markerHeight", ARROWHEAD_SIZE).attr("orient", "auto").append("polyline").attr(
|
|
12630
|
+
"points",
|
|
12631
|
+
`${ARROWHEAD_SIZE},0 0,${ARROWHEAD_SIZE / 2} ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE}`
|
|
12632
|
+
).attr("fill", "none").attr("stroke", palette.text).attr("stroke-width", 1.2);
|
|
12460
12633
|
if (title) {
|
|
12461
12634
|
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", svgWidth / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 20).attr("font-weight", "bold").text(title);
|
|
12462
12635
|
if (parsed.titleLineNumber) {
|
|
@@ -12737,10 +12910,17 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
12737
12910
|
const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
|
|
12738
12911
|
const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
|
|
12739
12912
|
const markerRef = step.async ? "url(#seq-arrowhead-async)" : "url(#seq-arrowhead)";
|
|
12740
|
-
|
|
12913
|
+
const markerStartRef = step.bidirectional ? step.async ? "url(#seq-arrowhead-async-reverse)" : "url(#seq-arrowhead-reverse)" : null;
|
|
12914
|
+
const line7 = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", palette.text).attr("stroke-width", 1.2).attr("marker-end", markerRef).attr("class", "message-arrow").attr(
|
|
12741
12915
|
"data-line-number",
|
|
12742
12916
|
String(messages[step.messageIndex].lineNumber)
|
|
12743
12917
|
).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
|
|
12918
|
+
if (markerStartRef) {
|
|
12919
|
+
line7.attr("marker-start", markerStartRef);
|
|
12920
|
+
}
|
|
12921
|
+
if (step.bidirectional && step.async) {
|
|
12922
|
+
line7.attr("stroke-dasharray", "6 4");
|
|
12923
|
+
}
|
|
12744
12924
|
if (step.label) {
|
|
12745
12925
|
const midX = (x1 + x2) / 2;
|
|
12746
12926
|
const labelEl = svg.append("text").attr("x", midX).attr("y", y - 8).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 12).attr("class", "message-label").attr(
|
|
@@ -12928,11 +13108,12 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark) {
|
|
|
12928
13108
|
isActor ? PARTICIPANT_BOX_HEIGHT + 14 : PARTICIPANT_BOX_HEIGHT / 2 + 5
|
|
12929
13109
|
).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 13).attr("font-weight", 500).text(participant.label);
|
|
12930
13110
|
}
|
|
12931
|
-
var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT4, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, COLLAPSED_NOTE_H, COLLAPSED_NOTE_W,
|
|
13111
|
+
var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT4, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, COLLAPSED_NOTE_H, COLLAPSED_NOTE_W, fill, stroke, SW, W, H;
|
|
12932
13112
|
var init_renderer7 = __esm({
|
|
12933
13113
|
"src/sequence/renderer.ts"() {
|
|
12934
13114
|
"use strict";
|
|
12935
13115
|
init_colors();
|
|
13116
|
+
init_inline_markdown();
|
|
12936
13117
|
init_fonts();
|
|
12937
13118
|
init_parser();
|
|
12938
13119
|
PARTICIPANT_GAP = 160;
|
|
@@ -12956,7 +13137,6 @@ var init_renderer7 = __esm({
|
|
|
12956
13137
|
NOTE_CHARS_PER_LINE = Math.floor((NOTE_MAX_W - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W);
|
|
12957
13138
|
COLLAPSED_NOTE_H = 20;
|
|
12958
13139
|
COLLAPSED_NOTE_W = 40;
|
|
12959
|
-
BARE_URL_MAX_DISPLAY = 35;
|
|
12960
13140
|
fill = (palette, isDark) => mix8(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
|
|
12961
13141
|
stroke = (palette) => palette.textMuted;
|
|
12962
13142
|
SW = 1.5;
|
|
@@ -13091,7 +13271,7 @@ function parseD3(content, palette) {
|
|
|
13091
13271
|
}
|
|
13092
13272
|
continue;
|
|
13093
13273
|
}
|
|
13094
|
-
if (line7.startsWith("
|
|
13274
|
+
if (line7.startsWith("//")) {
|
|
13095
13275
|
continue;
|
|
13096
13276
|
}
|
|
13097
13277
|
if (result.type === "arc") {
|
|
@@ -16265,7 +16445,7 @@ function parseQuadrant(content) {
|
|
|
16265
16445
|
for (let i = 0; i < lines.length; i++) {
|
|
16266
16446
|
const line7 = lines[i].trim();
|
|
16267
16447
|
const lineNumber = i + 1;
|
|
16268
|
-
if (!line7 || line7.startsWith("
|
|
16448
|
+
if (!line7 || line7.startsWith("//")) continue;
|
|
16269
16449
|
if (/^chart\s*:/i.test(line7)) continue;
|
|
16270
16450
|
const titleMatch = line7.match(/^title\s*:\s*(.+)/i);
|
|
16271
16451
|
if (titleMatch) {
|
|
@@ -16395,6 +16575,7 @@ init_renderer3();
|
|
|
16395
16575
|
init_parser3();
|
|
16396
16576
|
init_layout3();
|
|
16397
16577
|
init_renderer4();
|
|
16578
|
+
init_inline_markdown();
|
|
16398
16579
|
init_parser4();
|
|
16399
16580
|
init_layout();
|
|
16400
16581
|
init_renderer();
|
|
@@ -16411,12 +16592,12 @@ init_collapse();
|
|
|
16411
16592
|
|
|
16412
16593
|
// src/org/resolver.ts
|
|
16413
16594
|
init_diagnostics();
|
|
16595
|
+
init_tag_groups();
|
|
16414
16596
|
var MAX_DEPTH = 10;
|
|
16415
16597
|
var IMPORT_RE = /^(\s+)import:\s+(.+\.dgmo)\s*$/i;
|
|
16416
16598
|
var TAGS_RE = /^tags:\s+(.+\.dgmo)\s*$/i;
|
|
16417
16599
|
var HEADER_RE = /^(chart|title)\s*:/i;
|
|
16418
|
-
var
|
|
16419
|
-
var GROUP_HEADING_RE5 = /^##\s+/;
|
|
16600
|
+
var OPTION_RE2 = /^[a-z][a-z0-9-]*\s*:/i;
|
|
16420
16601
|
function dirname(filePath) {
|
|
16421
16602
|
const last = filePath.lastIndexOf("/");
|
|
16422
16603
|
return last > 0 ? filePath.substring(0, last) : "/";
|
|
@@ -16437,9 +16618,9 @@ function extractTagGroups(lines) {
|
|
|
16437
16618
|
let current = null;
|
|
16438
16619
|
for (const line7 of lines) {
|
|
16439
16620
|
const trimmed = line7.trim();
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
const name =
|
|
16621
|
+
const headingMatch = matchTagBlockHeading(trimmed);
|
|
16622
|
+
if (headingMatch) {
|
|
16623
|
+
const name = headingMatch.name.toLowerCase();
|
|
16443
16624
|
current = { name, lines: [line7] };
|
|
16444
16625
|
blocks.push(current);
|
|
16445
16626
|
} else if (current) {
|
|
@@ -16481,7 +16662,7 @@ function parseFileHeader(lines) {
|
|
|
16481
16662
|
tagsDirective = tagsMatch[1].trim();
|
|
16482
16663
|
continue;
|
|
16483
16664
|
}
|
|
16484
|
-
if (
|
|
16665
|
+
if (OPTION_RE2.test(trimmed) && !isTagBlockHeading(trimmed) && !lines[i].match(/^\s/)) {
|
|
16485
16666
|
const key = trimmed.split(":")[0].trim().toLowerCase();
|
|
16486
16667
|
if (key !== "chart" && key !== "title" && !trimmed.includes("|")) {
|
|
16487
16668
|
continue;
|
|
@@ -16511,7 +16692,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
|
|
|
16511
16692
|
headerLines.push(lines[i]);
|
|
16512
16693
|
continue;
|
|
16513
16694
|
}
|
|
16514
|
-
if (
|
|
16695
|
+
if (isTagBlockHeading(trimmed)) continue;
|
|
16515
16696
|
if (lines[i] !== trimmed) continue;
|
|
16516
16697
|
const tagsMatch = trimmed.match(TAGS_RE);
|
|
16517
16698
|
if (tagsMatch) {
|
|
@@ -16543,7 +16724,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
|
|
|
16543
16724
|
const importMatch = line7.match(IMPORT_RE);
|
|
16544
16725
|
if (!importMatch) {
|
|
16545
16726
|
const trimmed = line7.trim();
|
|
16546
|
-
if (
|
|
16727
|
+
if (isTagBlockHeading(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line7, bodyLines, i)) {
|
|
16547
16728
|
continue;
|
|
16548
16729
|
}
|
|
16549
16730
|
resolvedBodyLines.push(line7);
|
|
@@ -16638,7 +16819,7 @@ function findBodyStart(lines) {
|
|
|
16638
16819
|
if (inTagGroup) inTagGroup = false;
|
|
16639
16820
|
continue;
|
|
16640
16821
|
}
|
|
16641
|
-
if (
|
|
16822
|
+
if (isTagBlockHeading(trimmed)) {
|
|
16642
16823
|
inTagGroup = true;
|
|
16643
16824
|
continue;
|
|
16644
16825
|
}
|
|
@@ -16650,7 +16831,7 @@ function findBodyStart(lines) {
|
|
|
16650
16831
|
}
|
|
16651
16832
|
if (HEADER_RE.test(trimmed)) continue;
|
|
16652
16833
|
if (TAGS_RE.test(trimmed)) continue;
|
|
16653
|
-
if (
|
|
16834
|
+
if (OPTION_RE2.test(trimmed) && !isTagBlockHeading(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
|
|
16654
16835
|
const key = trimmed.split(":")[0].trim().toLowerCase();
|
|
16655
16836
|
if (key !== "chart" && key !== "title") {
|
|
16656
16837
|
continue;
|
|
@@ -16665,7 +16846,7 @@ function isTagGroupEntry(line7, allLines, index) {
|
|
|
16665
16846
|
for (let i = index - 1; i >= 0; i--) {
|
|
16666
16847
|
const prev = allLines[i].trim();
|
|
16667
16848
|
if (prev === "" || prev.startsWith("//")) continue;
|
|
16668
|
-
if (
|
|
16849
|
+
if (isTagBlockHeading(prev)) return true;
|
|
16669
16850
|
if (allLines[i].match(/^\s+/)) continue;
|
|
16670
16851
|
return false;
|
|
16671
16852
|
}
|
|
@@ -16822,6 +17003,7 @@ export {
|
|
|
16822
17003
|
parseERDiagram,
|
|
16823
17004
|
parseFlowchart,
|
|
16824
17005
|
parseInitiativeStatus,
|
|
17006
|
+
parseInlineMarkdown,
|
|
16825
17007
|
parseKanban,
|
|
16826
17008
|
parseOrg,
|
|
16827
17009
|
parseQuadrant,
|
|
@@ -16865,6 +17047,7 @@ export {
|
|
|
16865
17047
|
shade,
|
|
16866
17048
|
solarizedPalette,
|
|
16867
17049
|
tint,
|
|
16868
|
-
tokyoNightPalette
|
|
17050
|
+
tokyoNightPalette,
|
|
17051
|
+
truncateBareUrl
|
|
16869
17052
|
};
|
|
16870
17053
|
//# sourceMappingURL=index.js.map
|