Skip to content

Commit 34f1faf

Browse files
committed
Add support for Object Nodes
Fixes: jaime-olivares#65
1 parent 334d722 commit 34f1faf

File tree

3 files changed

+92
-28
lines changed

3 files changed

+92
-28
lines changed

src/diagrams/activity-diagram.mjs

+37-28
Original file line numberDiff line numberDiff line change
@@ -22,48 +22,57 @@ Decisions (start)-><d1>
2222
Decisions w/Label (start)-><d1>logged in->(Show Dashboard), <d1>not logged in->(Show Login Page)
2323
Parallel (Action1)->|a|,(Action 2)->|a|
2424
Note (Action1)-(note: A note message here)
25+
Object Node [Object]
2526
Comment // Comments
2627
*/
2728

28-
function parseYumlExpr(specLine) {
29-
const exprs = [];
30-
const parts = splitYumlExpr(specLine, "(<|");
29+
function* parseYumlExpr(specLine) {
30+
const parts = splitYumlExpr(specLine, "[(<|");
31+
32+
// yUML syntax allows any character in decision labels.
33+
// The following variable serves as flag to avoid parsing
34+
// brackets characters inside labels.
35+
let isDecisionLabel = false;
36+
let decisionLabelBuffer = "";
3137

3238
for (const part of parts) {
33-
if (/^\(.*\)$/.test(part)) {
39+
if (/->$/.test(part)) {
40+
// arrow
41+
const fullLabel = decisionLabelBuffer + part.substr(0, part.length - 2).trim();
42+
isDecisionLabel = false;
43+
decisionLabelBuffer = "";
44+
yield ["edge", "none", "vee", fullLabel, "solid"];
45+
} else if (isDecisionLabel) {
46+
// decision label parts
47+
decisionLabelBuffer += part;
48+
} else if (/^\(.*\)$/.test(part)) {
3449
// activity
3550
const ret = extractBgAndNote(
3651
part.substr(1, part.length - 2).trim(),
3752
true
3853
);
39-
exprs.push([
54+
yield [
4055
ret.isNote ? "note" : "record",
4156
ret.part,
57+
"rounded",
4258
ret.bg,
4359
ret.fontcolor,
44-
]);
60+
];
4561
} else if (/^<.*>$/.test(part)) {
4662
// decision
47-
exprs.push(["diamond", part.substr(1, part.length - 2).trim()]);
63+
isDecisionLabel = true;
64+
yield ["diamond", part.substr(1, part.length - 2).trim()];
65+
} else if (/^\[.*\]$/.test(part)) {
66+
// object node
67+
yield ["record", part.substr(1, part.length - 2).trim()];
4868
} else if (/^\|.*\|$/.test(part)) {
4969
// bar
50-
exprs.push(["mrecord", part.substr(1, part.length - 2).trim()]);
51-
} else if (/->$/.test(part)) {
52-
// arrow
53-
exprs.push([
54-
"edge",
55-
"none",
56-
"vee",
57-
part.substr(0, part.length - 2).trim(),
58-
"solid",
59-
]);
70+
yield ["mrecord", part.substr(1, part.length - 2).trim()];
6071
} else if (part === "-") {
6172
// connector for notes
62-
exprs.push(["edge", "none", "none", "", "solid"]);
63-
} else throw new Error("Invalid expression");
73+
yield ["edge", "none", "none", "", "solid"];
74+
} else throw new Error(`Invalid expression: "${part}"`);
6475
}
65-
66-
return exprs;
6776
}
6877

6978
function composeDotExpr(specLines, options) {
@@ -72,11 +81,10 @@ function composeDotExpr(specLines, options) {
7281
const elements = [];
7382

7483
for (const line of specLines) {
75-
const parsedYumlExpr = parseYumlExpr(line);
76-
const parsedYumlExprLastIndex = parsedYumlExpr.length - 1;
84+
const parsedYumlExpr = Array.from(parseYumlExpr(line));
7785

7886
for (const elem of parsedYumlExpr) {
79-
const [shape, label] = elem;
87+
const [shape, label, style] = elem;
8088

8189
if (shape === "note" || shape === "record") {
8290
const uid = uidHandler.createUid(label);
@@ -97,18 +105,18 @@ function composeDotExpr(specLines, options) {
97105
fontsize: 10,
98106
margin: "0.20,0.05",
99107
label: escape_label(label),
100-
style: "rounded",
108+
style,
101109
};
102110

103-
if (elem[2]) {
104-
const color = Color(elem[2]);
111+
if (elem[3]) {
112+
const color = Color(elem[3]);
105113

106114
node.style += ",filled";
107115
node.fillcolor = color.hex();
108116
node.fontcolor = color.isDark() ? "white" : "black";
109117
}
110118

111-
if (elem[3]) node.fontcolor = elem[3];
119+
if (elem[4]) node.fontcolor = elem[4];
112120
}
113121

114122
elements.push([uid, node]);
@@ -144,6 +152,7 @@ function composeDotExpr(specLines, options) {
144152
}
145153
}
146154

155+
const parsedYumlExprLastIndex = parsedYumlExpr.length - 1;
147156
for (let k = 1; k < parsedYumlExprLastIndex; k++) {
148157
if (
149158
parsedYumlExpr[k][0] === "edge" &&
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// {type:activity}
2+
(start)->[Water]->(Fill Kettle)->(end)
Loading

0 commit comments

Comments
 (0)