diff --git a/.eslintignore b/.eslintignore
index 04348c410..1db5125d0 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -4,4 +4,5 @@ docs/Setup.md
cypress.config.js
cypress/plugins/index.js
coverage
-*.json
\ No newline at end of file
+*.json
+node_modules
diff --git a/.github/ISSUE_TEMPLATE/diagram_proposal.yml b/.github/ISSUE_TEMPLATE/diagram_proposal.yml
index 67dad5d3a..59bda6d6d 100644
--- a/.github/ISSUE_TEMPLATE/diagram_proposal.yml
+++ b/.github/ISSUE_TEMPLATE/diagram_proposal.yml
@@ -3,6 +3,7 @@ description: Suggest a new Diagram Type to add to Mermaid.
labels:
- 'Status: Triage'
- 'Type: Enhancement'
+ - 'Type: New Diagram'
body:
- type: markdown
@@ -17,6 +18,14 @@ body:
- Use a clear and concise title
- Fill out the text fields with as much detail as possible.
- Never be shy to give us screenshots and/or code samples. It will help!
+
+ ## Example issues
+
+ Refer to the discussions here to get an idea of how the diagram syntax is created.
+
+ - https://github.com/mermaid-js/mermaid/issues/4269
+ - https://github.com/mermaid-js/mermaid/issues/4282
+
- type: textarea
attributes:
label: Proposal
@@ -35,8 +44,17 @@ body:
description: If applicable, add screenshots to show possible examples of how the diagram may look like.
- type: textarea
attributes:
- label: Code Sample
+ label: Syntax
description: |-
- If applicable, add a code sample for how to implement this new diagram.
- The text will automatically be rendered as JavaScript code.
- render: javascript
+ If possible, include a syntax which could be used to write the diagram.
+ Try to add one or two examples of valid use-cases here.
+ - type: dropdown
+ id: implementation
+ attributes:
+ label: Implementation
+ description: |-
+ Would you like to implement this yourself, or is it a proposal for the community?
+ If there is no corresponding PR from your side after 30 days, the diagram will be open for everyone to implement.
+ options:
+ - I will try and implement it myself.
+ - This is a proposal which I'd love to see built into mermaid by the wonderful community.
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index a21fbc005..d4bf4afe8 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -42,7 +42,7 @@ jobs:
if ! pnpm run lint; then
# print a nice error message on lint failure
ERROR_MESSAGE='Running `pnpm run lint` failed.'
- ERROR_MESSAGE+=' Running `pnpm run lint:fix` may fix this issue. '
+ ERROR_MESSAGE+=' Running `pnpm -w run lint:fix` may fix this issue. '
ERROR_MESSAGE+=" If this error doesn't occur on your local machine,"
ERROR_MESSAGE+=' make sure your packages are up-to-date by running `pnpm install`.'
ERROR_MESSAGE+=' You may also need to delete your prettier cache by running'
diff --git a/.vite/build.ts b/.vite/build.ts
index c2f8f08f5..a8cfe919c 100644
--- a/.vite/build.ts
+++ b/.vite/build.ts
@@ -44,6 +44,11 @@ const packageOptions = {
packageName: 'mermaid-example-diagram',
file: 'detector.ts',
},
+ 'mermaid-zenuml': {
+ name: 'mermaid-zenuml',
+ packageName: 'mermaid-zenuml',
+ file: 'detector.ts',
+ },
};
interface BuildOptions {
@@ -146,6 +151,7 @@ if (watch) {
build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
if (!mermaidOnly) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
+ build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' }));
}
} else if (visualize) {
await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' }));
diff --git a/.vite/server.ts b/.vite/server.ts
index 5a86b3d5b..41e510c83 100644
--- a/.vite/server.ts
+++ b/.vite/server.ts
@@ -15,6 +15,7 @@ async function createServer() {
app.use(cors());
app.use(express.static('./packages/mermaid/dist'));
+ app.use(express.static('./packages/mermaid-zenuml/dist'));
app.use(express.static('./packages/mermaid-example-diagram/dist'));
app.use(vite.middlewares);
app.use(express.static('demos'));
diff --git a/cSpell.json b/cSpell.json
index 154d01a99..786e8ca2c 100644
--- a/cSpell.json
+++ b/cSpell.json
@@ -7,6 +7,7 @@
"alois",
"aloisklink",
"antiscript",
+ "antlr",
"appli",
"applitools",
"asciidoctor",
@@ -83,6 +84,7 @@
"mkdocs",
"mmorel",
"mult",
+ "nextra",
"orlandoni",
"pathe",
"pbrolin",
@@ -134,7 +136,8 @@
"vitepress",
"vueuse",
"xlink",
- "yash"
+ "yash",
+ "zenuml"
],
"patterns": [
{ "name": "Markdown links", "pattern": "\\((.*)\\)", "description": "" },
diff --git a/cypress/integration/rendering/flowchart-elk.spec.js b/cypress/integration/rendering/flowchart-elk.spec.js
index d0ef42c5d..4f90646a2 100644
--- a/cypress/integration/rendering/flowchart-elk.spec.js
+++ b/cypress/integration/rendering/flowchart-elk.spec.js
@@ -684,6 +684,20 @@ A --> B
{ titleTopMargin: 0 }
);
});
+ it('elk: should include classes on the edges', () => {
+ renderGraph(
+ `flowchart-elk TD
+ A --> B --> C --> D
+ `,
+ {}
+ );
+ cy.get('svg').should((svg) => {
+ const edges = svg.querySelectorAll('.edges > path');
+ edges.forEach((edge) => {
+ expect(edge).to.have.class('flowchart-link');
+ });
+ });
+ });
describe('Markdown strings flowchart-elk (#4220)', () => {
describe('html labels', () => {
it('With styling and classes', () => {
diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js
index e5459637b..185cc4133 100644
--- a/cypress/integration/rendering/sequencediagram.spec.js
+++ b/cypress/integration/rendering/sequencediagram.spec.js
@@ -88,6 +88,16 @@ context('Sequence diagram', () => {
{}
);
});
+ it('should handle empty lines', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ Alice->>John: Hello John
+ John-->>Alice: Great
day!
+ `,
+ {}
+ );
+ });
it('should handle line breaks and wrap annotations', () => {
imgSnapshotTest(
`
diff --git a/cypress/integration/rendering/zenuml.spec.js b/cypress/integration/rendering/zenuml.spec.js
new file mode 100644
index 000000000..f317fbe82
--- /dev/null
+++ b/cypress/integration/rendering/zenuml.spec.js
@@ -0,0 +1,19 @@
+import { imgSnapshotTest } from '../../helpers/util.js';
+
+describe('Zen UML', () => {
+ it('Basic Zen UML diagram', () => {
+ imgSnapshotTest(
+ `
+ zenuml
+ A.method() {
+ if(x) {
+ B.method() {
+ selfCall() { return X }
+ }
+ }
+ }
+ `,
+ {}
+ );
+ });
+});
diff --git a/cypress/platform/knsv.html b/cypress/platform/knsv.html
index f6ee1ef03..512333c01 100644
--- a/cypress/platform/knsv.html
+++ b/cypress/platform/knsv.html
@@ -42,368 +42,86 @@
-flowchart LR - subgraph one - direction LR - A[myClass1] --> B[default] - subgraph two - direction BT - C[myClass2] --> D[default] - end - end ++ %%{init: {"flowchart": {"htmlLabels": true}} }%% + flowchart LR + b("`The dog in **the** hog.(1).. a a a a *very long text* about it + Word! + + Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words.`") --apa--> c + +++ classDiagram-v2 + classA -- classB : Inheritance + classA -- classC : link + classC -- classD : link + classB -- classD--flowchart LR - classDef aPID stroke:#4e4403,fill:#fdde29,color:#4e4403,rx:5px,ry:5px; - classDef crm stroke:#333333,fill:#DCDCDC,color:#333333,rx:5px,ry:5px; - classDef type stroke:#502604,fill:#FAB565,color:#502604,rx:20px,ry:20px;; - - O0("Joe") - class O0 aPID; - - O1("Person") - class O1 crm; - O0 -- has type -->O1["Person"] - - O2("aat:300411314") - class O2 type; - click O2 function "Sorry the newline html tags are not being processed correctly
So all of this appears on the
same line." - O0 -- has type -->O2["Bug"] - click O0 function "Lots of great info about Joe
Lots of great info about Joe
burt
fred"; ++ sequenceDiagram + Alice->>Bob: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be + loop Loopy + Bob->>Alice: Pasten + end--flowchart TD - subgraph test - direction TB - subgraph test2 - direction LR - F --> D - end - subgraph test3 - direction TB - G --> H - end - end ++ %%{init: {"flowchart": {"htmlLabels": false}} }%% + flowchart LR + b("`The dog in **the** hog.(1) + NL`") --"`1o **bold**`"--> c[new strings svg labels]--flowchart TD - - release-branch[Create Release Branch]:::relClass - develop-branch[Update Develop Branch]:::relClass - github-release-draft[GitHub Release Draft]:::relClass - trigger-pipeline[Trigger Jenkins pipeline]:::fixClass - github-release[GitHub Release]:::postClass - - build-ready --> release-branch - build-ready --> develop-branch - release-branch --> jenkins-release-build - jenkins-release-build --> github-release-draft - jenkins-release-build --> install-release - install-release --> verify-release - jenkins-release-build --> announce - github-release-draft --> github-release - verify-release --> verify-check - verify-check -- Yes --> github-release - verify-check -- No --> release-fix - release-fix --> release-branch-pr - verify-check -- No --> delete-artifacts - release-branch-pr --> trigger-pipeline - delete-artifacts --> trigger-pipeline - trigger-pipeline --> jenkins-release-build - - ++ %%{init: {"flowchart": {"htmlLabels": true}} }%% + flowchart LR + b("`The dog in **the** hog.(1) + NL`") --"`1o **bold**`"--> c[new strings html labels]--flowchart LR - a["Haiya"]===>b ++ %%{init: {"flowchart": {"htmlLabels": true}} }%% + flowchart LR + b("The dog in the hog.(1)\nNL") --"1o bold"--> c[old strings svg labels]--flowchart TD - A --> B - A --> C - B --> C ---flowchart TD - A([stadium shape test]) - A -->|Get money| B([Go shopping]) - B --> C([Let me think...-
Do I want something for work,
something to spend every free second with,
or something to get around?]) - C -->|One| D([Laptop]) - C -->|Two| E([iPhone]) - C -->|Three| F([Car
wroom wroom]) - click A "index.html#link-clicked" "link test" - click B testClick "click test" - classDef someclass fill:#f96; - class A someclass; - class C someclass; -- sequenceDiagram - title: My Sequence Diagram Title - accTitle: My Acc Sequence Diagram - accDescr: My Sequence Diagram Description - - Alice->>John: Hello John, how are you? - John-->>Alice: Great! - Alice-)John: See you later! ---graph TD - A -->|000| B - B -->|111| C - - linkStyle 1 stroke:#ff3,stroke-width:4px,color:red; --- journey - accTitle: My User Journey Diagram - accDescr: My User Journey Diagram Description - - title My working day - section Go to work - Make tea: 5: Me - Go upstairs: 3: Me - Do work: 1: Me, Cat - section Go home - Go downstairs: 5: Me - Sit down: 5: Me --- info ---requirementDiagram - accTitle: My req Diagram - accDescr: My req Diagram Description - - requirement test_req { - id: 1 - text: the test text. - risk: high - verifymethod: test - } - - functionalRequirement test_req2 { - id: 1.1 - text: the second test text. - risk: low - verifymethod: inspection - } - - performanceRequirement test_req3 { - id: 1.2 - text: the third test text. - risk: medium - verifymethod: demonstration - } - - element test_entity { - type: simulation - } - - element test_entity2 { - type: word doc - docRef: reqs/test_entity - } - - - test_entity - satisfies -> test_req2 - test_req - traces -> test_req2 - test_req - contains -> test_req3 - test_req <- copies - test_entity2 ---gantt - dateFormat YYYY-MM-DD - title Adding GANTT diagram functionality to mermaid - excludes weekends - %% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".) - - section A section - Completed task :done, des1, 2014-01-06,2014-01-08 - Active task :active, des2, 2014-01-09, 3d - Future task : des3, after des2, 5d - Future task2 : des4, after des3, 5d - - section Critical tasks - Completed task in the critical line :crit, done, 2014-01-06,24h - Implement parser and jison :crit, done, after des1, 2d - Create tests for parser :crit, active, 3d - Future task in critical line :crit, 5d - Create tests for renderer :2d - Add to mermaid :1d - Functionality added :milestone, 2014-01-25, 0d - - section Documentation - Describe gantt syntax :active, a1, after des1, 3d - Add gantt diagram to demo page :after a1 , 20h - Add another diagram to demo page :doc1, after a1 , 48h - - section Last section - Describe gantt syntax :after doc1, 3d - Add gantt diagram to demo page :20h - Add another diagram to demo page :48h ---stateDiagram - state Active { - Idle - } - Inactive --> Idle: ACT - Active --> Active: LOG --- flowchart TB - accTitle: My flowchart - accDescr: My flowchart Description - subgraph One - a1-->a2-->a3 - end --- sequenceDiagram - A ->> B: 1 - rect rgb(204, 0, 102) - break yes - rect rgb(0, 204, 204) - C ->> C: 0 - end - end - end - B ->> A: Return ---classDiagram -accTitle: My class diagram -accDescr: My class diagram Description -Class01 <|-- AveryLongClass : Cool -Class09 --> C2 : Where am i? -Class09 --* C3 -Class09 --|> Class07 -Class07 : equals() -Class07 : Object[] elementData -Class01 : size() -Class01 : int chimp -Class01 : int gorilla -class Class10 { - int id - size() -} ---%%{init: {'config': {'wrap': true }}}%% - sequenceDiagram - participant A as Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be - A->>Bob: Hola - Bob-->A: Pasten ! --- gitGraph - commit id: "ZERO" - branch develop - commit id:"A" - checkout main - commit id:"ONE" - checkout develop - commit id:"B" - branch featureA - commit id:"FIX" - commit id: "FIX-2" - checkout main - commit id:"TWO" - cherry-pick id:"A" - commit id:"THREE" - cherry-pick id:"FIX" - checkout develop - commit id:"C" - merge featureA ---flowchart TD - A[Christmas] -->|Get money| B(Go shopping) - B --> C{Let me think} - C -->|One| D[Laptop] - C -->|Two| E[iPhone] - C -->|Three| F[fa:fa-car Car] --- classDiagram - Animal "1" <|-- Duck - Animal <|-- Fish - Animal <--o Zebra - Animal : +int age - Animal : +String gender - Animal: +isMammal() - Animal: +mate() - class Duck{ - +String beakColor - +swim() - +quack() - } - class Fish{ - -int sizeInFeet - -canEat() - } - class Zebra{ - +bool is_wild - +run() - } --- erDiagram - CAR ||--o{ NAMED-DRIVER : allows - CAR { - string registrationNumber - string make - string model - } - PERSON ||--o{ NAMED-DRIVER : is - PERSON { - string firstName - string lastName - int age - } -- - - -