From 7809b5a93fae127f45727071f5ff14325222c518 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Tue, 14 Jan 2025 14:07:25 +0100 Subject: [PATCH 1/2] #6186 Fixes the flowchaart node metadata syntax bugs --- .changeset/great-ghosts-rule.md | 8 ++++++ .../rendering/flowchart-v2.spec.js | 28 +++++++++++++++++++ .../src/diagrams/flowchart/flowDiagram.ts | 3 +- .../flowchart/parser/flow-arrows.spec.js | 2 +- .../flowchart/parser/flow-comments.spec.js | 2 +- .../flowchart/parser/flow-direction.spec.js | 2 +- .../flowchart/parser/flow-edges.spec.js | 2 +- .../flowchart/parser/flow-huge.spec.js | 2 +- .../parser/flow-interactions.spec.js | 2 +- .../flowchart/parser/flow-lines.spec.js | 2 +- .../flowchart/parser/flow-md-string.spec.js | 2 +- .../flowchart/parser/flow-node-data.spec.js | 26 ++++++++++++++++- .../flowchart/parser/flow-singlenode.spec.js | 2 +- .../flowchart/parser/flow-style.spec.js | 2 +- .../flowchart/parser/flow-text.spec.js | 2 +- .../parser/flow-vertice-chaining.spec.js | 2 +- .../src/diagrams/flowchart/parser/flow.jison | 4 +-- .../diagrams/flowchart/parser/flow.spec.js | 2 +- .../diagrams/flowchart/parser/flowParser.ts | 12 ++++++++ .../flowchart/parser/subgraph.spec.js | 2 +- 20 files changed, 91 insertions(+), 18 deletions(-) create mode 100644 .changeset/great-ghosts-rule.md create mode 100644 packages/mermaid/src/diagrams/flowchart/parser/flowParser.ts diff --git a/.changeset/great-ghosts-rule.md b/.changeset/great-ghosts-rule.md new file mode 100644 index 000000000..f11c6e2a9 --- /dev/null +++ b/.changeset/great-ghosts-rule.md @@ -0,0 +1,8 @@ +--- +'mermaid': minor +--- + +Flowchart new syntax for node metadata bugs + +- Incorrect label mapping for nodes when using `&` +- Syntax error when `}` with trailing spaces before new line diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index 66452f4b2..bb37914cb 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -1076,4 +1076,32 @@ end ); }); }); + describe('New @ sytax for node metadata edge cases', () => { + it('should be possible to use @ syntax to add labels on multi nodes', () => { + imgSnapshotTest( + `flowchart TB + n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"} + `, + {} + ); + }); + it('should be possible to use @ syntax to add labels with trail spaces and &', () => { + imgSnapshotTest( + `flowchart TB + n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"} + `, + {} + ); + }); + it('should be possible to use @ syntax to add labels with trail spaces', () => { + imgSnapshotTest( + `flowchart TB + n2["label for n2"] + n4@{ label: "labe for n4"} + n5@{ label: "labe for n5"} + `, + {} + ); + }); + }); }); diff --git a/packages/mermaid/src/diagrams/flowchart/flowDiagram.ts b/packages/mermaid/src/diagrams/flowchart/flowDiagram.ts index 67cdf918f..ddb2eb3ed 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDiagram.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDiagram.ts @@ -3,7 +3,8 @@ import { setConfig } from '../../diagram-api/diagramAPI.js'; import flowDb from './flowDb.js'; import renderer from './flowRenderer-v3-unified.js'; // @ts-ignore: JISON doesn't support types -import flowParser from './parser/flow.jison'; +//import flowParser from './parser/flow.jison'; +import flowParser from './parser/flowParser.ts'; import flowStyles from './styles.js'; export const diagram = { diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-arrows.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-arrows.spec.js index e89398ab4..50236b60c 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-arrows.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-arrows.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-comments.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-comments.spec.js index 9c2a740af..487705cd7 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-comments.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-comments.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; import { cleanupComments } from '../../../diagram-api/comments.js'; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js index ce6b0b0c4..fcf3aa21f 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-edges.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-edges.spec.js index 5682c9bed..a23528fd6 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-edges.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-edges.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-huge.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-huge.spec.js index 8931c6ee1..7fef14f5b 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-huge.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-huge.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-interactions.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-interactions.spec.js index cb3f48cca..893a5e757 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-interactions.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-interactions.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; import { vi } from 'vitest'; const spyOn = vi.spyOn; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-lines.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-lines.spec.js index ec157e646..116878f6f 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-lines.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-lines.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-md-string.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-md-string.spec.js index 55e749a22..3c39dbc4f 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-md-string.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-md-string.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ 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 1669cfada..df3782a6b 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 @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ @@ -290,4 +290,28 @@ 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 @ 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"} + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(3); + expect(data4Layout.nodes[0].label).toEqual('label for n2'); + expect(data4Layout.nodes[1].label).toEqual('labe for n4'); + expect(data4Layout.nodes[2].label).toEqual('labe for n5'); + }); + 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"} ` + ); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(3); + expect(data4Layout.nodes[0].label).toEqual('label for n2'); + expect(data4Layout.nodes[1].label).toEqual('labe for n4'); + expect(data4Layout.nodes[2].label).toEqual('labe for n5'); + }); }); diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-singlenode.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-singlenode.spec.js index f6ed123d7..bf152c9bf 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-singlenode.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-singlenode.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-style.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-style.spec.js index 22fd48a33..c24873e7c 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-style.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-style.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js index 3754766f4..61774d7c0 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-vertice-chaining.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-vertice-chaining.spec.js index a5b6a2b6d..95494ab44 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-vertice-chaining.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-vertice-chaining.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison index fbd30fa9e..ade90382b 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison @@ -407,7 +407,7 @@ vertexStatement: vertexStatement link node shapeData |node spaceList { /*console.warn('vertexStatement: node spaceList', $node);*/ $$ = {stmt: $node, nodes:$node }} |node shapeData { /*console.warn('vertexStatement: node shapeData', $node[0], $shapeData);*/ - yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); + yy.addVertex($node[$node.length-1],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); $$ = {stmt: $node, nodes:$node, shapeData: $shapeData} } |node { /* console.warn('vertexStatement: single node', $node); */ $$ = {stmt: $node, nodes:$node }} @@ -416,7 +416,7 @@ vertexStatement: vertexStatement link node shapeData node: styledVertex { /*console.warn('nod', $styledVertex);*/ $$ = [$styledVertex];} | node shapeData spaceList AMP spaceList styledVertex - { yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); $$ = $node.concat($styledVertex); /*console.warn('pip2', $node[0], $styledVertex, $$);*/ } + { yy.addVertex($node[$node.length-1],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); $$ = $node.concat($styledVertex); /*console.warn('pip2', $node[0], $styledVertex, $$);*/ } | node spaceList AMP spaceList styledVertex { $$ = $node.concat($styledVertex); /*console.warn('pip', $node[0], $styledVertex, $$);*/ } ; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js index 8081c8fe4..e9d646a5a 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { cleanupComments } from '../../../diagram-api/comments.js'; import { setConfig } from '../../../config.js'; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flowParser.ts b/packages/mermaid/src/diagrams/flowchart/parser/flowParser.ts new file mode 100644 index 000000000..acf4fa525 --- /dev/null +++ b/packages/mermaid/src/diagrams/flowchart/parser/flowParser.ts @@ -0,0 +1,12 @@ +// @ts-ignore: JISON doesn't support types +import flowJisonParser from './flow.jison'; + +const newParser = Object.assign({}, flowJisonParser); + +newParser.parse = (src: string): unknown => { + // remove the trailing whitespace after closing curly braces when ending a line break + const newSrc = src.replace(/}\s*\n/g, '}\n'); + return flowJisonParser.parse(newSrc); +}; + +export default newParser; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js index 12b2e4a39..e2dd59284 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js @@ -1,5 +1,5 @@ import flowDb from '../flowDb.js'; -import flow from './flow.jison'; +import flow from './flowParser.ts'; import { setConfig } from '../../../config.js'; setConfig({ From 1d9c2aab8db7b18f48815e90f2c0806f621542f7 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Wed, 15 Jan 2025 13:45:04 +0100 Subject: [PATCH 2/2] #6186 Fix for flowchart new syntax with link --- .../integration/rendering/flowchart-v2.spec.js | 9 +++++++++ .../flowchart/parser/flow-node-data.spec.js | 15 +++++++++++++++ .../src/diagrams/flowchart/parser/flow.jison | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index bb37914cb..4322500df 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -1103,5 +1103,14 @@ end {} ); }); + it('should be possible to use @ syntax to add labels with trail spaces and edge/link', () => { + imgSnapshotTest( + `flowchart TD + A["A"] --> B["for B"] & C@{ label: "for c"} & E@{label : "for E"} + D@{label: "for D"} + `, + {} + ); + }); }); }); 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 df3782a6b..879572209 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 @@ -302,6 +302,21 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[1].label).toEqual('labe for n4'); expect(data4Layout.nodes[2].label).toEqual('labe for n5'); }); + + it('should be possible to use @ syntax to add labels on multi nodes with edge/link', function () { + const res = flow.parser.parse(`flowchart TD + A["A"] --> B["for B"] & C@{ label: "for c"} & E@{label : "for E"} + D@{label: "for D"} + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(5); + 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'); + }); 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 ade90382b..c3ac2b04b 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison @@ -399,7 +399,7 @@ shapeData: ; vertexStatement: vertexStatement link node shapeData - { /* console.warn('vs shapeData',$vertexStatement.stmt,$node, $shapeData);*/ yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } } + { /* console.warn('vs shapeData',$vertexStatement.stmt,$node, $shapeData);*/ yy.addVertex($node[$node.length-1],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } } | vertexStatement link node { /*console.warn('vs',$vertexStatement.stmt,$node);*/ yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } } | vertexStatement link node spaceList