Compare commits

..

63 Commits

Author SHA1 Message Date
Knut Sveidqvist
75f9de3d4a UPdated version to 10.2.3 2023-06-08 16:24:25 +02:00
Knut Sveidqvist
81e86bc87c Merge branch '10.2.2' into develop 2023-06-08 15:07:31 +02:00
Sidharth Vinod
f464212dc0 Merge pull request #4416 from MikeJeffers/bug/4408
Fix #4408: Handle wrapping long words
2023-06-08 11:46:09 +05:30
Sidharth Vinod
0ad084182a Remove old changelog 2023-06-08 11:42:14 +05:30
Sidharth Vinod
e2e9d0f1f3 Remove old changelog 2023-06-08 11:36:47 +05:30
Sidharth Vinod
ac488dd800 Merge branch 'develop' into pr/MikeJeffers/4416
* develop:
  Update docs
2023-06-08 11:13:51 +05:30
sidharthv96
d00d20fc37 Update docs 2023-06-07 18:49:51 +00:00
Sidharth Vinod
88b94dea66 Merge branch 'develop' into pr/MikeJeffers/4416
* develop: (45 commits)
  Add nextra to cSpell
  Update docs: Added Nextra to Blogs category on integrations page
  Render empty lines correctly
  Restore classes on edges for elk
  Update diagram proposal
  Update docs
  Added CKEditor and GitHub Writer to available integrations.
  Fix exceptions for empty lines
  chore(deps): update all patch dependencies
  build(deps): fix broken pnpm-lock.yaml file
  Mermaid version 10.2.0
  Mermaid Version 10.2.0-rc.4
  Label background fix
  Test commit
  Fix for regression error in sequenceDiagrams
  Update all minor dependencies
  Update all patch dependencies
  Update docs
  Add contributors profile url
  ignore ZenUML types
  ...
2023-06-08 00:16:49 +05:30
Sidharth Vinod
9896402be6 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into develop
* 'develop' of https://github.com/mermaid-js/mermaid:
  Update docs: Added Nextra to Blogs category on integrations page
2023-06-08 00:16:16 +05:30
Sidharth Vinod
e9b76bba9b Add nextra to cSpell 2023-06-08 00:16:12 +05:30
Sidharth Vinod
ad09d63f65 only split if string is over length. 2023-06-08 00:07:33 +05:30
Sidharth Vinod
af7531d08a Merge pull request #4463 from try-to-fly/add-nextra-to-blogs-integrations
Update docs: Added Nextra to Blogs category on integrations page
2023-06-07 20:28:40 +05:30
微笑
eef6745272 Update docs: Added Nextra to Blogs category on integrations page 2023-06-07 16:06:52 +08:00
mikejeffers
0cb6df1ef8 refactor text width computing func 2023-06-06 23:11:07 -04:00
Sidharth Vinod
f20ff4d580 Merge pull request #4436 from slab/zh-mermaid-empty-text
Fix exceptions for empty lines
2023-06-05 11:43:43 +05:30
Zihua Li
2a6603b33a Render empty lines correctly 2023-06-04 16:24:41 +08:00
Sidharth Vinod
6115f6976a Merge pull request #4452 from yoavst/feature/restore-classes-on-edges-for-elk
Restore classes on edges for elk
2023-06-04 12:02:54 +05:30
Yoav Sternberg
da1beb36bf Restore classes on edges for elk 2023-06-02 22:10:39 +03:00
Knut Sveidqvist
d2409dc163 Setting version to 10.2.2 2023-06-02 08:50:59 +02:00
Knut Sveidqvist
1b40f552b2 Merge pull request #4334 from mermaid-js/sidv/zenuml
Add `@mermaid-js/mermaid-zenuml` package for zenuml Integration
2023-06-02 08:41:49 +02:00
Knut Sveidqvist
5b696a72f8 Merge pull request #4448 from mermaid-js/sidv/diagramProposal
Update diagram proposal
2023-06-02 08:40:35 +02:00
Sidharth Vinod
d148a65967 Merge branch 'develop' into sidv/zenuml
* develop: (22 commits)
  Update docs
  Added CKEditor and GitHub Writer to available integrations.
  chore(deps): update all patch dependencies
  build(deps): fix broken pnpm-lock.yaml file
  Mermaid version 10.2.0
  Mermaid Version 10.2.0-rc.4
  Label background fix
  Test commit
  Fix for regression error in sequenceDiagrams
  Fix visibility issue for fields
  fix parsing issue with class diagrams
  fix: Use unicode arrows in quadrant chart axis
  fix: Use unicode arrows in quadrant chart axis
  fix lint command
  Bump version
  Back to JS with jsdoc types
  Add unsupported text
  Reduce changes in test
  Fix deps
  Fix lockfile
  ...
2023-06-02 11:59:12 +05:30
Sidharth Vinod
74ccf6410d Update diagram proposal 2023-06-02 11:50:49 +05:30
Knut Sveidqvist
7cdb15c526 Merge pull request #4447 from mermaid-js/4446-handling-of-arrowMarker-urls
#4446 Updating the cleanup criteria
2023-06-01 17:55:45 +02:00
Knut Sveidqvist
55092f532f #4446 Improved regular expression 2023-06-01 17:39:54 +02:00
Knut Sveidqvist
7b6cb4f974 #4446 Updating the cleanup criteria 2023-06-01 16:30:57 +02:00
Knut Sveidqvist
0cd1c5de97 Merge branch 'release/10.2.1' 2023-06-01 13:12:20 +02:00
sidharthv96
c2c8024718 Update docs 2023-05-31 11:11:04 +00:00
Sidharth Vinod
5338d90077 Merge pull request #4440 from AnnaTomanek/patch-1
Add CKEditor and GitHub Writer to available integrations
2023-05-31 16:36:30 +05:30
Anna Tomanek
180c695f2f Added CKEditor and GitHub Writer to available integrations. 2023-05-31 12:15:40 +02:00
Zihua Li
ce9bdcc53f Fix exceptions for empty lines 2023-05-29 21:00:37 +08:00
renovate[bot]
38d9ebc5da chore(deps): update all patch dependencies 2023-05-29 05:19:50 +00:00
Sidharth Vinod
5fd5de10b5 Merge pull request #4400 from mermaid-js/sidv/quadrantArrows
Quadrant chart unicode arrows
2023-05-26 17:21:26 +05:30
Alois Klink
cb2bc2a587 Merge pull request #4425 from aloisklink/chore/fix-broken-lockfile
Fix broken `pnpm-lock.yaml` file to fix CI
2023-05-24 23:03:54 +01:00
Sidharth Vinod
102b9bc8c3 Merge branch 'develop' into sidv/zenuml
* develop:
  Update all minor dependencies
  Update all patch dependencies
2023-05-23 10:36:02 +05:30
Sidharth Vinod
9cec5ae1c4 Merge branch 'sidv/zenuml' of https://github.com/mermaid-js/mermaid into sidv/zenuml
* 'sidv/zenuml' of https://github.com/mermaid-js/mermaid:
  Update docs
  Add contributors profile url
  ignore ZenUML types
  fixed typo and update peerDependencies version
  update pnpm-lock.yaml
  Address mermaid-zenuml PR comments
  Update all minor dependencies
  Update all patch dependencies
  Fix vitepress build
2023-05-23 10:34:08 +05:30
mikejeffers
496585b543 handle trailing whitespace on lines 2023-05-20 16:04:58 -04:00
mikejeffers
9e6168111f add e2e test 2023-05-20 15:20:28 -04:00
mikejeffers
f535640c1e Fixes #4408: solve infinite loop on words that exceed width constraint with word break 2023-05-20 14:59:04 -04:00
Alois Klink
acc19db5bb Merge branch 'develop' into sidv/zenuml
Conflicts:
	pnpm-lock.yaml
2023-05-17 19:59:58 +01:00
aloisklink
6cce1b20fb Update docs 2023-05-17 18:46:58 +00:00
dontry
a00616863d Add contributors profile url 2023-05-17 19:26:43 +01:00
dontry
49c97dad4c ignore ZenUML types 2023-05-17 19:26:43 +01:00
Alois Klink
e984b34af4 Merge branch 'develop' into sidv/zenuml
* develop: (66 commits)
  Update docs
  Update docs
  Improve the wording of security level values
  Added quadrantChart to the side bar
  Added e2e test cases with some fixes
  Added documentation for the quadrantChart
  Restructured the build function and addressed more review comment
  Fixed some parser issue and added test cases for the parser
  Fixed review comment
  Update docs
  Converted files to typescript and added proper types
  Fix blog linting
  Debug fetch-contributors
  Fix lockfile
  Revert "Replace esno & ts-node with tsx"
  [draft] Added support for quadrant chart
  Fix lockfile
  Fix build
  Update pnpm-lock
  Replace esno & ts-node with tsx
  ...

Merge conflicts:
  - pnpm-lock.yaml
2023-05-17 19:25:29 +01:00
Sidharth Vinod
c255d95ae2 Merge pull request #4405 from ZenUml/dongc/zenuml
Address mermaid-zenuml PR comments
2023-05-17 19:10:25 +01:00
Dong Cai
27e59e5adc fixed typo and update peerDependencies version 2023-05-17 19:10:19 +01:00
Dong Cai
507e24cc72 update pnpm-lock.yaml 2023-05-17 19:10:03 +01:00
Dong Cai
bb400d53b9 Address mermaid-zenuml PR comments 2023-05-17 19:09:48 +01:00
Sidharth Vinod
6a89ef94f7 Cleanup 2023-05-17 11:21:03 +05:30
Sidharth Vinod
97be4983f0 Merge branch 'develop' into sidv/zenuml
* develop: (66 commits)
  Update docs
  Update docs
  Improve the wording of security level values
  Added quadrantChart to the side bar
  Added e2e test cases with some fixes
  Added documentation for the quadrantChart
  Restructured the build function and addressed more review comment
  Fixed some parser issue and added test cases for the parser
  Fixed review comment
  Update docs
  Converted files to typescript and added proper types
  Fix blog linting
  Debug fetch-contributors
  Fix lockfile
  Revert "Replace esno & ts-node with tsx"
  [draft] Added support for quadrant chart
  Fix lockfile
  Fix build
  Update pnpm-lock
  Replace esno & ts-node with tsx
  ...
2023-05-16 23:26:35 +05:30
Sidharth Vinod
c7affbe33b Merge pull request #4405 from ZenUml/dongc/zenuml
Address mermaid-zenuml PR comments
2023-05-16 23:25:29 +05:30
Dong Cai
82eccb70fa fixed typo and update peerDependencies version 2023-05-16 23:41:53 +10:00
Dong Cai
c889ef0c30 update pnpm-lock.yaml 2023-05-16 21:08:25 +10:00
Dong Cai
cce5505662 Address mermaid-zenuml PR comments 2023-05-16 20:30:25 +10:00
Sidharth Vinod
b925849893 fix: Use unicode arrows in quadrant chart axis 2023-05-15 13:36:35 +05:30
Sidharth Vinod
d86d1e7887 fix: Use unicode arrows in quadrant chart axis 2023-05-15 13:32:59 +05:30
Sidharth Vinod
a01343bf1b Fix lockfile 2023-04-27 10:37:35 +05:30
Sidharth Vinod
88f9233aa8 Merge branch 'develop' into sidv/zenuml
* develop:
  submit built docs
  update Font Awesome Version
  Clarify FontAwesome support
2023-04-27 10:36:16 +05:30
Sidharth Vinod
8cd48bf405 Add docs 2023-04-26 00:31:00 +05:30
Sidharth Vinod
8b18fd93f4 Add test 2023-04-26 00:20:00 +05:30
Sidharth Vinod
ec62c2bf5b Merge branch 'develop' into sidv/zenuml
* develop: (33 commits)
  Update version
  Fix classParser
  Check for conflict when linting jison
  Update class grammar test
  fix Class diagram grammar
  Skip sourcemap
  Bump version
  Update deps
  Fix unit tests
  Update vite
  Fix applitools cypress
  Update packages/mermaid/package.json
  chore(deps): update dependency typescript to v5
  fix typedoc
  fix(deps): update all minor dependencies
  chore(deps): update pnpm to v8
  chore(deps): update fregante/setup-git-user action to v2
  fix(deps): update all minor dependencies
  chore(deps): update dependency start-server-and-test to v2
  chore(deps): update dependency rimraf to v5
  ...
2023-04-26 00:15:52 +05:30
Sidharth Vinod
b9e7ba023f Update ZenUML 2023-04-26 00:12:39 +05:30
Sidharth Vinod
12ed81855a Add zenuml 2023-04-23 00:34:59 +05:30
46 changed files with 1750 additions and 2282 deletions

View File

@@ -4,4 +4,5 @@ docs/Setup.md
cypress.config.js
cypress/plugins/index.js
coverage
*.json
*.json
node_modules

View File

@@ -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.

View File

@@ -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' }));

View File

@@ -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'));

View File

@@ -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": "" },

View File

@@ -60,7 +60,7 @@ export const renderGraph = (graphStr, options, api) => {
openURLAndVerifyRendering(url, options);
};
const openURLAndVerifyRendering = (url, options, validation = undefined) => {
export const openURLAndVerifyRendering = (url, options, validation = undefined) => {
const useAppli = Cypress.env('useAppli');
const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');

View File

@@ -1,4 +1,4 @@
import { urlSnapshotTest } from '../../helpers/util.js';
import { urlSnapshotTest, openURLAndVerifyRendering } from '../../helpers/util.js';
describe('CSS injections', () => {
it('should not allow CSS injections outside of the diagram', () => {
@@ -13,4 +13,11 @@ describe('CSS injections', () => {
flowchart: { htmlLabels: false },
});
});
it('should not allow manipulating styletags using arrowheads', () => {
openURLAndVerifyRendering('http://localhost:9000/xss23-css.html', {
logLevel: 1,
arrowMarkerAbsolute: false,
flowchart: { htmlLabels: true },
});
});
});

View File

@@ -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', () => {

View File

@@ -52,6 +52,17 @@ root[A root with a long text that wraps to keep the node size in check]
);
});
it('a root with wrapping text and long words that exceed width', () => {
imgSnapshotTest(
`mindmap
root[A few smaller words but then averylongsetofcharacterswithoutwhitespacetoseparate that we expect to wrapontonextlinesandnotexceedwidthparameters]
`,
{},
undefined,
shouldHaveRoot
);
});
it('a root with an icon', () => {
imgSnapshotTest(
`mindmap

View File

@@ -88,6 +88,16 @@ context('Sequence diagram', () => {
{}
);
});
it('should handle empty lines', () => {
imgSnapshotTest(
`
sequenceDiagram
Alice->>John: Hello John<br/>
John-->>Alice: Great<br/><br/>day!
`,
{}
);
});
it('should handle line breaks and wrap annotations', () => {
imgSnapshotTest(
`

View File

@@ -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 }
}
}
}
`,
{}
);
});
});

View File

@@ -1,5 +1,6 @@
import mermaid2 from './mermaid.esm.mjs';
import externalExample from '../../packages/mermaid-example-diagram/dist/mermaid-example-diagram.core.mjs';
import zenUml from '../../packages/mermaid-zenuml/dist/mermaid-zenuml.core.mjs';
function b64ToUtf8(str) {
return decodeURIComponent(escape(window.atob(str)));
@@ -44,7 +45,7 @@ const contentLoaded = async function () {
document.getElementsByTagName('body')[0].appendChild(div);
}
await mermaid2.registerExternalDiagrams([externalExample]);
await mermaid2.registerExternalDiagrams([externalExample, zenUml]);
mermaid2.initialize(graphObj.mermaid);
await mermaid2.run();
}

View File

@@ -0,0 +1,85 @@
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
rel="stylesheet"
/>
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 {
color: grey;
}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
}
.malware {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
}
</style>
</head>
<body>
<div>Security check</div>
<div class="flex">
<div id="diagram" class="mermaid"></div>
<div id="graph-div"></div>
<div id="res" class=""></div>
</div>
<script type="module">
import mermaid from './mermaid.esm.mjs';
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'base',
startOnLoad: false,
flowcharts: { htmlLabels: true },
});
function callback() {
alert('It worked');
}
function xssAttack() {
const div = document.createElement('div');
div.id = 'the-malware';
div.className = 'malware';
div.innerHTML = 'XSS Succeeded';
document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeeded');
}
let diagram = `graph TD
A[["a marker-end=#quot;url(<s title='#<style>*{background:red}</style>'>b"]]
`;
const el = document.querySelector('#graph-div');
console.log(diagram);
const { svg } = await mermaid.render('graph-div', diagram);
document.querySelector('#res').innerHTML = svg;
window.rendered = true;
</script>
</body>
</html>

View File

@@ -66,6 +66,9 @@
<li>
<h2><a href="./state.html">State</a></h2>
</li>
<li>
<h2><a href="./zenuml.html">ZenUML</a></h2>
</li>
</ul>
</body>
</html>

53
demos/zenuml.html Normal file
View File

@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Mermaid Zenuml Test Page</title>
</head>
<body>
<h1>Zenuml demos</h1>
<pre class="mermaid">
zenuml
title Sync Messages (Design Pattern: Adapter)
@Starter(Client)
Adapter.interfaceMethod() {
translateParameter(parameter)
result = Implementation.implementationMethod()
translateResult()
return translatedResult
}
</pre>
<pre class="mermaid">
zenuml
title Async Messages (SPA Authentication)
// ```
// GET https://${account.namespace}/authorize/?
// response_type=token
// &client_id=${account.clientId}
// &redirect_url=YOUR_CALLBACK_URL
// &state=VALUE_THAT_SURVIVES_REDIRECTS
// &scope=openid
// ```
Browser->Auth0: 1. initiate the authentication
Auth0->"Identity Provider": 2. OAuth2 / SAML, etc
"Identity Provider"->"Identity Provider": 3. user gets authenticated
Auth0->Browser: 4. redirect to ${YOUR_CALLBACK_URL}/#id_token=e68...
Browser->Auth0: 5. validate id_token and get user profile
Browser->"Your API": 6. call API sending JWT in Authorization header
"Your API"->"Your API": 7. validate token
</pre>
<script type="module">
import mermaid from './mermaid.esm.mjs';
import zenuml from './mermaid-zenuml.esm.mjs';
await mermaid.registerExternalDiagrams([zenuml]);
mermaid.initialize({
logLevel: 3,
});
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -96,7 +96,7 @@ mermaid.initialize(config);
#### Defined in
[mermaidAPI.ts:667](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L667)
[mermaidAPI.ts:670](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L670)
## Functions
@@ -127,7 +127,7 @@ Return the last node appended
#### Defined in
[mermaidAPI.ts:306](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L306)
[mermaidAPI.ts:309](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L309)
---
@@ -295,7 +295,7 @@ Put the svgCode into an iFrame. Return the iFrame code
#### Defined in
[mermaidAPI.ts:285](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L285)
[mermaidAPI.ts:288](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L288)
---
@@ -320,4 +320,4 @@ Remove any existing elements from the given document
#### Defined in
[mermaidAPI.ts:356](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L356)
[mermaidAPI.ts:359](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L359)

View File

@@ -16,6 +16,7 @@ They also serve as proof of concept, for the variety of things that can be built
- [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) (**Native support**)
- [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
- [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
- [GitHub Writer](https://github.com/ckeditor/github-writer)
- [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) (**Native support**)
- [Gitea](https://gitea.io) (**Native support**)
- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) (**Native support**)
@@ -58,6 +59,8 @@ They also serve as proof of concept, for the variety of things that can be built
- [hexo-filter-mermaid-diagrams](https://github.com/webappdevelp/hexo-filter-mermaid-diagrams)
- [hexo-tag-mermaid](https://github.com/JameChou/hexo-tag-mermaid)
- [hexo-mermaid-diagrams](https://github.com/mslxl/hexo-mermaid-diagrams)
- [Nextra](https://nextra.site/)
- [Mermaid](https://nextra.site/docs/guide/mermaid)
## CMS
@@ -142,6 +145,8 @@ They also serve as proof of concept, for the variety of things that can be built
- [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
- [GNU Nano](https://www.nano-editor.org/)
- [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
- [CKEditor](https://github.com/ckeditor/ckeditor5)
- [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
## Document Generation

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

472
docs/syntax/zenuml.md Normal file
View File

@@ -0,0 +1,472 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/zenuml.md](../../packages/mermaid/src/docs/syntax/zenuml.md).
# ZenUML
> A Sequence diagram is an interaction diagram that shows how processes operate with one another and in what order.
Mermaid can render sequence diagrams with [ZenUML](https://zenuml.com). Note that ZenUML uses a different
syntax than the original Sequence Diagram in mermaid.
```mermaid-example
zenuml
title Demo
Alice->John: Hello John, how are you?
John->Alice: Great!
Alice->John: See you later!
```
```mermaid
zenuml
title Demo
Alice->John: Hello John, how are you?
John->Alice: Great!
Alice->John: See you later!
```
## Syntax
### Participants
The participants can be defined implicitly as in the first example on this page. The participants or actors are
rendered in order of appearance in the diagram source text. Sometimes you might want to show the participants in a
different order than how they appear in the first message. It is possible to specify the actor's order of
appearance by doing the following:
```mermaid-example
zenuml
title Declare participant (optional)
Bob
Alice
Alice->Bob: Hi Bob
Bob->Alice: Hi Alice
```
```mermaid
zenuml
title Declare participant (optional)
Bob
Alice
Alice->Bob: Hi Bob
Bob->Alice: Hi Alice
```
### Annotators
If you specifically want to use symbols instead of just rectangles with text you can do so by using the annotator syntax to declare participants as per below.
```mermaid-example
zenuml
title Annotators
@Actor Alice
@Database Bob
Alice->Bob: Hi Bob
Bob->Alice: Hi Alice
```
```mermaid
zenuml
title Annotators
@Actor Alice
@Database Bob
Alice->Bob: Hi Bob
Bob->Alice: Hi Alice
```
Here are the available annotators:
![img.png](img/zenuml-participant-annotators.png)
### Aliases
The participants can have a convenient identifier and a descriptive label.
```mermaid-example
zenuml
title Aliases
A as Alice
J as John
A->J: Hello John, how are you?
J->A: Great!
```
```mermaid
zenuml
title Aliases
A as Alice
J as John
A->J: Hello John, how are you?
J->A: Great!
```
## Messages
Messages can be one of:
1. Sync message
2. Async message
3. Creation message
4. Reply message
### Sync message
You can think of a sync (blocking) method in a programming language.
```mermaid-example
zenuml
title Sync message
A.SyncMessage
A.SyncMessage(with, parameters) {
B.nestedSyncMessage()
}
```
```mermaid
zenuml
title Sync message
A.SyncMessage
A.SyncMessage(with, parameters) {
B.nestedSyncMessage()
}
```
### Async message
You can think of an async (non-blocking) method in a programming language.
Fire an event and forget about it.
```mermaid-example
zenuml
title Async message
Alice->Bob: How are you?
```
```mermaid
zenuml
title Async message
Alice->Bob: How are you?
```
### Creation message
We use `new` keyword to create an object.
```mermaid-example
zenuml
new A1
new A2(with, parameters)
```
```mermaid
zenuml
new A1
new A2(with, parameters)
```
### Reply message
There are three ways to express a reply message:
```mermaid-example
zenuml
// 1. assign a variable from a sync message.
a = A.SyncMessage()
// 1.1. optionally give the variable a type
SomeType a = A.SyncMessage()
// 2. use return keyword
A.SyncMessage() {
return result
}
// 3. use @return or @reply annotator on an async message
@return
A->B: result
```
```mermaid
zenuml
// 1. assign a variable from a sync message.
a = A.SyncMessage()
// 1.1. optionally give the variable a type
SomeType a = A.SyncMessage()
// 2. use return keyword
A.SyncMessage() {
return result
}
// 3. use @return or @reply annotator on an async message
@return
A->B: result
```
The third way `@return` is rarely used, but it is useful when you want to return to one level up.
```mermaid-example
zenuml
title Reply message
Client->A.method() {
B.method() {
if(condition) {
return x1
// return early
@return
A->Client: x11
}
}
return x2
}
```
```mermaid
zenuml
title Reply message
Client->A.method() {
B.method() {
if(condition) {
return x1
// return early
@return
A->Client: x11
}
}
return x2
}
```
## Nesting
Sync messages and Creation messages are naturally nestable with `{}`.
```mermaid-example
zenuml
A.method() {
B.nested_sync_method()
B->C: nested async message
}
```
```mermaid
zenuml
A.method() {
B.nested_sync_method()
B->C: nested async message
}
```
## Comments
It is possible to add comments to a sequence diagram with `// comment` syntax.
Comments will be rendered above the messages or fragments. Comments on other places
are ignored. Markdown is supported.
See the example below:
```mermaid-example
zenuml
// a comment on a participant will not be rendered
BookService
// a comment on a message.
// **Markdown** is supported.
BookService.getBook()
```
```mermaid
zenuml
// a comment on a participant will not be rendered
BookService
// a comment on a message.
// **Markdown** is supported.
BookService.getBook()
```
## Loops
It is possible to express loops in a ZenUML diagram. This is done by any of the
following notations:
1. while
2. for
3. forEach, foreach
4. loop
```zenuml
while(condition) {
...statements...
}
```
See the example below:
```mermaid-example
zenuml
Alice->John: Hello John, how are you?
while(true) {
John->Alice: Great!
}
```
```mermaid
zenuml
Alice->John: Hello John, how are you?
while(true) {
John->Alice: Great!
}
```
## Alt
It is possible to express alternative paths in a sequence diagram. This is done by the notation
```zenuml
if(condition1) {
...statements...
} else if(condition2) {
...statements...
} else {
...statements...
}
```
See the example below:
```mermaid-example
zenuml
Alice->Bob: Hello Bob, how are you?
if(is_sick) {
Bob->Alice: Not so good :(
} else {
Bob->Alice: Feeling fresh like a daisy
}
```
```mermaid
zenuml
Alice->Bob: Hello Bob, how are you?
if(is_sick) {
Bob->Alice: Not so good :(
} else {
Bob->Alice: Feeling fresh like a daisy
}
```
## Opt
It is possible to render an `opt` fragment. This is done by the notation
```zenuml
opt {
...statements...
}
```
See the example below:
```mermaid-example
zenuml
Alice->Bob: Hello Bob, how are you?
Bob->Alice: Not so good :(
opt {
Bob->Alice: Thanks for asking
}
```
```mermaid
zenuml
Alice->Bob: Hello Bob, how are you?
Bob->Alice: Not so good :(
opt {
Bob->Alice: Thanks for asking
}
```
## Parallel
It is possible to show actions that are happening in parallel.
This is done by the notation
```zenuml
par {
statement1
statement2
statement3
}
```
See the example below:
```mermaid-example
zenuml
par {
Alice->Bob: Hello guys!
Alice->John: Hello guys!
}
```
```mermaid
zenuml
par {
Alice->Bob: Hello guys!
Alice->John: Hello guys!
}
```
## Try/Catch/Finally (Break)
It is possible to indicate a stop of the sequence within the flow (usually used to model exceptions).
This is done by the notation
try {
...statements...
} catch {
...statements...
} finally {
...statements...
}
See the example below:
```mermaid-example
zenuml
try {
Consumer->API: Book something
API->BookingService: Start booking process
} catch {
API->Consumer: show failure
} finally {
API->BookingService: rollback status
}
```
```mermaid
zenuml
try {
Consumer->API: Book something
API->BookingService: Start booking process
} catch {
API->Consumer: show failure
} finally {
API->BookingService: rollback status
}
```
## Integrating with your library/website.
Zenuml uses the experimental lazy loading & async rendering features which could change in the future.
You can use this method to add mermaid including the zenuml diagram to a web page:
```html
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
import zenuml from 'https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-zenuml@0.1.0/dist/mermaid-zenuml.esm.min.mjs';
await mermaid.registerExternalDiagrams([zenuml]);
</script>
```

View File

@@ -1,7 +1,7 @@
{
"name": "mermaid-monorepo",
"private": true,
"version": "10.2.1",
"version": "10.2.3",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module",
"packageManager": "pnpm@8.5.1",
@@ -18,7 +18,7 @@
"build:vite": "ts-node-esm --transpileOnly .vite/build.ts",
"build:mermaid": "pnpm build:vite --mermaid",
"build:viz": "pnpm build:mermaid --visualize",
"build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-example-diagram/tsconfig.json --emitDeclarationOnly",
"build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-zenuml/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-example-diagram/tsconfig.json --emitDeclarationOnly",
"build:watch": "pnpm build:vite --watch",
"build": "pnpm run -r clean && pnpm build:types && pnpm build:vite",
"dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server.ts\"",

View File

@@ -0,0 +1 @@
../mermaid/src/docs/syntax/zenuml.md

View File

@@ -0,0 +1,47 @@
{
"name": "@mermaid-js/mermaid-zenuml",
"version": "0.1.0",
"description": "MermaidJS plugin for ZenUML integration",
"module": "dist/mermaid-zenuml.core.mjs",
"types": "dist/detector.d.ts",
"type": "module",
"exports": {
".": {
"import": "./dist/mermaid-zenuml.core.mjs",
"types": "./dist/detector.d.ts"
},
"./*": "./*"
},
"keywords": [
"diagram",
"markdown",
"zenuml",
"mermaid"
],
"scripts": {
"prepublishOnly": "pnpm -w run build"
},
"repository": {
"type": "git",
"url": "https://github.com/mermaid-js/mermaid",
"directory": "packages/mermaid-zenuml"
},
"contributors": [
"Peng Xiao (https://github.com/MrCoder)",
"Sidharth Vinod (https://sidharth.dev)",
"Dong Cai (https://github.com/dontry)"
],
"license": "MIT",
"dependencies": {
"@zenuml/core": "^3.0.0"
},
"devDependencies": {
"mermaid": "workspace:^"
},
"peerDependencies": {
"mermaid": "workspace:>=10.0.0"
},
"files": [
"dist"
]
}

View File

@@ -0,0 +1,21 @@
import type { ExternalDiagramDefinition } from 'mermaid';
const id = 'zenuml';
const regexp = /^\s*zenuml/;
const detector = (txt: string) => {
return txt.match(regexp) !== null;
};
const loader = async () => {
const { diagram } = await import('./zenuml-definition.js');
return { id, diagram };
};
const plugin: ExternalDiagramDefinition = {
id,
detector,
loader,
};
export default plugin;

View File

@@ -0,0 +1,58 @@
import type { MermaidConfig } from 'mermaid';
const warning = (s: string) => {
// Todo remove debug code
// eslint-disable-next-line no-console
console.error('Log function was called before initialization', s);
};
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
export const LEVELS: Record<LogLevel, number> = {
trace: 0,
debug: 1,
info: 2,
warn: 3,
error: 4,
fatal: 5,
};
export const log: Record<keyof typeof LEVELS, typeof console.log> = {
trace: warning,
debug: warning,
info: warning,
warn: warning,
error: warning,
fatal: warning,
};
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
export let getConfig: () => MermaidConfig;
export let sanitizeText: (str: string) => string;
// eslint-disable @typescript-eslint/no-explicit-any
export let setupGraphViewbox: (
graph: any,
svgElem: any,
padding: any,
useMaxWidth: boolean
) => void;
export const injectUtils = (
_log: Record<keyof typeof LEVELS, typeof console.log>,
_setLogLevel: any,
_getConfig: any,
_sanitizeText: any,
_setupGraphViewbox: any
) => {
_log.info('Mermaid utils injected');
log.trace = _log.trace;
log.debug = _log.debug;
log.info = _log.info;
log.warn = _log.warn;
log.error = _log.error;
log.fatal = _log.fatal;
setLogLevel = _setLogLevel;
getConfig = _getConfig;
sanitizeText = _sanitizeText;
setupGraphViewbox = _setupGraphViewbox;
};

View File

@@ -0,0 +1,12 @@
/**
* ZenUML manage parsing internally. It uses Antlr4 to parse the DSL.
* The parser is defined in https://github.com/ZenUml/vue-sequence/blob/main/src/parser/index.js
*
* This is a dummy parser that satisfies the mermaid API logic.
*/
export default {
parser: { yy: {} },
parse: () => {
// no op
},
};

View File

@@ -0,0 +1,17 @@
import { injectUtils } from './mermaidUtils.js';
import parser from './parser.js';
import renderer from './zenumlRenderer.js';
export const diagram = {
db: {
clear: () => {
// no-op
},
},
renderer,
parser,
styles: () => {
// no-op
},
injectUtils,
};

View File

@@ -0,0 +1,68 @@
import { getConfig, log } from './mermaidUtils.js';
import ZenUml from '@zenuml/core';
const regexp = /^\s*zenuml/;
// Create a Zen UML container outside the svg first for rendering, otherwise the Zen UML diagram cannot be rendered properly
function createTemporaryZenumlContainer(id: string) {
const container = document.createElement('div');
container.id = `container-${id}`;
container.style.display = 'flex';
container.innerHTML = `<div id="zenUMLApp-${id}"></div>`;
const app = container.querySelector(`#zenUMLApp-${id}`) as HTMLElement;
return { container, app };
}
// Create a foreignObject to wrap the Zen UML container in the svg
function createForeignObject(id: string) {
const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
foreignObject.setAttribute('x', '0');
foreignObject.setAttribute('y', '0');
foreignObject.setAttribute('width', '100%');
foreignObject.setAttribute('height', '100%');
const { container, app } = createTemporaryZenumlContainer(id);
foreignObject.appendChild(container);
return { foreignObject, container, app };
}
/**
* Draws a Zen UML in the tag with id: id based on the graph definition in text.
*
* @param text - The text of the diagram
* @param id - The id of the diagram which will be used as a DOM element id¨
*/
export const draw = async function (text: string, id: string) {
log.info('draw with Zen UML renderer', ZenUml);
text = text.replace(regexp, '');
const { securityLevel } = getConfig();
// Handle root and Document for when rendering in sandbox mode
let sandboxElement: HTMLIFrameElement | null = null;
if (securityLevel === 'sandbox') {
sandboxElement = document.getElementById('i' + id) as HTMLIFrameElement;
}
const root = securityLevel === 'sandbox' ? sandboxElement?.contentWindow?.document : document;
const svgContainer = root?.querySelector(`svg#${id}`);
if (!root || !svgContainer) {
log.error('Cannot find root or svgContainer');
return;
}
const { foreignObject, container, app } = createForeignObject(id);
svgContainer.appendChild(foreignObject);
// @ts-expect-error @zenuml/core@3.0.0 exports the wrong type for ZenUml
const zenuml = new ZenUml(app);
// default is a theme name. More themes to be added and will be configurable in the future
await zenuml.render(text, 'theme-mermaid');
const { width, height } = window.getComputedStyle(container);
log.debug('zenuml diagram size', width, height);
svgContainer.setAttribute('style', `width: ${width}; height: ${height};`);
};
export default {
draw,
};

View File

@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["./src/**/*.ts"],
"typeRoots": ["./src/types"]
}

View File

@@ -1,6 +1,6 @@
{
"name": "mermaid",
"version": "10.2.1",
"version": "10.2.3",
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module",
"module": "./dist/mermaid.core.mjs",

View File

@@ -717,7 +717,7 @@ const insertEdge = function (edgesEl, edge, edgeData, diagObj, parentLookupDb) {
const edgePath = edgesEl
.insert('path')
.attr('d', curve(points))
.attr('class', 'path')
.attr('class', 'path ' + edgeData.classes)
.attr('fill', 'none');
const edgeG = edgesEl.insert('g').attr('class', 'edgeLabel');
const edgeWithLabel = select(edgeG.node().appendChild(edge.labelEl));

View File

@@ -119,10 +119,10 @@ points
axisDetails
: X-AXIS text AXIS-TEXT-DELIMITER text {yy.setXAxisLeftText($2); yy.setXAxisRightText($4);}
| X-AXIS text AXIS-TEXT-DELIMITER {$2.text += $3; yy.setXAxisLeftText($2);}
| X-AXIS text AXIS-TEXT-DELIMITER {$2.text += " ⟶ "; yy.setXAxisLeftText($2);}
| X-AXIS text {yy.setXAxisLeftText($2);}
| Y-AXIS text AXIS-TEXT-DELIMITER text {yy.setYAxisBottomText($2); yy.setYAxisTopText($4);}
| Y-AXIS text AXIS-TEXT-DELIMITER {$2.text += $3; yy.setYAxisBottomText($2);}
| Y-AXIS text AXIS-TEXT-DELIMITER {$2.text += " ⟶ "; yy.setYAxisBottomText($2);}
| Y-AXIS text {yy.setYAxisBottomText($2);}
;

View File

@@ -93,7 +93,7 @@ describe('Testing quadrantChart jison file', () => {
str = 'quadrantChart\n x-AxIs "Urgent(* +=[❤" --> ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisLeftText).toHaveBeenCalledWith({
text: 'Urgent(* +=[❤ --> ',
text: 'Urgent(* +=[❤ ',
type: 'text',
});
expect(mockDB.setXAxisRightText).not.toHaveBeenCalled();
@@ -131,7 +131,7 @@ describe('Testing quadrantChart jison file', () => {
str = 'quadrantChart\n y-AxIs "Urgent(* +=[❤" --> ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisBottomText).toHaveBeenCalledWith({
text: 'Urgent(* +=[❤ --> ',
text: 'Urgent(* +=[❤ ',
type: 'text',
});
expect(mockDB.setYAxisTopText).not.toHaveBeenCalled();

View File

@@ -1,7 +1,7 @@
import common from '../common/common.js';
import * as svgDrawCommon from '../common/svgDrawCommon';
import { addFunction } from '../../interactionDb.js';
import { parseFontSize } from '../../utils.js';
import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js';
import { sanitizeUrl } from '@braintree/sanitize-url';
export const drawRect = function (elem, rectData) {
@@ -224,15 +224,16 @@ export const drawText = function (elem, textData) {
textElem.attr('dy', dy);
}
const text = line || ZERO_WIDTH_SPACE;
if (textData.tspan) {
const span = textElem.append('tspan');
span.attr('x', textData.x);
if (textData.fill !== undefined) {
span.attr('fill', textData.fill);
}
span.text(line);
span.text(text);
} else {
textElem.text(line);
textElem.text(text);
}
if (
textData.valign !== undefined &&

View File

@@ -121,6 +121,7 @@ function sidebarSyntax() {
{ text: 'C4C Diagram (Context) Diagram 🦺⚠️', link: '/syntax/c4c' },
{ text: 'Mindmaps 🔥', link: '/syntax/mindmap' },
{ text: 'Timeline 🔥', link: '/syntax/timeline' },
{ text: 'Zenuml 🔥', link: '/syntax/zenuml' },
{ text: 'Other Examples', link: '/syntax/examples' },
],
},

View File

@@ -1,6 +1,10 @@
import mermaid, { type MermaidConfig } from 'mermaid';
import zenuml from '../../../../../mermaid-zenuml/dist/mermaid-zenuml.core.mjs';
const init = mermaid.registerExternalDiagrams([zenuml]);
export const render = async (id: string, code: string, config: MermaidConfig): Promise<string> => {
await init;
mermaid.initialize(config);
const { svg } = await mermaid.render(id, code);
return svg;

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@ They also serve as proof of concept, for the variety of things that can be built
- [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) (**Native support**)
- [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
- [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
- [GitHub Writer](https://github.com/ckeditor/github-writer)
- [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) (**Native support**)
- [Gitea](https://gitea.io) (**Native support**)
- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) (**Native support**)
@@ -52,6 +53,8 @@ They also serve as proof of concept, for the variety of things that can be built
- [hexo-filter-mermaid-diagrams](https://github.com/webappdevelp/hexo-filter-mermaid-diagrams)
- [hexo-tag-mermaid](https://github.com/JameChou/hexo-tag-mermaid)
- [hexo-mermaid-diagrams](https://github.com/mslxl/hexo-mermaid-diagrams)
- [Nextra](https://nextra.site/)
- [Mermaid](https://nextra.site/docs/guide/mermaid)
## CMS
@@ -136,6 +139,8 @@ They also serve as proof of concept, for the variety of things that can be built
- [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
- [GNU Nano](https://www.nano-editor.org/)
- [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
- [CKEditor](https://github.com/ckeditor/ckeditor5)
- [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
## Document Generation

View File

@@ -30,7 +30,7 @@
"unplugin-vue-components": "^0.24.1",
"vite": "^4.3.3",
"vite-plugin-pwa": "^0.15.0",
"vitepress": "1.0.0-alpha.76",
"vitepress": "1.0.0-beta.1",
"workbox-window": "^6.5.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

View File

@@ -0,0 +1,314 @@
# ZenUML
> A Sequence diagram is an interaction diagram that shows how processes operate with one another and in what order.
Mermaid can render sequence diagrams with [ZenUML](https://zenuml.com). Note that ZenUML uses a different
syntax than the original Sequence Diagram in mermaid.
```mermaid-example
zenuml
title Demo
Alice->John: Hello John, how are you?
John->Alice: Great!
Alice->John: See you later!
```
## Syntax
### Participants
The participants can be defined implicitly as in the first example on this page. The participants or actors are
rendered in order of appearance in the diagram source text. Sometimes you might want to show the participants in a
different order than how they appear in the first message. It is possible to specify the actor's order of
appearance by doing the following:
```mermaid-example
zenuml
title Declare participant (optional)
Bob
Alice
Alice->Bob: Hi Bob
Bob->Alice: Hi Alice
```
### Annotators
If you specifically want to use symbols instead of just rectangles with text you can do so by using the annotator syntax to declare participants as per below.
```mermaid-example
zenuml
title Annotators
@Actor Alice
@Database Bob
Alice->Bob: Hi Bob
Bob->Alice: Hi Alice
```
Here are the available annotators:
![img.png](img/zenuml-participant-annotators.png)
### Aliases
The participants can have a convenient identifier and a descriptive label.
```mermaid-example
zenuml
title Aliases
A as Alice
J as John
A->J: Hello John, how are you?
J->A: Great!
```
## Messages
Messages can be one of:
1. Sync message
2. Async message
3. Creation message
4. Reply message
### Sync message
You can think of a sync (blocking) method in a programming language.
```mermaid-example
zenuml
title Sync message
A.SyncMessage
A.SyncMessage(with, parameters) {
B.nestedSyncMessage()
}
```
### Async message
You can think of an async (non-blocking) method in a programming language.
Fire an event and forget about it.
```mermaid-example
zenuml
title Async message
Alice->Bob: How are you?
```
### Creation message
We use `new` keyword to create an object.
```mermaid-example
zenuml
new A1
new A2(with, parameters)
```
### Reply message
There are three ways to express a reply message:
```mermaid-example
zenuml
// 1. assign a variable from a sync message.
a = A.SyncMessage()
// 1.1. optionally give the variable a type
SomeType a = A.SyncMessage()
// 2. use return keyword
A.SyncMessage() {
return result
}
// 3. use @return or @reply annotator on an async message
@return
A->B: result
```
The third way `@return` is rarely used, but it is useful when you want to return to one level up.
```mermaid-example
zenuml
title Reply message
Client->A.method() {
B.method() {
if(condition) {
return x1
// return early
@return
A->Client: x11
}
}
return x2
}
```
## Nesting
Sync messages and Creation messages are naturally nestable with `{}`.
```mermaid-example
zenuml
A.method() {
B.nested_sync_method()
B->C: nested async message
}
```
## Comments
It is possible to add comments to a sequence diagram with `// comment` syntax.
Comments will be rendered above the messages or fragments. Comments on other places
are ignored. Markdown is supported.
See the example below:
```mermaid-example
zenuml
// a comment on a participant will not be rendered
BookService
// a comment on a message.
// **Markdown** is supported.
BookService.getBook()
```
## Loops
It is possible to express loops in a ZenUML diagram. This is done by any of the
following notations:
1. while
2. for
3. forEach, foreach
4. loop
```zenuml
while(condition) {
...statements...
}
```
See the example below:
```mermaid-example
zenuml
Alice->John: Hello John, how are you?
while(true) {
John->Alice: Great!
}
```
## Alt
It is possible to express alternative paths in a sequence diagram. This is done by the notation
```zenuml
if(condition1) {
...statements...
} else if(condition2) {
...statements...
} else {
...statements...
}
```
See the example below:
```mermaid-example
zenuml
Alice->Bob: Hello Bob, how are you?
if(is_sick) {
Bob->Alice: Not so good :(
} else {
Bob->Alice: Feeling fresh like a daisy
}
```
## Opt
It is possible to render an `opt` fragment. This is done by the notation
```zenuml
opt {
...statements...
}
```
See the example below:
```mermaid-example
zenuml
Alice->Bob: Hello Bob, how are you?
Bob->Alice: Not so good :(
opt {
Bob->Alice: Thanks for asking
}
```
## Parallel
It is possible to show actions that are happening in parallel.
This is done by the notation
```zenuml
par {
statement1
statement2
statement3
}
```
See the example below:
```mermaid-example
zenuml
par {
Alice->Bob: Hello guys!
Alice->John: Hello guys!
}
```
## Try/Catch/Finally (Break)
It is possible to indicate a stop of the sequence within the flow (usually used to model exceptions).
This is done by the notation
```
try {
...statements...
} catch {
...statements...
} finally {
...statements...
}
```
See the example below:
```mermaid-example
zenuml
try {
Consumer->API: Book something
API->BookingService: Start booking process
} catch {
API->Consumer: show failure
} finally {
API->BookingService: rollback status
}
```
## Integrating with your library/website.
Zenuml uses the experimental lazy loading & async rendering features which could change in the future.
You can use this method to add mermaid including the zenuml diagram to a web page:
```html
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
import zenuml from 'https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-zenuml@0.1.0/dist/mermaid-zenuml.esm.min.mjs';
await mermaid.registerExternalDiagrams([zenuml]);
</script>
```

View File

@@ -263,7 +263,10 @@ export const cleanUpSvgCode = (
// Replace marker-end urls with just the # anchor (remove the preceding part of the URL)
if (!useArrowMarkerUrls && !inSandboxMode) {
cleanedUpSvg = cleanedUpSvg.replace(/marker-end="url\(.*?#/g, 'marker-end="url(#');
cleanedUpSvg = cleanedUpSvg.replace(
/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,
'marker-end="url(#'
);
}
cleanedUpSvg = decodeEntities(cleanedUpSvg);

View File

@@ -78,6 +78,22 @@ function createTspan(textElement, lineIndex, lineHeight) {
.attr('dy', lineHeight + 'em');
}
/**
* Compute the width of rendered text
* @param {object} parentNode
* @param {number} lineHeight
* @param {string} text
* @returns {number}
*/
function computeWidthOfText(parentNode, lineHeight, text) {
const testElement = parentNode.append('text');
const testSpan = createTspan(testElement, 1, lineHeight);
updateTextContentAndStyles(testSpan, [{ content: text, type: 'normal' }]);
const textLength = testSpan.node().getComputedTextLength();
testElement.remove();
return textLength;
}
/**
* Creates a formatted text element by breaking lines and applying styles based on
* the given structuredText.
@@ -95,31 +111,44 @@ function createFormattedText(width, g, structuredText, addBackground = false) {
// .attr('dominant-baseline', 'middle')
// .attr('text-anchor', 'middle');
// .attr('text-anchor', 'middle');
let lineIndex = -1;
let lineIndex = 0;
structuredText.forEach((line) => {
lineIndex++;
let tspan = createTspan(textElement, lineIndex, lineHeight);
let words = [...line].reverse();
let currentWord;
let wrappedLine = [];
while (words.length) {
currentWord = words.pop();
wrappedLine.push(currentWord);
updateTextContentAndStyles(tspan, wrappedLine);
if (tspan.node().getComputedTextLength() > width) {
wrappedLine.pop();
words.push(currentWord);
updateTextContentAndStyles(tspan, wrappedLine);
wrappedLine = [];
lineIndex++;
tspan = createTspan(textElement, lineIndex, lineHeight);
/**
* Preprocess raw string content of line data
* Creating an array of strings pre-split to satisfy width limit
*/
let fullStr = line.map((data) => data.content).join(' ');
let tempStr = '';
let linesUnderWidth = [];
let prevIndex = 0;
if (computeWidthOfText(labelGroup, lineHeight, fullStr) <= width) {
linesUnderWidth.push(fullStr);
} else {
for (let i = 0; i <= fullStr.length; i++) {
tempStr = fullStr.slice(prevIndex, i);
log.info(tempStr, prevIndex, i);
if (computeWidthOfText(labelGroup, lineHeight, tempStr) > width) {
const subStr = fullStr.slice(prevIndex, i);
// Break at space if any
const lastSpaceIndex = subStr.lastIndexOf(' ');
if (lastSpaceIndex > -1) {
i = prevIndex + lastSpaceIndex + 1;
}
linesUnderWidth.push(fullStr.slice(prevIndex, i).trim());
prevIndex = i;
tempStr = null;
}
}
if (tempStr != null) {
linesUnderWidth.push(tempStr);
}
}
/** Add each prepared line as a tspan to the parent node */
const preparedLines = linesUnderWidth.map((w) => ({ content: w, type: line.type }));
for (const preparedLine of preparedLines) {
let tspan = createTspan(textElement, lineIndex, lineHeight);
updateTextContentAndStyles(tspan, [preparedLine]);
lineIndex++;
}
});
if (addBackground) {

View File

@@ -70,7 +70,6 @@ export const setupGraphViewbox = function (graph, svgElem, padding, useMaxWidth)
height = sHeight + padding * 2;
// }
// width =
log.info(`Calculated bounds: ${width}x${height}`);
configureSvgSize(svgElem, height, width, useMaxWidth);

View File

@@ -32,6 +32,8 @@ import assignWithDepth from './assignWithDepth.js';
import { MermaidConfig } from './config.type.js';
import memoize from 'lodash-es/memoize.js';
export const ZERO_WIDTH_SPACE = '\u200b';
// Effectively an enum of the supported curve types, accessible by name
const d3CurveTypes = {
curveBasis: curveBasis,
@@ -765,7 +767,7 @@ export const calculateTextDimensions: (
const dim = { width: 0, height: 0, lineHeight: 0 };
for (const line of lines) {
const textObj = getTextObj();
textObj.text = line;
textObj.text = line || ZERO_WIDTH_SPACE;
const textElem = drawSimpleText(g, textObj)
.style('font-size', _fontSizePx)
.style('font-weight', fontWeight)

552
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff