@diagrammo/dgmo 0.2.28 → 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/dist/cli.cjs +361 -921
- package/dist/index.cjs +40 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +40 -47
- package/dist/index.js.map +1 -1
- package/docs/language-reference.md +16 -14
- package/package.json +6 -6
- package/src/class/layout.ts +17 -12
- package/src/class/parser.ts +20 -42
- package/src/class/renderer.ts +44 -46
package/dist/index.cjs
CHANGED
|
@@ -2710,23 +2710,6 @@ function parseClassDiagram(content, palette) {
|
|
|
2710
2710
|
}
|
|
2711
2711
|
currentClass = null;
|
|
2712
2712
|
contentStarted = true;
|
|
2713
|
-
const relKeyword = trimmed.match(REL_KEYWORD_RE);
|
|
2714
|
-
if (relKeyword) {
|
|
2715
|
-
const sourceName = relKeyword[1];
|
|
2716
|
-
const keyword = relKeyword[2].toLowerCase();
|
|
2717
|
-
const targetName = relKeyword[3];
|
|
2718
|
-
const label = relKeyword[4]?.trim();
|
|
2719
|
-
getOrCreateClass(sourceName, lineNumber);
|
|
2720
|
-
getOrCreateClass(targetName, lineNumber);
|
|
2721
|
-
result.relationships.push({
|
|
2722
|
-
source: classId(sourceName),
|
|
2723
|
-
target: classId(targetName),
|
|
2724
|
-
type: KEYWORD_TO_TYPE[keyword],
|
|
2725
|
-
...label && { label },
|
|
2726
|
-
lineNumber
|
|
2727
|
-
});
|
|
2728
|
-
continue;
|
|
2729
|
-
}
|
|
2730
2713
|
const relArrow = trimmed.match(REL_ARROW_RE);
|
|
2731
2714
|
if (relArrow) {
|
|
2732
2715
|
const sourceName = relArrow[1];
|
|
@@ -2747,13 +2730,24 @@ function parseClassDiagram(content, palette) {
|
|
|
2747
2730
|
const classDecl = trimmed.match(CLASS_DECL_RE);
|
|
2748
2731
|
if (classDecl) {
|
|
2749
2732
|
const name = classDecl[1];
|
|
2750
|
-
const
|
|
2751
|
-
const
|
|
2733
|
+
const relKeyword = classDecl[2];
|
|
2734
|
+
const parentName = classDecl[3];
|
|
2735
|
+
const modifier = classDecl[4];
|
|
2736
|
+
const colorName = classDecl[5]?.trim();
|
|
2752
2737
|
const color = colorName ? resolveColor(colorName, palette) : void 0;
|
|
2753
2738
|
const node = getOrCreateClass(name, lineNumber);
|
|
2754
2739
|
if (modifier) node.modifier = modifier;
|
|
2755
2740
|
if (color) node.color = color;
|
|
2756
2741
|
node.lineNumber = lineNumber;
|
|
2742
|
+
if (relKeyword && parentName) {
|
|
2743
|
+
getOrCreateClass(parentName, lineNumber);
|
|
2744
|
+
result.relationships.push({
|
|
2745
|
+
source: classId(name),
|
|
2746
|
+
target: classId(parentName),
|
|
2747
|
+
type: relKeyword,
|
|
2748
|
+
lineNumber
|
|
2749
|
+
});
|
|
2750
|
+
}
|
|
2757
2751
|
currentClass = node;
|
|
2758
2752
|
continue;
|
|
2759
2753
|
}
|
|
@@ -2793,8 +2787,9 @@ function looksLikeClassDiagram(content) {
|
|
|
2793
2787
|
hasModifier = true;
|
|
2794
2788
|
hasClassDecl = true;
|
|
2795
2789
|
}
|
|
2796
|
-
if (
|
|
2790
|
+
if (/^[A-Z][A-Za-z0-9_]*\s+(extends|implements)\s+[A-Z]/.test(trimmed)) {
|
|
2797
2791
|
hasRelationship = true;
|
|
2792
|
+
hasClassDecl = true;
|
|
2798
2793
|
}
|
|
2799
2794
|
if (REL_ARROW_RE.test(trimmed)) {
|
|
2800
2795
|
hasRelationship = true;
|
|
@@ -2812,27 +2807,19 @@ function looksLikeClassDiagram(content) {
|
|
|
2812
2807
|
if (hasRelationship && hasClassDecl && hasIndentedMember) return true;
|
|
2813
2808
|
return false;
|
|
2814
2809
|
}
|
|
2815
|
-
var CLASS_DECL_RE,
|
|
2810
|
+
var CLASS_DECL_RE, REL_ARROW_RE, VISIBILITY_RE, STATIC_SUFFIX_RE, METHOD_RE, FIELD_RE, ARROW_TO_TYPE;
|
|
2816
2811
|
var init_parser2 = __esm({
|
|
2817
2812
|
"src/class/parser.ts"() {
|
|
2818
2813
|
"use strict";
|
|
2819
2814
|
init_colors();
|
|
2820
2815
|
init_diagnostics();
|
|
2821
2816
|
init_parsing();
|
|
2822
|
-
CLASS_DECL_RE = /^([A-Z][A-Za-z0-9_]*)(?:\s+\[(abstract|interface|enum)\])?(?:\s+\(([^)]+)\))?\s*$/;
|
|
2823
|
-
REL_KEYWORD_RE = /^([A-Z][A-Za-z0-9_]*)\s+(extends|implements|contains|has|uses)\s+([A-Z][A-Za-z0-9_]*)(?:\s*:\s*(.+))?$/;
|
|
2817
|
+
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*$/;
|
|
2824
2818
|
REL_ARROW_RE = /^([A-Z][A-Za-z0-9_]*)\s+(--\|>|\.\.\|>|\*--|o--|\.\.\>|->)\s+([A-Z][A-Za-z0-9_]*)(?:\s*:\s*(.+))?$/;
|
|
2825
2819
|
VISIBILITY_RE = /^([+\-#])\s*/;
|
|
2826
2820
|
STATIC_SUFFIX_RE = /\{static\}\s*$/;
|
|
2827
2821
|
METHOD_RE = /^(.+?)\(([^)]*)\)(?:\s*:\s*(.+))?$/;
|
|
2828
2822
|
FIELD_RE = /^(.+?)\s*:\s*(.+)$/;
|
|
2829
|
-
KEYWORD_TO_TYPE = {
|
|
2830
|
-
extends: "extends",
|
|
2831
|
-
implements: "implements",
|
|
2832
|
-
contains: "composes",
|
|
2833
|
-
has: "aggregates",
|
|
2834
|
-
uses: "depends"
|
|
2835
|
-
};
|
|
2836
2823
|
ARROW_TO_TYPE = {
|
|
2837
2824
|
"--|>": "extends",
|
|
2838
2825
|
"..|>": "implements",
|
|
@@ -2872,7 +2859,7 @@ function parseRelationship(trimmed, lineNumber, pushError) {
|
|
|
2872
2859
|
};
|
|
2873
2860
|
}
|
|
2874
2861
|
}
|
|
2875
|
-
const kw = trimmed.match(
|
|
2862
|
+
const kw = trimmed.match(REL_KEYWORD_RE);
|
|
2876
2863
|
if (kw) {
|
|
2877
2864
|
const fromSym = KEYWORD_TO_SYMBOL[kw[2].toLowerCase()] ?? kw[2];
|
|
2878
2865
|
const toSym = KEYWORD_TO_SYMBOL[kw[3].toLowerCase()] ?? kw[3];
|
|
@@ -3055,7 +3042,7 @@ function looksLikeERDiagram(content) {
|
|
|
3055
3042
|
if (hasRelationship && hasTableDecl && hasConstraint) return true;
|
|
3056
3043
|
return false;
|
|
3057
3044
|
}
|
|
3058
|
-
var TABLE_DECL_RE, COLUMN_RE, CONSTRAINT_MAP, REL_SYMBOLIC_RE,
|
|
3045
|
+
var TABLE_DECL_RE, COLUMN_RE, CONSTRAINT_MAP, REL_SYMBOLIC_RE, REL_KEYWORD_RE, KEYWORD_TO_SYMBOL;
|
|
3059
3046
|
var init_parser3 = __esm({
|
|
3060
3047
|
"src/er/parser.ts"() {
|
|
3061
3048
|
"use strict";
|
|
@@ -3071,7 +3058,7 @@ var init_parser3 = __esm({
|
|
|
3071
3058
|
nullable: "nullable"
|
|
3072
3059
|
};
|
|
3073
3060
|
REL_SYMBOLIC_RE = /^([a-zA-Z_]\w*)\s+([1*?])\s*-{1,2}\s*([1*?])\s+([a-zA-Z_]\w*)(?:\s*:\s*(.+))?$/;
|
|
3074
|
-
|
|
3061
|
+
REL_KEYWORD_RE = /^([a-zA-Z_]\w*)\s+(one|many|zero)[- ]to[- ](one|many|zero)\s+([a-zA-Z_]\w*)(?:\s*:\s*(.+))?$/i;
|
|
3075
3062
|
KEYWORD_TO_SYMBOL = {
|
|
3076
3063
|
one: "1",
|
|
3077
3064
|
many: "*",
|
|
@@ -7753,22 +7740,30 @@ function computeNodeDimensions(node) {
|
|
|
7753
7740
|
}
|
|
7754
7741
|
const width = Math.max(MIN_WIDTH, maxTextLen * CHAR_WIDTH2 + PADDING_X);
|
|
7755
7742
|
const headerHeight = HEADER_BASE + (node.modifier ? MODIFIER_BADGE : 0);
|
|
7756
|
-
let fieldsHeight
|
|
7743
|
+
let fieldsHeight;
|
|
7757
7744
|
if (isEnum) {
|
|
7758
7745
|
const enumValues = node.members;
|
|
7759
7746
|
if (enumValues.length > 0) {
|
|
7760
7747
|
fieldsHeight = COMPARTMENT_PADDING_Y * 2 + enumValues.length * MEMBER_LINE_HEIGHT + SEPARATOR_HEIGHT;
|
|
7748
|
+
} else {
|
|
7749
|
+
fieldsHeight = SEPARATOR_HEIGHT + COMPARTMENT_PADDING_Y;
|
|
7761
7750
|
}
|
|
7762
7751
|
} else {
|
|
7763
7752
|
if (fields.length > 0) {
|
|
7764
7753
|
fieldsHeight = COMPARTMENT_PADDING_Y * 2 + fields.length * MEMBER_LINE_HEIGHT + SEPARATOR_HEIGHT;
|
|
7754
|
+
} else {
|
|
7755
|
+
fieldsHeight = SEPARATOR_HEIGHT + COMPARTMENT_PADDING_Y;
|
|
7765
7756
|
}
|
|
7766
7757
|
}
|
|
7767
7758
|
let methodsHeight = 0;
|
|
7768
|
-
if (!isEnum
|
|
7769
|
-
|
|
7759
|
+
if (!isEnum) {
|
|
7760
|
+
if (methods.length > 0) {
|
|
7761
|
+
methodsHeight = COMPARTMENT_PADDING_Y * 2 + methods.length * MEMBER_LINE_HEIGHT + SEPARATOR_HEIGHT;
|
|
7762
|
+
} else {
|
|
7763
|
+
methodsHeight = SEPARATOR_HEIGHT + COMPARTMENT_PADDING_Y;
|
|
7764
|
+
}
|
|
7770
7765
|
}
|
|
7771
|
-
const height = headerHeight + fieldsHeight + methodsHeight
|
|
7766
|
+
const height = headerHeight + fieldsHeight + methodsHeight;
|
|
7772
7767
|
return { width, height, headerHeight, fieldsHeight, methodsHeight };
|
|
7773
7768
|
}
|
|
7774
7769
|
function layoutClassDiagram(parsed) {
|
|
@@ -8021,17 +8016,15 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
8021
8016
|
const fields = node.members.filter((m) => !m.isMethod);
|
|
8022
8017
|
const methods = node.members.filter((m) => m.isMethod);
|
|
8023
8018
|
if (isEnum) {
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
memberY += MEMBER_LINE_HEIGHT2;
|
|
8030
|
-
}
|
|
8019
|
+
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);
|
|
8020
|
+
let memberY = yPos + COMPARTMENT_PADDING_Y2;
|
|
8021
|
+
for (const member of node.members) {
|
|
8022
|
+
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);
|
|
8023
|
+
memberY += MEMBER_LINE_HEIGHT2;
|
|
8031
8024
|
}
|
|
8032
8025
|
} else {
|
|
8026
|
+
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);
|
|
8033
8027
|
if (fields.length > 0) {
|
|
8034
|
-
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);
|
|
8035
8028
|
let memberY = yPos + COMPARTMENT_PADDING_Y2;
|
|
8036
8029
|
for (const field of fields) {
|
|
8037
8030
|
const vis = visibilitySymbol(field.visibility);
|
|
@@ -8044,10 +8037,10 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
8044
8037
|
textEl.text(text);
|
|
8045
8038
|
memberY += MEMBER_LINE_HEIGHT2;
|
|
8046
8039
|
}
|
|
8047
|
-
yPos += node.fieldsHeight;
|
|
8048
8040
|
}
|
|
8041
|
+
yPos += node.fieldsHeight;
|
|
8042
|
+
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);
|
|
8049
8043
|
if (methods.length > 0) {
|
|
8050
|
-
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);
|
|
8051
8044
|
let memberY = yPos + COMPARTMENT_PADDING_Y2;
|
|
8052
8045
|
for (const method of methods) {
|
|
8053
8046
|
const vis = visibilitySymbol(method.visibility);
|