@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.js
CHANGED
|
@@ -2688,23 +2688,6 @@ function parseClassDiagram(content, palette) {
|
|
|
2688
2688
|
}
|
|
2689
2689
|
currentClass = null;
|
|
2690
2690
|
contentStarted = true;
|
|
2691
|
-
const relKeyword = trimmed.match(REL_KEYWORD_RE);
|
|
2692
|
-
if (relKeyword) {
|
|
2693
|
-
const sourceName = relKeyword[1];
|
|
2694
|
-
const keyword = relKeyword[2].toLowerCase();
|
|
2695
|
-
const targetName = relKeyword[3];
|
|
2696
|
-
const label = relKeyword[4]?.trim();
|
|
2697
|
-
getOrCreateClass(sourceName, lineNumber);
|
|
2698
|
-
getOrCreateClass(targetName, lineNumber);
|
|
2699
|
-
result.relationships.push({
|
|
2700
|
-
source: classId(sourceName),
|
|
2701
|
-
target: classId(targetName),
|
|
2702
|
-
type: KEYWORD_TO_TYPE[keyword],
|
|
2703
|
-
...label && { label },
|
|
2704
|
-
lineNumber
|
|
2705
|
-
});
|
|
2706
|
-
continue;
|
|
2707
|
-
}
|
|
2708
2691
|
const relArrow = trimmed.match(REL_ARROW_RE);
|
|
2709
2692
|
if (relArrow) {
|
|
2710
2693
|
const sourceName = relArrow[1];
|
|
@@ -2725,13 +2708,24 @@ function parseClassDiagram(content, palette) {
|
|
|
2725
2708
|
const classDecl = trimmed.match(CLASS_DECL_RE);
|
|
2726
2709
|
if (classDecl) {
|
|
2727
2710
|
const name = classDecl[1];
|
|
2728
|
-
const
|
|
2729
|
-
const
|
|
2711
|
+
const relKeyword = classDecl[2];
|
|
2712
|
+
const parentName = classDecl[3];
|
|
2713
|
+
const modifier = classDecl[4];
|
|
2714
|
+
const colorName = classDecl[5]?.trim();
|
|
2730
2715
|
const color = colorName ? resolveColor(colorName, palette) : void 0;
|
|
2731
2716
|
const node = getOrCreateClass(name, lineNumber);
|
|
2732
2717
|
if (modifier) node.modifier = modifier;
|
|
2733
2718
|
if (color) node.color = color;
|
|
2734
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
|
+
}
|
|
2735
2729
|
currentClass = node;
|
|
2736
2730
|
continue;
|
|
2737
2731
|
}
|
|
@@ -2771,8 +2765,9 @@ function looksLikeClassDiagram(content) {
|
|
|
2771
2765
|
hasModifier = true;
|
|
2772
2766
|
hasClassDecl = true;
|
|
2773
2767
|
}
|
|
2774
|
-
if (
|
|
2768
|
+
if (/^[A-Z][A-Za-z0-9_]*\s+(extends|implements)\s+[A-Z]/.test(trimmed)) {
|
|
2775
2769
|
hasRelationship = true;
|
|
2770
|
+
hasClassDecl = true;
|
|
2776
2771
|
}
|
|
2777
2772
|
if (REL_ARROW_RE.test(trimmed)) {
|
|
2778
2773
|
hasRelationship = true;
|
|
@@ -2790,27 +2785,19 @@ function looksLikeClassDiagram(content) {
|
|
|
2790
2785
|
if (hasRelationship && hasClassDecl && hasIndentedMember) return true;
|
|
2791
2786
|
return false;
|
|
2792
2787
|
}
|
|
2793
|
-
var CLASS_DECL_RE,
|
|
2788
|
+
var CLASS_DECL_RE, REL_ARROW_RE, VISIBILITY_RE, STATIC_SUFFIX_RE, METHOD_RE, FIELD_RE, ARROW_TO_TYPE;
|
|
2794
2789
|
var init_parser2 = __esm({
|
|
2795
2790
|
"src/class/parser.ts"() {
|
|
2796
2791
|
"use strict";
|
|
2797
2792
|
init_colors();
|
|
2798
2793
|
init_diagnostics();
|
|
2799
2794
|
init_parsing();
|
|
2800
|
-
CLASS_DECL_RE = /^([A-Z][A-Za-z0-9_]*)(?:\s+\[(abstract|interface|enum)\])?(?:\s+\(([^)]+)\))?\s*$/;
|
|
2801
|
-
REL_KEYWORD_RE = /^([A-Z][A-Za-z0-9_]*)\s+(extends|implements|contains|has|uses)\s+([A-Z][A-Za-z0-9_]*)(?:\s*:\s*(.+))?$/;
|
|
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*$/;
|
|
2802
2796
|
REL_ARROW_RE = /^([A-Z][A-Za-z0-9_]*)\s+(--\|>|\.\.\|>|\*--|o--|\.\.\>|->)\s+([A-Z][A-Za-z0-9_]*)(?:\s*:\s*(.+))?$/;
|
|
2803
2797
|
VISIBILITY_RE = /^([+\-#])\s*/;
|
|
2804
2798
|
STATIC_SUFFIX_RE = /\{static\}\s*$/;
|
|
2805
2799
|
METHOD_RE = /^(.+?)\(([^)]*)\)(?:\s*:\s*(.+))?$/;
|
|
2806
2800
|
FIELD_RE = /^(.+?)\s*:\s*(.+)$/;
|
|
2807
|
-
KEYWORD_TO_TYPE = {
|
|
2808
|
-
extends: "extends",
|
|
2809
|
-
implements: "implements",
|
|
2810
|
-
contains: "composes",
|
|
2811
|
-
has: "aggregates",
|
|
2812
|
-
uses: "depends"
|
|
2813
|
-
};
|
|
2814
2801
|
ARROW_TO_TYPE = {
|
|
2815
2802
|
"--|>": "extends",
|
|
2816
2803
|
"..|>": "implements",
|
|
@@ -2850,7 +2837,7 @@ function parseRelationship(trimmed, lineNumber, pushError) {
|
|
|
2850
2837
|
};
|
|
2851
2838
|
}
|
|
2852
2839
|
}
|
|
2853
|
-
const kw = trimmed.match(
|
|
2840
|
+
const kw = trimmed.match(REL_KEYWORD_RE);
|
|
2854
2841
|
if (kw) {
|
|
2855
2842
|
const fromSym = KEYWORD_TO_SYMBOL[kw[2].toLowerCase()] ?? kw[2];
|
|
2856
2843
|
const toSym = KEYWORD_TO_SYMBOL[kw[3].toLowerCase()] ?? kw[3];
|
|
@@ -3033,7 +3020,7 @@ function looksLikeERDiagram(content) {
|
|
|
3033
3020
|
if (hasRelationship && hasTableDecl && hasConstraint) return true;
|
|
3034
3021
|
return false;
|
|
3035
3022
|
}
|
|
3036
|
-
var TABLE_DECL_RE, COLUMN_RE, CONSTRAINT_MAP, REL_SYMBOLIC_RE,
|
|
3023
|
+
var TABLE_DECL_RE, COLUMN_RE, CONSTRAINT_MAP, REL_SYMBOLIC_RE, REL_KEYWORD_RE, KEYWORD_TO_SYMBOL;
|
|
3037
3024
|
var init_parser3 = __esm({
|
|
3038
3025
|
"src/er/parser.ts"() {
|
|
3039
3026
|
"use strict";
|
|
@@ -3049,7 +3036,7 @@ var init_parser3 = __esm({
|
|
|
3049
3036
|
nullable: "nullable"
|
|
3050
3037
|
};
|
|
3051
3038
|
REL_SYMBOLIC_RE = /^([a-zA-Z_]\w*)\s+([1*?])\s*-{1,2}\s*([1*?])\s+([a-zA-Z_]\w*)(?:\s*:\s*(.+))?$/;
|
|
3052
|
-
|
|
3039
|
+
REL_KEYWORD_RE = /^([a-zA-Z_]\w*)\s+(one|many|zero)[- ]to[- ](one|many|zero)\s+([a-zA-Z_]\w*)(?:\s*:\s*(.+))?$/i;
|
|
3053
3040
|
KEYWORD_TO_SYMBOL = {
|
|
3054
3041
|
one: "1",
|
|
3055
3042
|
many: "*",
|
|
@@ -7732,22 +7719,30 @@ function computeNodeDimensions(node) {
|
|
|
7732
7719
|
}
|
|
7733
7720
|
const width = Math.max(MIN_WIDTH, maxTextLen * CHAR_WIDTH2 + PADDING_X);
|
|
7734
7721
|
const headerHeight = HEADER_BASE + (node.modifier ? MODIFIER_BADGE : 0);
|
|
7735
|
-
let fieldsHeight
|
|
7722
|
+
let fieldsHeight;
|
|
7736
7723
|
if (isEnum) {
|
|
7737
7724
|
const enumValues = node.members;
|
|
7738
7725
|
if (enumValues.length > 0) {
|
|
7739
7726
|
fieldsHeight = COMPARTMENT_PADDING_Y * 2 + enumValues.length * MEMBER_LINE_HEIGHT + SEPARATOR_HEIGHT;
|
|
7727
|
+
} else {
|
|
7728
|
+
fieldsHeight = SEPARATOR_HEIGHT + COMPARTMENT_PADDING_Y;
|
|
7740
7729
|
}
|
|
7741
7730
|
} else {
|
|
7742
7731
|
if (fields.length > 0) {
|
|
7743
7732
|
fieldsHeight = COMPARTMENT_PADDING_Y * 2 + fields.length * MEMBER_LINE_HEIGHT + SEPARATOR_HEIGHT;
|
|
7733
|
+
} else {
|
|
7734
|
+
fieldsHeight = SEPARATOR_HEIGHT + COMPARTMENT_PADDING_Y;
|
|
7744
7735
|
}
|
|
7745
7736
|
}
|
|
7746
7737
|
let methodsHeight = 0;
|
|
7747
|
-
if (!isEnum
|
|
7748
|
-
|
|
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
|
+
}
|
|
7749
7744
|
}
|
|
7750
|
-
const height = headerHeight + fieldsHeight + methodsHeight
|
|
7745
|
+
const height = headerHeight + fieldsHeight + methodsHeight;
|
|
7751
7746
|
return { width, height, headerHeight, fieldsHeight, methodsHeight };
|
|
7752
7747
|
}
|
|
7753
7748
|
function layoutClassDiagram(parsed) {
|
|
@@ -8001,17 +7996,15 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
8001
7996
|
const fields = node.members.filter((m) => !m.isMethod);
|
|
8002
7997
|
const methods = node.members.filter((m) => m.isMethod);
|
|
8003
7998
|
if (isEnum) {
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
memberY += MEMBER_LINE_HEIGHT2;
|
|
8010
|
-
}
|
|
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;
|
|
8011
8004
|
}
|
|
8012
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);
|
|
8013
8007
|
if (fields.length > 0) {
|
|
8014
|
-
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);
|
|
8015
8008
|
let memberY = yPos + COMPARTMENT_PADDING_Y2;
|
|
8016
8009
|
for (const field of fields) {
|
|
8017
8010
|
const vis = visibilitySymbol(field.visibility);
|
|
@@ -8024,10 +8017,10 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
8024
8017
|
textEl.text(text);
|
|
8025
8018
|
memberY += MEMBER_LINE_HEIGHT2;
|
|
8026
8019
|
}
|
|
8027
|
-
yPos += node.fieldsHeight;
|
|
8028
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);
|
|
8029
8023
|
if (methods.length > 0) {
|
|
8030
|
-
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);
|
|
8031
8024
|
let memberY = yPos + COMPARTMENT_PADDING_Y2;
|
|
8032
8025
|
for (const method of methods) {
|
|
8033
8026
|
const vis = visibilitySymbol(method.visibility);
|