From 9a90d795cab393b1819d7a3cf883da27bee9dfab Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Fri, 17 Jan 2025 11:46:44 +0100 Subject: [PATCH 01/15] #6195 Updated lexer to not allow quotes in link ids --- cypress/platform/knsv2.html | 26 +++++++++++++------ .../flowchart/parser/flow-node-data.spec.js | 26 +++++++++++++++++++ .../src/diagrams/flowchart/parser/flow.jison | 2 +- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index dfcd8aa4f..90ecd20ea 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -78,9 +78,11 @@ font-family: monospace; font-size: 72px; } + pre { width: 100%; } + /* tspan { font-size: 6px !important; } */ @@ -103,16 +105,20 @@ -
+    
       flowchart LR
-        A --> B
+        AB["apa@apa@"] --> B(("`apa@apa`"))
+    
+
+      flowchart
+        D(("for D"))
     
       flowchart LR
         A e1@==> B
         e1@{ animate: true}
     
-
+    
 flowchart LR
   A e1@--> B
   classDef animate stroke-width:2,stroke-dasharray:10\,8,stroke-dashoffset:-180,animation: edge-animation-frame 6s linear infinite, stroke-linecap: round
@@ -126,7 +132,7 @@ flowchart LR
   class e1 animate
     

Mermaid - edge-animation-slow

-
+    
 flowchart LR
   A e1@--> B
 e1@{ animation: fast}
@@ -428,7 +434,10 @@ kanban
       window.callback = function () {
         alert('A callback was triggered');
       };
-      mermaid.initialize({
+      function callback() {
+        alert('It worked');
+      }
+      await mermaid.initialize({
         // theme: 'base',
         // theme: 'default',
         // theme: 'forest',
@@ -440,9 +449,11 @@ kanban
         // layout: 'fixed',
         // htmlLabels: false,
         flowchart: { titleTopMargin: 10 },
+
         // fontFamily: 'Caveat',
         // fontFamily: 'Kalam',
         // fontFamily: 'courier',
+        fontFamily: 'arial',
         sequence: {
           actorFontFamily: 'courier',
           noteFontFamily: 'courier',
@@ -454,10 +465,9 @@ kanban
         fontSize: 12,
         logLevel: 0,
         securityLevel: 'loose',
+        callback,
       });
-      function callback() {
-        alert('It worked');
-      }
+
       mermaid.parseError = function (err, hash) {
         console.error('In parse error:');
         console.error(err);
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js
index 879572209..0125572ae 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js
@@ -317,6 +317,32 @@ describe('when parsing directions', function () {
     expect(data4Layout.nodes[3].label).toEqual('for E');
     expect(data4Layout.nodes[4].label).toEqual('for D');
   });
+
+  it('should be possible to use @  syntax in labels', function () {
+    const res = flow.parser.parse(`flowchart TD
+    A["@A@"] --> B["@for@ B@"] & C@{ label: "@for@ c@"} & E{"\`@for@ E@\`"} & D(("@for@ D@"))
+      H1{{"@for@ H@"}}
+      H2{{"\`@for@ H@\`"}}
+      Q1{"@for@ Q@"}
+      Q2{"\`@for@ Q@\`"}
+      AS1>"@for@ AS@"]
+      AS2>"\`@for@ AS@\`"]
+      `);
+
+    const data4Layout = flow.parser.yy.getData();
+    expect(data4Layout.nodes.length).toBe(11);
+    expect(data4Layout.nodes[0].label).toEqual('@A@');
+    expect(data4Layout.nodes[1].label).toEqual('@for@ B@');
+    expect(data4Layout.nodes[2].label).toEqual('@for@ c@');
+    expect(data4Layout.nodes[3].label).toEqual('@for@ E@');
+    expect(data4Layout.nodes[4].label).toEqual('@for@ D@');
+    expect(data4Layout.nodes[5].label).toEqual('@for@ H@');
+    expect(data4Layout.nodes[6].label).toEqual('@for@ H@');
+    expect(data4Layout.nodes[7].label).toEqual('@for@ Q@');
+    expect(data4Layout.nodes[8].label).toEqual('@for@ Q@');
+    expect(data4Layout.nodes[9].label).toEqual('@for@ AS@');
+    expect(data4Layout.nodes[10].label).toEqual('@for@ AS@');
+  });
   it.skip(' should be possible to use @  syntax to add labels with trail spaces', function () {
     const res = flow.parser.parse(
       `flowchart TB
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
index c3ac2b04b..7b2f4386a 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
@@ -141,7 +141,7 @@ that id.
 .*direction\s+RL[^\n]*       return 'direction_rl';
 .*direction\s+LR[^\n]*       return 'direction_lr';
 
-[^\s]+\@(?=[^\{])               { return 'LINK_ID'; }
+[^\s\"]+\@(?=[^\{\"])               { return 'LINK_ID'; }
 [0-9]+                       return 'NUM';
 \#                           return 'BRKT';
 ":::"                        return 'STYLE_SEPARATOR';

From 127bac1147034d8a8588cc8f7870abe92ebc945e Mon Sep 17 00:00:00 2001
From: Knut Sveidqvist 
Date: Fri, 17 Jan 2025 11:48:28 +0100
Subject: [PATCH 02/15] Adding changeset

---
 .changeset/chatty-elephants-warn.md | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 .changeset/chatty-elephants-warn.md

diff --git a/.changeset/chatty-elephants-warn.md b/.changeset/chatty-elephants-warn.md
new file mode 100644
index 000000000..07fd53aff
--- /dev/null
+++ b/.changeset/chatty-elephants-warn.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+Fix for issue #6195 - allowinf @ signs inside node labels

From 7f47678862eb341183d61a5fb7bf58a9c7328d38 Mon Sep 17 00:00:00 2001
From: Knut Sveidqvist 
Date: Fri, 17 Jan 2025 11:50:22 +0100
Subject: [PATCH 03/15] Spellfix in changeset

---
 .changeset/chatty-elephants-warn.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.changeset/chatty-elephants-warn.md b/.changeset/chatty-elephants-warn.md
index 07fd53aff..225047ece 100644
--- a/.changeset/chatty-elephants-warn.md
+++ b/.changeset/chatty-elephants-warn.md
@@ -2,4 +2,4 @@
 'mermaid': patch
 ---
 
-Fix for issue #6195 - allowinf @ signs inside node labels
+Fix for issue #6195 - allowing @ signs inside node labels

From 7ba415dad1c11c3f294ed4bfac8aa8b643550496 Mon Sep 17 00:00:00 2001
From: Feroz Mujawar 
Date: Fri, 17 Jan 2025 21:23:30 +0530
Subject: [PATCH 04/15] edge flickering fix

---
 packages/mermaid/src/diagrams/flowchart/flowDb.ts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
index 931347a4d..1e3f215c8 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
@@ -233,6 +233,8 @@ export const addSingleLink = function (_start: string, _end: string, type: any,
   }
   if (id) {
     edge.id = id;
+  } else {
+    edge.id = `${edge.start}-${edge.end}-${edge.length}`;
   }
 
   if (edges.length < (config.maxEdges ?? 500)) {

From 64237fbaa74e40a5838c0577af8aceab92a40f70 Mon Sep 17 00:00:00 2001
From: Feroz Mujawar 
Date: Mon, 20 Jan 2025 19:59:46 +0530
Subject: [PATCH 05/15] updated addSingleLink for multiple outgoing edges to
 same end node

---
 packages/mermaid/src/diagrams/flowchart/flowDb.ts | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
index 1e3f215c8..d60dcc27b 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
@@ -234,7 +234,12 @@ export const addSingleLink = function (_start: string, _end: string, type: any,
   if (id) {
     edge.id = id;
   } else {
-    edge.id = `${edge.start}-${edge.end}-${edge.length}`;
+    const existingLinks = edges.filter((e) => e.start === edge.start && e.end === edge.end);
+    if (existingLinks.length === 0) {
+      edge.id = `${edge.start}-${edge.end}-${edge.length}`;
+    } else {
+      edge.id = `${edge.start}-${edge.end}-${existingLinks.length + 1}`;
+    }
   }
 
   if (edges.length < (config.maxEdges ?? 500)) {
@@ -269,9 +274,11 @@ export const addLink = function (_start: string[], _end: string[], linkData: unk
 
   log.info('addLink', _start, _end, id);
 
+  let idIsUsed = false;
   for (const start of _start) {
     for (const end of _end) {
-      addSingleLink(start, end, linkData, id);
+      addSingleLink(start, end, linkData, !idIsUsed ? id : undefined);
+      idIsUsed = true;
     }
   }
 };

From c432aec2f6cbd28a1dcfd5c45ef129dbb76e3aa6 Mon Sep 17 00:00:00 2001
From: saurabhg772244 
Date: Mon, 20 Jan 2025 20:05:51 +0530
Subject: [PATCH 06/15] fix: styles for Sankey, Gantt, and User Journey
 diagrams

---
 packages/mermaid/src/diagrams/gantt/styles.js        | 12 ++++++------
 .../mermaid/src/diagrams/sankey/sankeyDiagram.ts     |  2 ++
 .../mermaid/src/diagrams/sankey/sankeyRenderer.ts    |  1 -
 packages/mermaid/src/diagrams/sankey/styles.js       |  6 ++++++
 packages/mermaid/src/diagrams/user-journey/styles.js |  6 ++----
 5 files changed, 16 insertions(+), 11 deletions(-)
 create mode 100644 packages/mermaid/src/diagrams/sankey/styles.js

diff --git a/packages/mermaid/src/diagrams/gantt/styles.js b/packages/mermaid/src/diagrams/gantt/styles.js
index 626ed4e0f..dcb75939d 100644
--- a/packages/mermaid/src/diagrams/gantt/styles.js
+++ b/packages/mermaid/src/diagrams/gantt/styles.js
@@ -1,7 +1,7 @@
 const getStyles = (options) =>
   `
   .mermaid-main-font {
-    font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
+        font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
   }
 
   .exclude-range {
@@ -45,7 +45,7 @@ const getStyles = (options) =>
 
   .sectionTitle {
     text-anchor: start;
-    font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
+    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
   }
 
 
@@ -58,7 +58,7 @@ const getStyles = (options) =>
   }
 
   .grid .tick text {
-    font-family: ${options.fontFamily};
+    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
     fill: ${options.textColor};
   }
 
@@ -86,13 +86,13 @@ const getStyles = (options) =>
 
   .taskText {
     text-anchor: middle;
-    font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
+    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
   }
 
   .taskTextOutsideRight {
     fill: ${options.taskTextDarkColor};
     text-anchor: start;
-    font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
+    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
   }
 
   .taskTextOutsideLeft {
@@ -248,7 +248,7 @@ const getStyles = (options) =>
     text-anchor: middle;
     font-size: 18px;
     fill: ${options.titleColor || options.textColor};
-    font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
+    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
   }
 `;
 
diff --git a/packages/mermaid/src/diagrams/sankey/sankeyDiagram.ts b/packages/mermaid/src/diagrams/sankey/sankeyDiagram.ts
index 6fed435ac..54aa40a78 100644
--- a/packages/mermaid/src/diagrams/sankey/sankeyDiagram.ts
+++ b/packages/mermaid/src/diagrams/sankey/sankeyDiagram.ts
@@ -4,11 +4,13 @@ import parser from './parser/sankey.jison';
 import db from './sankeyDB.js';
 import renderer from './sankeyRenderer.js';
 import { prepareTextForParsing } from './sankeyUtils.js';
+import sankeyStyles from './styles.js';
 
 const originalParse = parser.parse.bind(parser);
 parser.parse = (text: string) => originalParse(prepareTextForParsing(text));
 
 export const diagram: DiagramDefinition = {
+  styles: sankeyStyles,
   parser,
   db,
   renderer,
diff --git a/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts b/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts
index a981a346e..5e3f04173 100644
--- a/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts
+++ b/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts
@@ -136,7 +136,6 @@ export const draw = function (text: string, id: string, _version: string, diagOb
   svg
     .append('g')
     .attr('class', 'node-labels')
-    .attr('font-family', 'sans-serif')
     .attr('font-size', 14)
     .selectAll('text')
     .data(graph.nodes)
diff --git a/packages/mermaid/src/diagrams/sankey/styles.js b/packages/mermaid/src/diagrams/sankey/styles.js
new file mode 100644
index 000000000..bb70bfbd2
--- /dev/null
+++ b/packages/mermaid/src/diagrams/sankey/styles.js
@@ -0,0 +1,6 @@
+const getStyles = (options) =>
+  `.label {
+      font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+    }`;
+
+export default getStyles;
diff --git a/packages/mermaid/src/diagrams/user-journey/styles.js b/packages/mermaid/src/diagrams/user-journey/styles.js
index 998a73894..87edee576 100644
--- a/packages/mermaid/src/diagrams/user-journey/styles.js
+++ b/packages/mermaid/src/diagrams/user-journey/styles.js
@@ -1,7 +1,6 @@
 const getStyles = (options) =>
   `.label {
-    font-family: 'trebuchet ms', verdana, arial, sans-serif;
-    font-family: var(--mermaid-font-family);
+    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
     color: ${options.textColor};
   }
   .mouth {
@@ -79,8 +78,7 @@ const getStyles = (options) =>
     text-align: center;
     max-width: 200px;
     padding: 2px;
-    font-family: 'trebuchet ms', verdana, arial, sans-serif;
-    font-family: var(--mermaid-font-family);
+    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
     font-size: 12px;
     background: ${options.tertiaryColor};
     border: 1px solid ${options.border2};

From 7bbebff583111c45679fb01b1818f707f0022c2d Mon Sep 17 00:00:00 2001
From: saurabhg772244 
Date: Mon, 20 Jan 2025 20:30:28 +0530
Subject: [PATCH 07/15] Updated styles implementation

---
 packages/mermaid/src/diagrams/gantt/styles.js        | 12 ++++++------
 packages/mermaid/src/diagrams/sankey/styles.js       |  4 ++--
 packages/mermaid/src/diagrams/user-journey/styles.js |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/packages/mermaid/src/diagrams/gantt/styles.js b/packages/mermaid/src/diagrams/gantt/styles.js
index dcb75939d..1f670a16d 100644
--- a/packages/mermaid/src/diagrams/gantt/styles.js
+++ b/packages/mermaid/src/diagrams/gantt/styles.js
@@ -1,7 +1,7 @@
 const getStyles = (options) =>
   `
   .mermaid-main-font {
-        font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+        font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
   }
 
   .exclude-range {
@@ -45,7 +45,7 @@ const getStyles = (options) =>
 
   .sectionTitle {
     text-anchor: start;
-    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
   }
 
 
@@ -58,7 +58,7 @@ const getStyles = (options) =>
   }
 
   .grid .tick text {
-    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
     fill: ${options.textColor};
   }
 
@@ -86,13 +86,13 @@ const getStyles = (options) =>
 
   .taskText {
     text-anchor: middle;
-    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
   }
 
   .taskTextOutsideRight {
     fill: ${options.taskTextDarkColor};
     text-anchor: start;
-    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
   }
 
   .taskTextOutsideLeft {
@@ -248,7 +248,7 @@ const getStyles = (options) =>
     text-anchor: middle;
     font-size: 18px;
     fill: ${options.titleColor || options.textColor};
-    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
   }
 `;
 
diff --git a/packages/mermaid/src/diagrams/sankey/styles.js b/packages/mermaid/src/diagrams/sankey/styles.js
index bb70bfbd2..f2e31651a 100644
--- a/packages/mermaid/src/diagrams/sankey/styles.js
+++ b/packages/mermaid/src/diagrams/sankey/styles.js
@@ -1,6 +1,6 @@
-const getStyles = (options) =>
+const getStyles = () =>
   `.label {
-      font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+      font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
     }`;
 
 export default getStyles;
diff --git a/packages/mermaid/src/diagrams/user-journey/styles.js b/packages/mermaid/src/diagrams/user-journey/styles.js
index 87edee576..81aef1180 100644
--- a/packages/mermaid/src/diagrams/user-journey/styles.js
+++ b/packages/mermaid/src/diagrams/user-journey/styles.js
@@ -1,6 +1,6 @@
 const getStyles = (options) =>
   `.label {
-    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
     color: ${options.textColor};
   }
   .mouth {
@@ -78,7 +78,7 @@ const getStyles = (options) =>
     text-align: center;
     max-width: 200px;
     padding: 2px;
-    font-family: ${options.fontFamily ? options.fontFamily : 'Trebuchet MS, Verdana, Arial, sans-serif'};
+    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
     font-size: 12px;
     background: ${options.tertiaryColor};
     border: 1px solid ${options.border2};

From 32a68d489ed83a5b79f516d6b2fb3a7505c5eb24 Mon Sep 17 00:00:00 2001
From: saurabhg772244 
Date: Tue, 21 Jan 2025 11:35:23 +0530
Subject: [PATCH 08/15] Added changeset

---
 .changeset/stupid-dots-do.md | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 .changeset/stupid-dots-do.md

diff --git a/.changeset/stupid-dots-do.md b/.changeset/stupid-dots-do.md
new file mode 100644
index 000000000..594fa9536
--- /dev/null
+++ b/.changeset/stupid-dots-do.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: Gantt, Sankey and User Journey diagram are now able to pick font-family from mermaid config.

From 46c16c963b8b8e57f97a8e30408fed0dba13c22d Mon Sep 17 00:00:00 2001
From: saurabhg772244 
Date: Tue, 21 Jan 2025 15:32:53 +0530
Subject: [PATCH 09/15] Minor change.

---
 packages/mermaid/src/diagrams/gantt/styles.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/mermaid/src/diagrams/gantt/styles.js b/packages/mermaid/src/diagrams/gantt/styles.js
index 1f670a16d..14cbb2430 100644
--- a/packages/mermaid/src/diagrams/gantt/styles.js
+++ b/packages/mermaid/src/diagrams/gantt/styles.js
@@ -58,7 +58,7 @@ const getStyles = (options) =>
   }
 
   .grid .tick text {
-    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+    font-family: ${options.fontFamily};
     fill: ${options.textColor};
   }
 

From ee6fb832651bb64a0663cc3cc240ea759ad6df97 Mon Sep 17 00:00:00 2001
From: saurabhg772244 
Date: Tue, 21 Jan 2025 18:27:05 +0530
Subject: [PATCH 10/15] Used 'options' instead of 'var(--mermaid-font-family)'

---
 packages/mermaid/src/diagrams/gantt/styles.js        | 10 +++++-----
 packages/mermaid/src/diagrams/sankey/styles.js       |  4 ++--
 packages/mermaid/src/diagrams/user-journey/styles.js |  4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/packages/mermaid/src/diagrams/gantt/styles.js b/packages/mermaid/src/diagrams/gantt/styles.js
index 14cbb2430..5b53a1b07 100644
--- a/packages/mermaid/src/diagrams/gantt/styles.js
+++ b/packages/mermaid/src/diagrams/gantt/styles.js
@@ -1,7 +1,7 @@
 const getStyles = (options) =>
   `
   .mermaid-main-font {
-        font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+        font-family: ${options.fontFamily};
   }
 
   .exclude-range {
@@ -45,7 +45,7 @@ const getStyles = (options) =>
 
   .sectionTitle {
     text-anchor: start;
-    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+    font-family: ${options.fontFamily};
   }
 
 
@@ -86,13 +86,13 @@ const getStyles = (options) =>
 
   .taskText {
     text-anchor: middle;
-    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+    font-family: ${options.fontFamily};
   }
 
   .taskTextOutsideRight {
     fill: ${options.taskTextDarkColor};
     text-anchor: start;
-    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+    font-family: ${options.fontFamily};
   }
 
   .taskTextOutsideLeft {
@@ -248,7 +248,7 @@ const getStyles = (options) =>
     text-anchor: middle;
     font-size: 18px;
     fill: ${options.titleColor || options.textColor};
-    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+    font-family: ${options.fontFamily};
   }
 `;
 
diff --git a/packages/mermaid/src/diagrams/sankey/styles.js b/packages/mermaid/src/diagrams/sankey/styles.js
index f2e31651a..eafb62b05 100644
--- a/packages/mermaid/src/diagrams/sankey/styles.js
+++ b/packages/mermaid/src/diagrams/sankey/styles.js
@@ -1,6 +1,6 @@
-const getStyles = () =>
+const getStyles = (options) =>
   `.label {
-      font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+      font-family: ${options.fontFamily};
     }`;
 
 export default getStyles;
diff --git a/packages/mermaid/src/diagrams/user-journey/styles.js b/packages/mermaid/src/diagrams/user-journey/styles.js
index 81aef1180..9cdbcd12e 100644
--- a/packages/mermaid/src/diagrams/user-journey/styles.js
+++ b/packages/mermaid/src/diagrams/user-journey/styles.js
@@ -1,6 +1,6 @@
 const getStyles = (options) =>
   `.label {
-    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+    font-family: ${options.fontFamily};
     color: ${options.textColor};
   }
   .mouth {
@@ -78,7 +78,7 @@ const getStyles = (options) =>
     text-align: center;
     max-width: 200px;
     padding: 2px;
-    font-family: var(--mermaid-font-family), trebuchet ms, verdana, arial, sans-serif;
+    font-family: ${options.fontFamily};
     font-size: 12px;
     background: ${options.tertiaryColor};
     border: 1px solid ${options.border2};

From 54a0dd0af6d46130df957b6a4ff2b50c717026cb Mon Sep 17 00:00:00 2001
From: Ashish Jain 
Date: Wed, 22 Jan 2025 01:09:49 +0100
Subject: [PATCH 11/15] Make flowchart edge Ids consistent across getEdges and
 getData

---
 .../mermaid/src/diagrams/flowchart/flowDb.ts    | 17 ++++++++++++-----
 .../mermaid/src/diagrams/flowchart/types.ts     |  1 +
 packages/mermaid/src/rendering-util/types.ts    |  1 +
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
index d60dcc27b..83c55fc9b 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
@@ -212,6 +212,7 @@ export const addSingleLink = function (_start: string, _end: string, type: any,
     text: '',
     labelType: 'text',
     classes: [],
+    isUserDefinedId: false,
   };
   log.info('abc78 Got edge...', edge);
   const linkTextObj = type.text;
@@ -233,12 +234,15 @@ export const addSingleLink = function (_start: string, _end: string, type: any,
   }
   if (id) {
     edge.id = id;
+    edge.isUserDefinedId = true;
   } else {
     const existingLinks = edges.filter((e) => e.start === edge.start && e.end === edge.end);
     if (existingLinks.length === 0) {
-      edge.id = `${edge.start}-${edge.end}-${edge.length}`;
+      edge.id = getEdgeId(edge.start, edge.end, { counter: 0, prefix: 'L' });
+      //edge.id = `${edge.start}-${edge.end}-${edge.length}`;
     } else {
-      edge.id = `${edge.start}-${edge.end}-${existingLinks.length + 1}`;
+      edge.id = getEdgeId(edge.start, edge.end, { counter: existingLinks.length + 1, prefix: 'L' });
+      //edge.id = `${edge.start}-${edge.end}-${existingLinks.length + 1}`;
     }
   }
 
@@ -274,11 +278,13 @@ export const addLink = function (_start: string[], _end: string[], linkData: unk
 
   log.info('addLink', _start, _end, id);
 
-  let idIsUsed = false;
+  // for a group syntax like A e1@--> B & C, only the first edge should have an the userDefined id
+  // the rest of the edges should have auto generated ids
+  let isEdgeConsumed = false;
   for (const start of _start) {
     for (const end of _end) {
-      addSingleLink(start, end, linkData, !idIsUsed ? id : undefined);
-      idIsUsed = true;
+      addSingleLink(start, end, linkData, !isEdgeConsumed ? id : undefined);
+      isEdgeConsumed = true;
     }
   }
 };
@@ -1054,6 +1060,7 @@ export const getData = () => {
     }
     const edge: Edge = {
       id: getEdgeId(rawEdge.start, rawEdge.end, { counter: index, prefix: 'L' }, rawEdge.id),
+      isUserDefinedId: rawEdge.isUserDefinedId,
       start: rawEdge.start,
       end: rawEdge.end,
       type: rawEdge.type ?? 'normal',
diff --git a/packages/mermaid/src/diagrams/flowchart/types.ts b/packages/mermaid/src/diagrams/flowchart/types.ts
index 00acb6751..54156091b 100644
--- a/packages/mermaid/src/diagrams/flowchart/types.ts
+++ b/packages/mermaid/src/diagrams/flowchart/types.ts
@@ -53,6 +53,7 @@ export interface FlowText {
 }
 
 export interface FlowEdge {
+  isUserDefinedId: boolean;
   start: string;
   end: string;
   interpolate?: string;
diff --git a/packages/mermaid/src/rendering-util/types.ts b/packages/mermaid/src/rendering-util/types.ts
index 1f84c66c3..b11d2f314 100644
--- a/packages/mermaid/src/rendering-util/types.ts
+++ b/packages/mermaid/src/rendering-util/types.ts
@@ -125,6 +125,7 @@ export interface Edge {
   pattern?: string;
   thickness?: 'normal' | 'thick' | 'invisible' | 'dotted';
   look?: string;
+  isUserDefinedId?: boolean;
 }
 
 export interface RectOptions {

From 304f133227fce587bfb30fd052ad8296bde07c36 Mon Sep 17 00:00:00 2001
From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com>
Date: Wed, 22 Jan 2025 00:14:56 +0000
Subject: [PATCH 12/15] [autofix.ci] apply automated fixes

---
 docs/config/setup/interfaces/mermaid.LayoutData.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/config/setup/interfaces/mermaid.LayoutData.md b/docs/config/setup/interfaces/mermaid.LayoutData.md
index 552a16a8d..46c9134e8 100644
--- a/docs/config/setup/interfaces/mermaid.LayoutData.md
+++ b/docs/config/setup/interfaces/mermaid.LayoutData.md
@@ -20,7 +20,7 @@
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.ts:147](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L147)
+[packages/mermaid/src/rendering-util/types.ts:148](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L148)
 
 ---
 
@@ -30,7 +30,7 @@
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L146)
+[packages/mermaid/src/rendering-util/types.ts:147](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L147)
 
 ---
 
@@ -40,4 +40,4 @@
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.ts:145](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L145)
+[packages/mermaid/src/rendering-util/types.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L146)

From c063b92cc9120895cbd36f5884e7c91cfcba1535 Mon Sep 17 00:00:00 2001
From: Ashish Jain 
Date: Wed, 22 Jan 2025 02:03:29 +0100
Subject: [PATCH 13/15] Handle more edge cases, and lint fixes

---
 .../mermaid/src/diagrams/flowchart/flowDb.ts  | 16 ++++---
 .../flowchart/parser/flow-node-data.spec.js   | 45 ++++++++++++++++---
 2 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
index 83c55fc9b..053e6f73c 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
@@ -232,17 +232,16 @@ export const addSingleLink = function (_start: string, _end: string, type: any,
     edge.stroke = type.stroke;
     edge.length = type.length > 10 ? 10 : type.length;
   }
-  if (id) {
+
+  if (id && !edges.some((e) => e.id === id)) {
     edge.id = id;
     edge.isUserDefinedId = true;
   } else {
     const existingLinks = edges.filter((e) => e.start === edge.start && e.end === edge.end);
     if (existingLinks.length === 0) {
       edge.id = getEdgeId(edge.start, edge.end, { counter: 0, prefix: 'L' });
-      //edge.id = `${edge.start}-${edge.end}-${edge.length}`;
     } else {
       edge.id = getEdgeId(edge.start, edge.end, { counter: existingLinks.length + 1, prefix: 'L' });
-      //edge.id = `${edge.start}-${edge.end}-${existingLinks.length + 1}`;
     }
   }
 
@@ -280,11 +279,16 @@ export const addLink = function (_start: string[], _end: string[], linkData: unk
 
   // for a group syntax like A e1@--> B & C, only the first edge should have an the userDefined id
   // the rest of the edges should have auto generated ids
-  let isEdgeConsumed = false;
   for (const start of _start) {
     for (const end of _end) {
-      addSingleLink(start, end, linkData, !isEdgeConsumed ? id : undefined);
-      isEdgeConsumed = true;
+      //use the id only for last node in _start and and first node in _end
+      const isLastStart = start === _start[_start.length - 1];
+      const isFirstEnd = end === _end[0];
+      if (isLastStart && isFirstEnd) {
+        addSingleLink(start, end, linkData, id);
+      } else {
+        addSingleLink(start, end, linkData, undefined);
+      }
     }
   }
 };
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js
index 0125572ae..2a987753c 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js
@@ -251,7 +251,7 @@ describe('when parsing directions', function () {
     expect(data4Layout.nodes[0].shape).toEqual('squareRect');
     expect(data4Layout.nodes[0].label).toEqual('This is a
multiline string'); }); - it(' should be possible to use } in strings', function () { + it('should be possible to use } in strings', function () { const res = flow.parser.parse(`flowchart TB A@{ label: "This is a string with }" @@ -264,7 +264,7 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[0].shape).toEqual('squareRect'); expect(data4Layout.nodes[0].label).toEqual('This is a string with }'); }); - it(' should be possible to use @ in strings', function () { + it('should be possible to use @ in strings', function () { const res = flow.parser.parse(`flowchart TB A@{ label: "This is a string with @" @@ -277,7 +277,7 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[0].shape).toEqual('squareRect'); expect(data4Layout.nodes[0].label).toEqual('This is a string with @'); }); - it(' should be possible to use @ in strings', function () { + it('should be possible to use @ in strings', function () { const res = flow.parser.parse(`flowchart TB A@{ label: "This is a string with}" @@ -291,7 +291,7 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[0].label).toEqual('This is a string with}'); }); - it(' should be possible to use @ syntax to add labels on multi nodes', function () { + it('should be possible to use @ syntax to add labels on multi nodes', function () { const res = flow.parser.parse(`flowchart TB n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"} `); @@ -343,7 +343,42 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[9].label).toEqual('@for@ AS@'); expect(data4Layout.nodes[10].label).toEqual('@for@ AS@'); }); - it.skip(' should be possible to use @ syntax to add labels with trail spaces', function () { + + it('should handle unique edge creation with using @ and &', function () { + const res = flow.parser.parse(`flowchart TD + A & B e1@--> C & D + A1 e2@--> C1 & D1 + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(7); + expect(data4Layout.edges.length).toBe(6); + expect(data4Layout.edges[0].id).toEqual('L_A_C_0'); + expect(data4Layout.edges[1].id).toEqual('L_A_D_0'); + expect(data4Layout.edges[2].id).toEqual('e1'); + expect(data4Layout.edges[3].id).toEqual('L_B_D_0'); + expect(data4Layout.edges[4].id).toEqual('e2'); + expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0'); + }); + + it('should handle redefine same edge ids again', function () { + const res = flow.parser.parse(`flowchart TD + A & B e1@--> C & D + A1 e1@--> C1 & D1 + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(7); + expect(data4Layout.edges.length).toBe(6); + expect(data4Layout.edges[0].id).toEqual('L_A_C_0'); + expect(data4Layout.edges[1].id).toEqual('L_A_D_0'); + expect(data4Layout.edges[2].id).toEqual('e1'); + expect(data4Layout.edges[3].id).toEqual('L_B_D_0'); + expect(data4Layout.edges[4].id).toEqual('L_A1_C1_0'); + expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0'); + }); + + it.skip('should be possible to use @ syntax to add labels with trail spaces', function () { const res = flow.parser.parse( `flowchart TB n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"} ` From e2e51010058c0bfc3adf0a5218f4ac8af81a004c Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Wed, 22 Jan 2025 10:57:57 +0100 Subject: [PATCH 14/15] Handle more override edge animate --- .../mermaid/src/diagrams/flowchart/flowDb.ts | 4 ++-- .../flowchart/parser/flow-node-data.spec.js | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts index 053e6f73c..8c097d9fa 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts @@ -94,10 +94,10 @@ export const addVertex = function ( const edge = edges.find((e) => e.id === id); if (edge) { const edgeDoc = doc as EdgeMetaData; - if (edgeDoc?.animate) { + if (edgeDoc?.animate !== undefined) { edge.animate = edgeDoc.animate; } - if (edgeDoc?.animation) { + if (edgeDoc?.animation !== undefined) { edge.animation = edgeDoc.animation; } return; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js index 2a987753c..9f221f82f 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js @@ -378,6 +378,28 @@ describe('when parsing directions', function () { expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0'); }); + it('should handle overriding edge animate again', function () { + const res = flow.parser.parse(`flowchart TD + A e1@--> B + C e2@--> D + E e3@--> F + e1@{ animate: true } + e2@{ animate: false } + e3@{ animate: true } + e3@{ animate: false } + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(6); + expect(data4Layout.edges.length).toBe(3); + expect(data4Layout.edges[0].id).toEqual('e1'); + expect(data4Layout.edges[0].animate).toEqual(true); + expect(data4Layout.edges[1].id).toEqual('e2'); + expect(data4Layout.edges[1].animate).toEqual(false); + expect(data4Layout.edges[2].id).toEqual('e3'); + expect(data4Layout.edges[2].animate).toEqual(false); + }); + it.skip('should be possible to use @ syntax to add labels with trail spaces', function () { const res = flow.parser.parse( `flowchart TB From 963efa64c794466dcd0f06bad6de6ba554d05a54 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Wed, 22 Jan 2025 11:01:37 +0100 Subject: [PATCH 15/15] Added changeset --- .changeset/bright-ads-exist.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/bright-ads-exist.md diff --git a/.changeset/bright-ads-exist.md b/.changeset/bright-ads-exist.md new file mode 100644 index 000000000..ef2f76f4c --- /dev/null +++ b/.changeset/bright-ads-exist.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +Fixes for consistent edge id creation & handling edge cases for animate edge feature