mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-08 18:16:44 +02:00
Compare commits
268 Commits
release/10
...
sidv/runTi
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b4be53ff04 | ||
![]() |
0b0d901b7f | ||
![]() |
7fec51f322 | ||
![]() |
1659ace65d | ||
![]() |
3340608689 | ||
![]() |
a43cd55c53 | ||
![]() |
70d236244f | ||
![]() |
171a2019ec | ||
![]() |
70df6bbbca | ||
![]() |
5807d521b7 | ||
![]() |
2b2bbe35d0 | ||
![]() |
d11bfaa6c4 | ||
![]() |
25cd86feec | ||
![]() |
062176d8d0 | ||
![]() |
a344d88020 | ||
![]() |
30b180d77b | ||
![]() |
00423ed152 | ||
![]() |
48ff3b2c11 | ||
![]() |
eee0d4bf31 | ||
![]() |
e047755a21 | ||
![]() |
b30d609d19 | ||
![]() |
191ea24e29 | ||
![]() |
72a6fad1db | ||
![]() |
a2a99485f9 | ||
![]() |
969e2c1ff1 | ||
![]() |
93dee55ade | ||
![]() |
781945325d | ||
![]() |
dc476233ba | ||
![]() |
eb6c92b0d9 | ||
![]() |
c6cf5953a1 | ||
![]() |
32db724752 | ||
![]() |
6702d41840 | ||
![]() |
441deaffc9 | ||
![]() |
af53a968f6 | ||
![]() |
55be75c974 | ||
![]() |
47a6ce4342 | ||
![]() |
3ecb841c1a | ||
![]() |
1d2450245e | ||
![]() |
f6c4c9260f | ||
![]() |
f354d68350 | ||
![]() |
bea76aa682 | ||
![]() |
6d4b27aacb | ||
![]() |
e008b7dae7 | ||
![]() |
96a3991c56 | ||
![]() |
8d1d691bc3 | ||
![]() |
e07608209b | ||
![]() |
50cdb74d54 | ||
![]() |
edc091f4d4 | ||
![]() |
e0448a7b7b | ||
![]() |
0f02f5ff34 | ||
![]() |
b2111adef5 | ||
![]() |
442da6c4a2 | ||
![]() |
f715863540 | ||
![]() |
ed7dbb100d | ||
![]() |
52fdea0419 | ||
![]() |
b7c72cb38a | ||
![]() |
5cc20b5e44 | ||
![]() |
ce9a9db33a | ||
![]() |
31e19a0434 | ||
![]() |
16968eb38c | ||
![]() |
5c46b98eee | ||
![]() |
ba46747cb0 | ||
![]() |
0dcca35ec2 | ||
![]() |
c7eaee037e | ||
![]() |
832e3f5d49 | ||
![]() |
6261fce91f | ||
![]() |
e8f655439d | ||
![]() |
c11093fa71 | ||
![]() |
af7282511a | ||
![]() |
58b6cf0174 | ||
![]() |
aab7631a9f | ||
![]() |
526d2a61f8 | ||
![]() |
54a09ead95 | ||
![]() |
c2ea23f01f | ||
![]() |
ff6188bd80 | ||
![]() |
dc1b2a6873 | ||
![]() |
d732a146c2 | ||
![]() |
b9bc518a0a | ||
![]() |
edf32911be | ||
![]() |
b8470a471b | ||
![]() |
45880395ea | ||
![]() |
6f3c9205cd | ||
![]() |
96c90b24d1 | ||
![]() |
aa4bfa0727 | ||
![]() |
8873ffca12 | ||
![]() |
0bda748ad9 | ||
![]() |
867686fe34 | ||
![]() |
60f92dcdbc | ||
![]() |
6871ad09e6 | ||
![]() |
479188bc40 | ||
![]() |
c3c7ccd78a | ||
![]() |
000b432bb2 | ||
![]() |
65a08efa00 | ||
![]() |
60266289e0 | ||
![]() |
3145758411 | ||
![]() |
d7948a845d | ||
![]() |
aff69e583e | ||
![]() |
e7f7b6ad68 | ||
![]() |
b5e58f4076 | ||
![]() |
fd0f51926e | ||
![]() |
733d6fe6eb | ||
![]() |
bffbf87cb3 | ||
![]() |
63890cc2fd | ||
![]() |
9ade49b39c | ||
![]() |
6d49cd6859 | ||
![]() |
5eb116059b | ||
![]() |
bcdd1c56bf | ||
![]() |
cbcd2cce9b | ||
![]() |
94c3d7fb60 | ||
![]() |
a2db4a464a | ||
![]() |
fe7da97c5c | ||
![]() |
c294a0a9ac | ||
![]() |
30fe363b57 | ||
![]() |
4ec57836d8 | ||
![]() |
5b7ba838f1 | ||
![]() |
ac99eb59d2 | ||
![]() |
1be09df9d4 | ||
![]() |
38b3a2080b | ||
![]() |
0fec0ef624 | ||
![]() |
f0d6789722 | ||
![]() |
7ef61d58fd | ||
![]() |
96ae4a5967 | ||
![]() |
bca645f63d | ||
![]() |
a8105f084e | ||
![]() |
e86f09aaed | ||
![]() |
692a7471c1 | ||
![]() |
480645d22f | ||
![]() |
784a853ec7 | ||
![]() |
088fc392ab | ||
![]() |
0d7644c782 | ||
![]() |
f15d24b4e8 | ||
![]() |
510549f365 | ||
![]() |
99313fe162 | ||
![]() |
f9df193b7b | ||
![]() |
113a400952 | ||
![]() |
b6983e4b21 | ||
![]() |
fc400ea57b | ||
![]() |
068a74adeb | ||
![]() |
1a8743ec11 | ||
![]() |
9925b9b455 | ||
![]() |
4c43bae92d | ||
![]() |
659db9f04b | ||
![]() |
b88d1dfaa9 | ||
![]() |
7c79bbd6b0 | ||
![]() |
ce6bfcb7f5 | ||
![]() |
6ce543e118 | ||
![]() |
1d88ac43cf | ||
![]() |
6102285577 | ||
![]() |
b83603488c | ||
![]() |
cf22e30237 | ||
![]() |
f01971b67c | ||
![]() |
c62be1bb45 | ||
![]() |
cf1880343b | ||
![]() |
0c57433567 | ||
![]() |
5ef0527ebc | ||
![]() |
53ef5c51cc | ||
![]() |
58c7934dd8 | ||
![]() |
0a626917f8 | ||
![]() |
922bb1452f | ||
![]() |
1cda37659e | ||
![]() |
fe2e46fe60 | ||
![]() |
7765afa7da | ||
![]() |
55d7e9ec61 | ||
![]() |
6a4ad8af06 | ||
![]() |
018440354f | ||
![]() |
49a197eaa8 | ||
![]() |
3abe7cfc45 | ||
![]() |
8c31db6352 | ||
![]() |
91eb824c21 | ||
![]() |
3e3519e8ec | ||
![]() |
566150977a | ||
![]() |
0ff3ba30b7 | ||
![]() |
3c90894e38 | ||
![]() |
136f1c50e7 | ||
![]() |
043729f557 | ||
![]() |
75f1f9228d | ||
![]() |
38d9c6d26b | ||
![]() |
afd7cf51cf | ||
![]() |
c41594d220 | ||
![]() |
fedbd48c0f | ||
![]() |
271b779995 | ||
![]() |
52b33f6f47 | ||
![]() |
5aee43d05b | ||
![]() |
7b29a380fc | ||
![]() |
997c23befa | ||
![]() |
24d43849a0 | ||
![]() |
4ce26296d6 | ||
![]() |
4342759da7 | ||
![]() |
25f2d224f1 | ||
![]() |
0abb4f8c6f | ||
![]() |
697ac18872 | ||
![]() |
fc229cf274 | ||
![]() |
b48136d994 | ||
![]() |
77ba7c987a | ||
![]() |
84f3baf013 | ||
![]() |
795baedbb1 | ||
![]() |
5469a7eb71 | ||
![]() |
23fc7c2c96 | ||
![]() |
dff404a8c9 | ||
![]() |
146364aa67 | ||
![]() |
258dbf30e0 | ||
![]() |
44b93c039a | ||
![]() |
4d5313699e | ||
![]() |
cd198290d7 | ||
![]() |
60ed7d3273 | ||
![]() |
9bcfba6620 | ||
![]() |
7ea3c64268 | ||
![]() |
2b6a34e9e0 | ||
![]() |
458b90c78d | ||
![]() |
dd284c0986 | ||
![]() |
21539dfb6a | ||
![]() |
91785b8284 | ||
![]() |
f202770b70 | ||
![]() |
8186a54962 | ||
![]() |
866909b803 | ||
![]() |
408910e6e8 | ||
![]() |
24c8e575f4 | ||
![]() |
8d0ca2c876 | ||
![]() |
fc96ebefd4 | ||
![]() |
394330175f | ||
![]() |
f946c3da06 | ||
![]() |
156fbd1958 | ||
![]() |
7dd0d126e2 | ||
![]() |
205360c109 | ||
![]() |
984a0e6d06 | ||
![]() |
eb63568ceb | ||
![]() |
cc6f896b69 | ||
![]() |
83e47a7216 | ||
![]() |
1d64549cce | ||
![]() |
d0c36c0de3 | ||
![]() |
341db13279 | ||
![]() |
1c8e13b9c1 | ||
![]() |
49c5f3bb9c | ||
![]() |
4ae361bd1f | ||
![]() |
6502496a2c | ||
![]() |
8678ceeb3c | ||
![]() |
9cb62f4d2e | ||
![]() |
6c0ef54e18 | ||
![]() |
fd731c5ccd | ||
![]() |
cbe9490dc0 | ||
![]() |
82054bfabc | ||
![]() |
963dd75c39 | ||
![]() |
1c24617f98 | ||
![]() |
1559c2ca21 | ||
![]() |
6141722b1f | ||
![]() |
222d8eed4e | ||
![]() |
718d52a72c | ||
![]() |
fe1a06271a | ||
![]() |
bd2370555b | ||
![]() |
86c9ee4e90 | ||
![]() |
b26bcf1343 | ||
![]() |
5d5c6275f9 | ||
![]() |
9c1a47d1fc | ||
![]() |
13852b7f4e | ||
![]() |
4fd7a88a15 | ||
![]() |
5c2a6b5eb1 | ||
![]() |
9cbebbb8a0 | ||
![]() |
e26d987c4e | ||
![]() |
53669efaf8 | ||
![]() |
b68f45ef59 | ||
![]() |
8f44de651b | ||
![]() |
2ede244da0 | ||
![]() |
77a181978e | ||
![]() |
170bbce0d3 | ||
![]() |
fc99d9be41 | ||
![]() |
9fb9bed806 | ||
![]() |
01b2f80a95 | ||
![]() |
da7ff777d1 |
30
.build/common.ts
Normal file
30
.build/common.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Shared common options for both ESBuild and Vite
|
||||
*/
|
||||
export const packageOptions = {
|
||||
parser: {
|
||||
name: 'mermaid-parser',
|
||||
packageName: 'parser',
|
||||
file: 'index.ts',
|
||||
},
|
||||
mermaid: {
|
||||
name: 'mermaid',
|
||||
packageName: 'mermaid',
|
||||
file: 'mermaid.ts',
|
||||
},
|
||||
'mermaid-example-diagram': {
|
||||
name: 'mermaid-example-diagram',
|
||||
packageName: 'mermaid-example-diagram',
|
||||
file: 'detector.ts',
|
||||
},
|
||||
'mermaid-zenuml': {
|
||||
name: 'mermaid-zenuml',
|
||||
packageName: 'mermaid-zenuml',
|
||||
file: 'detector.ts',
|
||||
},
|
||||
'mermaid-flowchart-elk': {
|
||||
name: 'mermaid-flowchart-elk',
|
||||
packageName: 'mermaid-flowchart-elk',
|
||||
file: 'detector.ts',
|
||||
},
|
||||
} as const;
|
5
.build/generateLangium.ts
Normal file
5
.build/generateLangium.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { generate } from 'langium-cli';
|
||||
|
||||
export async function generateLangium() {
|
||||
await generate({ file: `./packages/parser/langium-config.json` });
|
||||
}
|
124
.build/jsonSchema.ts
Normal file
124
.build/jsonSchema.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { load, JSON_SCHEMA } from 'js-yaml';
|
||||
import assert from 'node:assert';
|
||||
import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
|
||||
import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js';
|
||||
|
||||
/**
|
||||
* All of the keys in the mermaid config that have a mermaid diagram config.
|
||||
*/
|
||||
const MERMAID_CONFIG_DIAGRAM_KEYS = [
|
||||
'flowchart',
|
||||
'sequence',
|
||||
'gantt',
|
||||
'journey',
|
||||
'class',
|
||||
'state',
|
||||
'er',
|
||||
'pie',
|
||||
'quadrantChart',
|
||||
'xyChart',
|
||||
'requirement',
|
||||
'mindmap',
|
||||
'timeline',
|
||||
'gitGraph',
|
||||
'c4',
|
||||
'sankey',
|
||||
'block',
|
||||
'packet',
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Generate default values from the JSON Schema.
|
||||
*
|
||||
* AJV does not support nested default values yet (or default values with $ref),
|
||||
* so we need to manually find them (this may be fixed in ajv v9).
|
||||
*
|
||||
* @param mermaidConfigSchema - The Mermaid JSON Schema to use.
|
||||
* @returns The default mermaid config object.
|
||||
*/
|
||||
function generateDefaults(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
|
||||
const ajv = new Ajv2019({
|
||||
useDefaults: true,
|
||||
allowUnionTypes: true,
|
||||
strict: true,
|
||||
});
|
||||
|
||||
ajv.addKeyword({
|
||||
keyword: 'meta:enum', // used by jsonschema2md
|
||||
errors: false,
|
||||
});
|
||||
ajv.addKeyword({
|
||||
keyword: 'tsType', // used by json-schema-to-typescript
|
||||
errors: false,
|
||||
});
|
||||
|
||||
// ajv currently doesn't support nested default values, see https://github.com/ajv-validator/ajv/issues/1718
|
||||
// (may be fixed in v9) so we need to manually use sub-schemas
|
||||
const mermaidDefaultConfig = {};
|
||||
|
||||
assert.ok(mermaidConfigSchema.$defs);
|
||||
const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
|
||||
|
||||
for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
|
||||
const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
|
||||
const [root, defs, defName] = subSchemaRef.split('/');
|
||||
assert.strictEqual(root, '#');
|
||||
assert.strictEqual(defs, '$defs');
|
||||
const subSchema = {
|
||||
$schema: mermaidConfigSchema.$schema,
|
||||
$defs: mermaidConfigSchema.$defs,
|
||||
...mermaidConfigSchema.$defs[defName],
|
||||
} as JSONSchemaType<BaseDiagramConfig>;
|
||||
|
||||
const validate = ajv.compile(subSchema);
|
||||
|
||||
mermaidDefaultConfig[key] = {};
|
||||
|
||||
for (const required of subSchema.required ?? []) {
|
||||
if (subSchema.properties[required] === undefined && baseDiagramConfig.properties[required]) {
|
||||
mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
|
||||
}
|
||||
}
|
||||
if (!validate(mermaidDefaultConfig[key])) {
|
||||
throw new Error(
|
||||
`schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
|
||||
validate.errors,
|
||||
undefined,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const validate = ajv.compile(mermaidConfigSchema);
|
||||
|
||||
if (!validate(mermaidDefaultConfig)) {
|
||||
throw new Error(
|
||||
`Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
|
||||
validate.errors,
|
||||
undefined,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
return mermaidDefaultConfig;
|
||||
}
|
||||
|
||||
export const loadSchema = (src: string, filename: string): JSONSchemaType<MermaidConfig> => {
|
||||
const jsonSchema = load(src, {
|
||||
filename,
|
||||
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
|
||||
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
|
||||
schema: JSON_SCHEMA,
|
||||
}) as JSONSchemaType<MermaidConfig>;
|
||||
return jsonSchema;
|
||||
};
|
||||
|
||||
export const getDefaults = (schema: JSONSchemaType<MermaidConfig>) => {
|
||||
return `export default ${JSON.stringify(generateDefaults(schema), undefined, 2)};`;
|
||||
};
|
||||
|
||||
export const getSchema = (schema: JSONSchemaType<MermaidConfig>) => {
|
||||
return `export default ${JSON.stringify(schema, undefined, 2)};`;
|
||||
};
|
18
.build/types.ts
Normal file
18
.build/types.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { packageOptions } from './common.js';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
const buildType = (packageName: string) => {
|
||||
console.log(`Building types for ${packageName}`);
|
||||
try {
|
||||
const out = execSync(`tsc -p ./packages/${packageName}/tsconfig.json --emitDeclarationOnly`);
|
||||
out.length > 0 && console.log(out.toString());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
e.stdout.length > 0 && console.error(e.stdout.toString());
|
||||
e.stderr.length > 0 && console.error(e.stderr.toString());
|
||||
}
|
||||
};
|
||||
|
||||
for (const { packageName } of Object.values(packageOptions)) {
|
||||
buildType(packageName);
|
||||
}
|
@@ -53,6 +53,7 @@ GENERICTYPE
|
||||
getBoundarys
|
||||
grammr
|
||||
graphtype
|
||||
iife
|
||||
interp
|
||||
introdcued
|
||||
INVTRAPEND
|
||||
@@ -74,17 +75,20 @@ loglevel
|
||||
LOGMSG
|
||||
lookaheads
|
||||
mdast
|
||||
metafile
|
||||
minlen
|
||||
Mstartx
|
||||
MULT
|
||||
NODIR
|
||||
NSTR
|
||||
outdir
|
||||
Qcontrolx
|
||||
reinit
|
||||
rels
|
||||
reqs
|
||||
rewritelinks
|
||||
rgba
|
||||
runtimes
|
||||
RIGHTOF
|
||||
sankey
|
||||
sequencenumber
|
||||
|
65
.esbuild/build.ts
Normal file
65
.esbuild/build.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { build } from 'esbuild';
|
||||
import { mkdir, writeFile } from 'node:fs/promises';
|
||||
import { packageOptions } from '../.build/common.js';
|
||||
import { generateLangium } from '../.build/generateLangium.js';
|
||||
import { MermaidBuildOptions, defaultOptions, getBuildConfig } from './util.js';
|
||||
|
||||
const shouldVisualize = process.argv.includes('--visualize');
|
||||
|
||||
const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
||||
const commonOptions = { ...defaultOptions, entryName } as const;
|
||||
const buildConfigs = [
|
||||
// package.mjs
|
||||
{ ...commonOptions },
|
||||
// package.min.mjs
|
||||
{
|
||||
...commonOptions,
|
||||
minify: true,
|
||||
metafile: shouldVisualize,
|
||||
},
|
||||
// package.core.mjs
|
||||
{ ...commonOptions, core: true },
|
||||
];
|
||||
|
||||
if (entryName === 'mermaid') {
|
||||
const iifeOptions: MermaidBuildOptions = { ...commonOptions, format: 'iife' };
|
||||
buildConfigs.push(
|
||||
// mermaid.js
|
||||
{ ...iifeOptions },
|
||||
// mermaid.min.js
|
||||
{ ...iifeOptions, minify: true, metafile: shouldVisualize }
|
||||
);
|
||||
}
|
||||
|
||||
const results = await Promise.all(buildConfigs.map((option) => build(getBuildConfig(option))));
|
||||
|
||||
if (shouldVisualize) {
|
||||
for (const { metafile } of results) {
|
||||
if (!metafile) {
|
||||
continue;
|
||||
}
|
||||
const fileName = Object.keys(metafile.outputs)
|
||||
.filter((file) => !file.includes('chunks') && file.endsWith('js'))[0]
|
||||
.replace('dist/', '');
|
||||
// Upload metafile into https://esbuild.github.io/analyze/
|
||||
await writeFile(`stats/${fileName}.meta.json`, JSON.stringify(metafile));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handler = (e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
await generateLangium();
|
||||
await mkdir('stats').catch(() => {});
|
||||
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
||||
// it should build `parser` before `mermaid` because it's a dependency
|
||||
for (const pkg of packageNames) {
|
||||
await buildPackage(pkg).catch(handler);
|
||||
}
|
||||
};
|
||||
|
||||
void main();
|
15
.esbuild/jisonPlugin.ts
Normal file
15
.esbuild/jisonPlugin.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { transformJison } from '../.build/jisonTransformer.js';
|
||||
import { Plugin } from 'esbuild';
|
||||
|
||||
export const jisonPlugin: Plugin = {
|
||||
name: 'jison',
|
||||
setup(build) {
|
||||
build.onLoad({ filter: /\.jison$/ }, async (args) => {
|
||||
// Load the file from the file system
|
||||
const source = await readFile(args.path, 'utf8');
|
||||
const contents = transformJison(source);
|
||||
return { contents, warnings: [] };
|
||||
});
|
||||
},
|
||||
};
|
35
.esbuild/jsonSchemaPlugin.ts
Normal file
35
.esbuild/jsonSchemaPlugin.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { JSONSchemaType } from 'ajv/dist/2019.js';
|
||||
import type { MermaidConfig } from '../packages/mermaid/src/config.type.js';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js';
|
||||
|
||||
/**
|
||||
* ESBuild plugin that handles JSON Schemas saved as a `.schema.yaml` file.
|
||||
*
|
||||
* Use `my-example.schema.yaml?only-defaults=true` to only load the default values.
|
||||
*/
|
||||
|
||||
export const jsonSchemaPlugin = {
|
||||
name: 'json-schema-plugin',
|
||||
setup(build) {
|
||||
let schema: JSONSchemaType<MermaidConfig> | undefined = undefined;
|
||||
let content = '';
|
||||
|
||||
build.onLoad({ filter: /config\.schema\.yaml$/ }, async (args) => {
|
||||
// Load the file from the file system
|
||||
const source = await readFile(args.path, 'utf8');
|
||||
const resolvedSchema: JSONSchemaType<MermaidConfig> =
|
||||
content === source && schema ? schema : loadSchema(source, args.path);
|
||||
if (content !== source) {
|
||||
content = source;
|
||||
schema = resolvedSchema;
|
||||
}
|
||||
const contents = args.suffix.includes('only-defaults')
|
||||
? getDefaults(resolvedSchema)
|
||||
: getSchema(resolvedSchema);
|
||||
return { contents, warnings: [] };
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default jsonSchemaPlugin;
|
102
.esbuild/server.ts
Normal file
102
.esbuild/server.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import express from 'express';
|
||||
import type { NextFunction, Request, Response } from 'express';
|
||||
import cors from 'cors';
|
||||
import { getBuildConfig, defaultOptions } from './util.js';
|
||||
import { context } from 'esbuild';
|
||||
import chokidar from 'chokidar';
|
||||
import { generateLangium } from '../.build/generateLangium.js';
|
||||
import { packageOptions } from '../.build/common.js';
|
||||
|
||||
const configs = Object.values(packageOptions).map(({ packageName }) =>
|
||||
getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: packageName })
|
||||
);
|
||||
const mermaidIIFEConfig = getBuildConfig({
|
||||
...defaultOptions,
|
||||
minify: false,
|
||||
core: false,
|
||||
entryName: 'mermaid',
|
||||
format: 'iife',
|
||||
});
|
||||
configs.push(mermaidIIFEConfig);
|
||||
|
||||
const contexts = await Promise.all(configs.map((config) => context(config)));
|
||||
|
||||
const rebuildAll = async () => {
|
||||
console.time('Rebuild time');
|
||||
await Promise.all(contexts.map((ctx) => ctx.rebuild())).catch((e) => console.error(e));
|
||||
console.timeEnd('Rebuild time');
|
||||
};
|
||||
|
||||
let clients: { id: number; response: Response }[] = [];
|
||||
function eventsHandler(request: Request, response: Response, next: NextFunction) {
|
||||
const headers = {
|
||||
'Content-Type': 'text/event-stream',
|
||||
Connection: 'keep-alive',
|
||||
'Cache-Control': 'no-cache',
|
||||
};
|
||||
response.writeHead(200, headers);
|
||||
const clientId = Date.now();
|
||||
clients.push({
|
||||
id: clientId,
|
||||
response,
|
||||
});
|
||||
request.on('close', () => {
|
||||
clients = clients.filter((client) => client.id !== clientId);
|
||||
});
|
||||
}
|
||||
|
||||
let timeoutId: NodeJS.Timeout | undefined = undefined;
|
||||
|
||||
/**
|
||||
* Debounce file change events to avoid rebuilding multiple times.
|
||||
*/
|
||||
function handleFileChange() {
|
||||
if (timeoutId !== undefined) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
timeoutId = setTimeout(async () => {
|
||||
await rebuildAll();
|
||||
sendEventsToAll();
|
||||
timeoutId = undefined;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function sendEventsToAll() {
|
||||
clients.forEach(({ response }) => response.write(`data: ${Date.now()}\n\n`));
|
||||
}
|
||||
|
||||
async function createServer() {
|
||||
await generateLangium();
|
||||
handleFileChange();
|
||||
const app = express();
|
||||
chokidar
|
||||
.watch('**/src/**/*.{js,ts,langium,yaml,json}', {
|
||||
ignoreInitial: true,
|
||||
ignored: [/node_modules/, /dist/, /docs/, /coverage/],
|
||||
})
|
||||
.on('all', async (event, path) => {
|
||||
// Ignore other events.
|
||||
if (!['add', 'change'].includes(event)) {
|
||||
return;
|
||||
}
|
||||
if (/\.langium$/.test(path)) {
|
||||
await generateLangium();
|
||||
}
|
||||
console.log(`${path} changed. Rebuilding...`);
|
||||
handleFileChange();
|
||||
});
|
||||
|
||||
app.use(cors());
|
||||
app.get('/events', eventsHandler);
|
||||
for (const { packageName } of Object.values(packageOptions)) {
|
||||
app.use(express.static(`./packages/${packageName}/dist`));
|
||||
}
|
||||
app.use(express.static('demos'));
|
||||
app.use(express.static('cypress/platform'));
|
||||
|
||||
app.listen(9000, () => {
|
||||
console.log(`Listening on http://localhost:9000`);
|
||||
});
|
||||
}
|
||||
|
||||
createServer();
|
101
.esbuild/util.ts
Normal file
101
.esbuild/util.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import type { BuildOptions } from 'esbuild';
|
||||
import { readFileSync } from 'fs';
|
||||
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
|
||||
import { packageOptions } from '../.build/common.js';
|
||||
import { jisonPlugin } from './jisonPlugin.js';
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
export interface MermaidBuildOptions {
|
||||
minify: boolean;
|
||||
core: boolean;
|
||||
metafile: boolean;
|
||||
format: 'esm' | 'iife';
|
||||
entryName: keyof typeof packageOptions;
|
||||
}
|
||||
|
||||
export const defaultOptions: Omit<MermaidBuildOptions, 'entryName'> = {
|
||||
minify: false,
|
||||
metafile: false,
|
||||
core: false,
|
||||
format: 'esm',
|
||||
} as const;
|
||||
|
||||
const buildOptions = (override: BuildOptions): BuildOptions => {
|
||||
return {
|
||||
bundle: true,
|
||||
minify: true,
|
||||
keepNames: true,
|
||||
platform: 'browser',
|
||||
tsconfig: 'tsconfig.json',
|
||||
resolveExtensions: ['.ts', '.js', '.json', '.jison', '.yaml'],
|
||||
external: ['require', 'fs', 'path'],
|
||||
outdir: 'dist',
|
||||
plugins: [jisonPlugin, jsonSchemaPlugin],
|
||||
sourcemap: 'external',
|
||||
...override,
|
||||
};
|
||||
};
|
||||
|
||||
const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOptions) => {
|
||||
if (core) {
|
||||
fileName += '.core';
|
||||
} else if (format === 'esm') {
|
||||
fileName += '.esm';
|
||||
}
|
||||
if (minify) {
|
||||
fileName += '.min';
|
||||
}
|
||||
return fileName;
|
||||
};
|
||||
|
||||
export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
|
||||
const { core, entryName, metafile, format, minify } = options;
|
||||
const external: string[] = ['require', 'fs', 'path'];
|
||||
const { name, file, packageName } = packageOptions[entryName];
|
||||
const outFileName = getFileName(name, options);
|
||||
let output: BuildOptions = buildOptions({
|
||||
absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
|
||||
entryPoints: {
|
||||
[outFileName]: `src/${file}`,
|
||||
},
|
||||
metafile,
|
||||
minify,
|
||||
logLevel: 'info',
|
||||
chunkNames: `chunks/${outFileName}/[name]-[hash]`,
|
||||
define: {
|
||||
'import.meta.vitest': 'undefined',
|
||||
},
|
||||
});
|
||||
|
||||
if (core) {
|
||||
const { dependencies } = JSON.parse(
|
||||
readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
|
||||
);
|
||||
// Core build is used to generate file without bundled dependencies.
|
||||
// This is used by downstream projects to bundle dependencies themselves.
|
||||
// Ignore dependencies and any dependencies of dependencies
|
||||
external.push(...Object.keys(dependencies));
|
||||
output.external = external;
|
||||
}
|
||||
|
||||
if (format === 'iife') {
|
||||
output.format = 'iife';
|
||||
output.splitting = false;
|
||||
output.globalName = '__esbuild_esm_mermaid';
|
||||
// Workaround for removing the .default access in esbuild IIFE.
|
||||
// https://github.com/mermaid-js/mermaid/pull/4109#discussion_r1292317396
|
||||
output.footer = {
|
||||
js: 'globalThis.mermaid = globalThis.__esbuild_esm_mermaid.default;',
|
||||
};
|
||||
output.outExtension = { '.js': '.js' };
|
||||
} else {
|
||||
output.format = 'esm';
|
||||
output.splitting = true;
|
||||
output.outExtension = { '.js': '.mjs' };
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
@@ -6,3 +6,6 @@ cypress/plugins/index.js
|
||||
coverage
|
||||
*.json
|
||||
node_modules
|
||||
|
||||
# autogenereated by langium-cli
|
||||
generated/
|
||||
|
1
.github/codecov.yaml
vendored
1
.github/codecov.yaml
vendored
@@ -15,3 +15,4 @@ coverage:
|
||||
# Turing off for now as code coverage isn't stable and causes unnecessary build failures.
|
||||
# default:
|
||||
# threshold: 2%
|
||||
patch: off
|
||||
|
2
.github/lychee.toml
vendored
2
.github/lychee.toml
vendored
@@ -40,7 +40,7 @@ exclude = [
|
||||
# BundlePhobia has frequent downtime
|
||||
"https://bundlephobia.com",
|
||||
|
||||
# Chrome webstore migration issue. Temporary
|
||||
# Chrome webstore redirect issue
|
||||
"https://chromewebstore.google.com"
|
||||
]
|
||||
|
||||
|
2
.github/workflows/build-docs.yml
vendored
2
.github/workflows/build-docs.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
|
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js
|
||||
|
2
.github/workflows/e2e-applitools.yml
vendored
2
.github/workflows/e2e-applitools.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js
|
||||
|
87
.github/workflows/e2e.yml
vendored
87
.github/workflows/e2e.yml
vendored
@@ -15,6 +15,7 @@ on:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used.
|
||||
@@ -28,7 +29,7 @@ jobs:
|
||||
options: --user 1001
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -48,15 +49,35 @@ jobs:
|
||||
with:
|
||||
ref: ${{ env.targetHash }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||
uses: cypress-io/github-action@v6
|
||||
with:
|
||||
# just perform install
|
||||
runTests: false
|
||||
|
||||
- name: Build
|
||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' && github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
pnpm run build:viz
|
||||
mkdir -p cypress/snapshots/stats/base
|
||||
mv stats cypress/snapshots/stats/base
|
||||
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v4
|
||||
uses: cypress-io/github-action@v6
|
||||
id: cypress-snapshot-gen
|
||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||
with:
|
||||
install: false
|
||||
start: pnpm run dev
|
||||
wait-on: 'http://localhost:9000'
|
||||
browser: chrome
|
||||
|
||||
- name: Move runtime data
|
||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||
run: |
|
||||
mv cypress/snapshots/runtimes/current cypress/snapshots/runtimes/base
|
||||
|
||||
e2e:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
@@ -70,7 +91,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js
|
||||
@@ -86,15 +107,42 @@ jobs:
|
||||
path: ./cypress/snapshots
|
||||
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
|
||||
|
||||
- name: Install dependencies
|
||||
uses: cypress-io/github-action@v6
|
||||
with:
|
||||
runTests: false
|
||||
|
||||
- name: Build
|
||||
id: size
|
||||
if: ${{ github.event_name == 'pull_request' && matrix.containers == 1 }}
|
||||
run: |
|
||||
pnpm run build:viz
|
||||
mv stats cypress/snapshots/stats/head
|
||||
{
|
||||
echo 'size_diff<<EOF'
|
||||
npx tsx scripts/size.ts
|
||||
echo EOF
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Size diff only needs to be posted from one job, on PRs.
|
||||
- name: Comment PR size difference
|
||||
if: ${{ github.event_name == 'pull_request' && matrix.containers == 1 }}
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
message: |
|
||||
${{ steps.size.outputs.size_diff }}
|
||||
comment_tag: size-diff
|
||||
|
||||
# Install NPM dependencies, cache them correctly
|
||||
# and run all Cypress tests
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v4
|
||||
uses: cypress-io/github-action@v6
|
||||
id: cypress
|
||||
# If CYPRESS_RECORD_KEY is set, run in parallel on all containers
|
||||
# Otherwise (e.g. if running from fork), we run on a single container only
|
||||
if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
|
||||
with:
|
||||
install: false
|
||||
start: pnpm run dev:coverage
|
||||
wait-on: 'http://localhost:9000'
|
||||
browser: chrome
|
||||
@@ -133,6 +181,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ always() }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js 18.x
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.x
|
||||
|
||||
# Download all snapshot artifacts and merge them into a single folder
|
||||
- name: Download All Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -141,6 +199,27 @@ jobs:
|
||||
pattern: snapshots-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Build
|
||||
id: runtime
|
||||
if: ${{ needs.e2e.result != 'failure' && github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
mv ./snapshots/runtimes/current ./snapshots/runtimes/head
|
||||
npm config set ignore-scripts true
|
||||
pnpm install --frozen-lockfile
|
||||
{
|
||||
echo 'runtime_diff<<EOF'
|
||||
npx tsx scripts/runTime.ts ./snapshots
|
||||
echo EOF
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Comment PR runtime difference
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
message: |
|
||||
${{ steps.runtime.outputs.runtime_diff }}
|
||||
comment_tag: size-diff
|
||||
|
||||
# For successful push events, we save the snapshots cache
|
||||
- name: Save snapshots cache
|
||||
id: cache-upload
|
||||
|
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js
|
||||
|
2
.github/workflows/publish-docs.yml
vendored
2
.github/workflows/publish-docs.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
|
2
.github/workflows/release-draft.yml
vendored
2
.github/workflows/release-draft.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
draft-release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # write permission is required to create a GitHub release
|
||||
contents: write # write permission is required to create a github release
|
||||
pull-requests: read # required to read PR titles/labels
|
||||
steps:
|
||||
- name: Draft Release
|
||||
|
@@ -13,7 +13,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
|
2
.github/workflows/release-publish.yml
vendored
2
.github/workflows/release-publish.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: fregante/setup-git-user@v2
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js
|
||||
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js
|
||||
|
2
.github/workflows/update-browserlist.yml
vendored
2
.github/workflows/update-browserlist.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
- run: npx update-browserslist-db@latest
|
||||
- name: Commit changes
|
||||
uses: EndBug/add-and-commit@v9
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@@ -29,6 +29,7 @@ Gemfile.lock
|
||||
|
||||
cypress/screenshots/
|
||||
cypress/snapshots/
|
||||
cypress/runtimes/
|
||||
|
||||
# eslint --cache file
|
||||
.eslintcache
|
||||
@@ -46,4 +47,8 @@ stats/
|
||||
|
||||
demos/dev/**
|
||||
!/demos/dev/example.html
|
||||
!/demos/dev/reload.js
|
||||
tsx-0/**
|
||||
|
||||
# autogenereated by langium-cli
|
||||
generated/
|
||||
|
@@ -11,6 +11,8 @@ stats
|
||||
.nyc_output
|
||||
# Autogenerated by `pnpm run --filter mermaid types:build-config`
|
||||
packages/mermaid/src/config.type.ts
|
||||
# autogenereated by langium-cli
|
||||
generated/
|
||||
# Ignore the files creates in /demos/dev except for example.html
|
||||
demos/dev/**
|
||||
!/demos/dev/example.html
|
||||
|
@@ -3,11 +3,12 @@ import { resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import jisonPlugin from './jisonPlugin.js';
|
||||
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
|
||||
import { readFileSync } from 'fs';
|
||||
import typescript from '@rollup/plugin-typescript';
|
||||
import { visualizer } from 'rollup-plugin-visualizer';
|
||||
import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js';
|
||||
import istanbul from 'vite-plugin-istanbul';
|
||||
import { packageOptions } from '../.build/common.js';
|
||||
import { generateLangium } from '../.build/generateLangium.js';
|
||||
|
||||
const visualize = process.argv.includes('--visualize');
|
||||
const watch = process.argv.includes('--watch');
|
||||
@@ -36,24 +37,6 @@ const visualizerOptions = (packageName: string, core = false): PluginOption[] =>
|
||||
);
|
||||
};
|
||||
|
||||
const packageOptions = {
|
||||
mermaid: {
|
||||
name: 'mermaid',
|
||||
packageName: 'mermaid',
|
||||
file: 'mermaid.ts',
|
||||
},
|
||||
'mermaid-example-diagram': {
|
||||
name: 'mermaid-example-diagram',
|
||||
packageName: 'mermaid-example-diagram',
|
||||
file: 'detector.ts',
|
||||
},
|
||||
'mermaid-zenuml': {
|
||||
name: 'mermaid-zenuml',
|
||||
packageName: 'mermaid-zenuml',
|
||||
file: 'detector.ts',
|
||||
},
|
||||
};
|
||||
|
||||
interface BuildOptions {
|
||||
minify: boolean | 'esbuild';
|
||||
core?: boolean;
|
||||
@@ -72,34 +55,8 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
||||
sourcemap,
|
||||
entryFileNames: `${name}.esm${minify ? '.min' : ''}.mjs`,
|
||||
},
|
||||
{
|
||||
name,
|
||||
format: 'umd',
|
||||
sourcemap,
|
||||
entryFileNames: `${name}${minify ? '.min' : ''}.js`,
|
||||
},
|
||||
];
|
||||
|
||||
if (core) {
|
||||
const { dependencies } = JSON.parse(
|
||||
readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
|
||||
);
|
||||
// Core build is used to generate file without bundled dependencies.
|
||||
// This is used by downstream projects to bundle dependencies themselves.
|
||||
// Ignore dependencies and any dependencies of dependencies
|
||||
// Adapted from the RegEx used by `rollup-plugin-node`
|
||||
external.push(new RegExp('^(?:' + Object.keys(dependencies).join('|') + ')(?:/.+)?$'));
|
||||
// This needs to be an array. Otherwise vite will build esm & umd with same name and overwrite esm with umd.
|
||||
output = [
|
||||
{
|
||||
name,
|
||||
format: 'esm',
|
||||
sourcemap,
|
||||
entryFileNames: `${name}.core.mjs`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const config: InlineConfig = {
|
||||
configFile: false,
|
||||
build: {
|
||||
@@ -129,7 +86,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
||||
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
|
||||
typescript({ compilerOptions: { declaration: false } }),
|
||||
istanbul({
|
||||
exclude: ['node_modules', 'test/', '__mocks__'],
|
||||
exclude: ['node_modules', 'test/', '__mocks__', 'generated'],
|
||||
extension: ['.js', '.ts'],
|
||||
requireEnv: true,
|
||||
forceBuildInstrument: coverage,
|
||||
@@ -149,24 +106,28 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
||||
|
||||
const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
||||
await build(getBuildConfig({ minify: false, entryName }));
|
||||
await build(getBuildConfig({ minify: 'esbuild', entryName }));
|
||||
await build(getBuildConfig({ minify: false, core: true, entryName }));
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
||||
for (const pkg of packageNames.filter((pkg) => !mermaidOnly || pkg === 'mermaid')) {
|
||||
for (const pkg of packageNames.filter(
|
||||
(pkg) => !mermaidOnly || pkg === 'mermaid' || pkg === 'parser'
|
||||
)) {
|
||||
await buildPackage(pkg);
|
||||
}
|
||||
};
|
||||
|
||||
await generateLangium();
|
||||
|
||||
if (watch) {
|
||||
await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' }));
|
||||
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, watch, core: false, entryName: 'parser' }));
|
||||
await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' }));
|
||||
await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }));
|
||||
} else {
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import { transformJison } from './jisonTransformer.js';
|
||||
import { transformJison } from '../.build/jisonTransformer.js';
|
||||
|
||||
const fileRegex = /\.(jison)$/;
|
||||
|
||||
export default function jison() {
|
||||
return {
|
||||
name: 'jison',
|
||||
|
||||
transform(src: string, id: string) {
|
||||
if (fileRegex.test(id)) {
|
||||
return {
|
||||
|
@@ -1,110 +1,5 @@
|
||||
import { load, JSON_SCHEMA } from 'js-yaml';
|
||||
import assert from 'node:assert';
|
||||
import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
|
||||
import { PluginOption } from 'vite';
|
||||
|
||||
import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js';
|
||||
|
||||
/**
|
||||
* All of the keys in the mermaid config that have a mermaid diagram config.
|
||||
*/
|
||||
const MERMAID_CONFIG_DIAGRAM_KEYS = [
|
||||
'flowchart',
|
||||
'sequence',
|
||||
'gantt',
|
||||
'journey',
|
||||
'class',
|
||||
'state',
|
||||
'er',
|
||||
'pie',
|
||||
'quadrantChart',
|
||||
'xyChart',
|
||||
'requirement',
|
||||
'mindmap',
|
||||
'timeline',
|
||||
'gitGraph',
|
||||
'c4',
|
||||
'sankey',
|
||||
'block',
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Generate default values from the JSON Schema.
|
||||
*
|
||||
* AJV does not support nested default values yet (or default values with $ref),
|
||||
* so we need to manually find them (this may be fixed in ajv v9).
|
||||
*
|
||||
* @param mermaidConfigSchema - The Mermaid JSON Schema to use.
|
||||
* @returns The default mermaid config object.
|
||||
*/
|
||||
function generateDefaults(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
|
||||
const ajv = new Ajv2019({
|
||||
useDefaults: true,
|
||||
allowUnionTypes: true,
|
||||
strict: true,
|
||||
});
|
||||
|
||||
ajv.addKeyword({
|
||||
keyword: 'meta:enum', // used by jsonschema2md
|
||||
errors: false,
|
||||
});
|
||||
ajv.addKeyword({
|
||||
keyword: 'tsType', // used by json-schema-to-typescript
|
||||
errors: false,
|
||||
});
|
||||
|
||||
// ajv currently doesn't support nested default values, see https://github.com/ajv-validator/ajv/issues/1718
|
||||
// (may be fixed in v9) so we need to manually use sub-schemas
|
||||
const mermaidDefaultConfig = {};
|
||||
|
||||
assert.ok(mermaidConfigSchema.$defs);
|
||||
const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
|
||||
|
||||
for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
|
||||
const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
|
||||
const [root, defs, defName] = subSchemaRef.split('/');
|
||||
assert.strictEqual(root, '#');
|
||||
assert.strictEqual(defs, '$defs');
|
||||
const subSchema = {
|
||||
$schema: mermaidConfigSchema.$schema,
|
||||
$defs: mermaidConfigSchema.$defs,
|
||||
...mermaidConfigSchema.$defs[defName],
|
||||
} as JSONSchemaType<BaseDiagramConfig>;
|
||||
|
||||
const validate = ajv.compile(subSchema);
|
||||
|
||||
mermaidDefaultConfig[key] = {};
|
||||
|
||||
for (const required of subSchema.required ?? []) {
|
||||
if (subSchema.properties[required] === undefined && baseDiagramConfig.properties[required]) {
|
||||
mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
|
||||
}
|
||||
}
|
||||
if (!validate(mermaidDefaultConfig[key])) {
|
||||
throw new Error(
|
||||
`schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
|
||||
validate.errors,
|
||||
undefined,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const validate = ajv.compile(mermaidConfigSchema);
|
||||
|
||||
if (!validate(mermaidDefaultConfig)) {
|
||||
throw new Error(
|
||||
`Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
|
||||
validate.errors,
|
||||
undefined,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
return mermaidDefaultConfig;
|
||||
}
|
||||
import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js';
|
||||
|
||||
/**
|
||||
* Vite plugin that handles JSON Schemas saved as a `.schema.yaml` file.
|
||||
@@ -121,32 +16,13 @@ export default function jsonSchemaPlugin(): PluginOption {
|
||||
return;
|
||||
}
|
||||
|
||||
if (idAsUrl.searchParams.get('only-defaults')) {
|
||||
const jsonSchema = load(src, {
|
||||
filename: idAsUrl.pathname,
|
||||
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
|
||||
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
|
||||
schema: JSON_SCHEMA,
|
||||
}) as JSONSchemaType<MermaidConfig>;
|
||||
return {
|
||||
code: `export default ${JSON.stringify(generateDefaults(jsonSchema), undefined, 2)};`,
|
||||
map: null, // no source map
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
code: `export default ${JSON.stringify(
|
||||
load(src, {
|
||||
filename: idAsUrl.pathname,
|
||||
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
|
||||
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
|
||||
schema: JSON_SCHEMA,
|
||||
}),
|
||||
undefined,
|
||||
2
|
||||
)};`,
|
||||
map: null, // provide source map if available
|
||||
};
|
||||
}
|
||||
const jsonSchema = loadSchema(src, idAsUrl.pathname);
|
||||
return {
|
||||
code: idAsUrl.searchParams.get('only-defaults')
|
||||
? getDefaults(jsonSchema)
|
||||
: getSchema(jsonSchema),
|
||||
map: null, // no source map
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import { createServer as createViteServer } from 'vite';
|
||||
import { packageOptions } from '../.build/common.js';
|
||||
|
||||
async function createServer() {
|
||||
const app = express();
|
||||
@@ -14,9 +15,9 @@ 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'));
|
||||
for (const { packageName } of Object.values(packageOptions)) {
|
||||
app.use(express.static(`./packages/${packageName}/dist`));
|
||||
}
|
||||
app.use(vite.middlewares);
|
||||
app.use(express.static('demos'));
|
||||
app.use(express.static('cypress/platform'));
|
||||
|
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* Mocked C4Context diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const drawPersonOrSystemArray = vi.fn();
|
||||
export const drawBoundary = vi.fn();
|
||||
|
||||
export const setConf = vi.fn();
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
drawPersonOrSystemArray,
|
||||
drawBoundary,
|
||||
setConf,
|
||||
draw,
|
||||
};
|
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Mocked class diagram v2 renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const setConf = vi.fn();
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
setConf,
|
||||
draw,
|
||||
};
|
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Mocked class diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
draw,
|
||||
};
|
@@ -1 +0,0 @@
|
||||
// DO NOT delete this file. It is used by vitest to mock the dagre-d3 module.
|
@@ -1,3 +0,0 @@
|
||||
module.exports = function (txt: string) {
|
||||
return txt;
|
||||
};
|
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Mocked er diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const setConf = vi.fn();
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
setConf,
|
||||
draw,
|
||||
};
|
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* Mocked flow (flowchart) diagram v2 renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const setConf = vi.fn();
|
||||
export const addVertices = vi.fn();
|
||||
export const addEdges = vi.fn();
|
||||
export const getClasses = vi.fn().mockImplementation(() => {
|
||||
return {};
|
||||
});
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
setConf,
|
||||
addVertices,
|
||||
addEdges,
|
||||
getClasses,
|
||||
draw,
|
||||
};
|
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Mocked gantt diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const setConf = vi.fn();
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
setConf,
|
||||
draw,
|
||||
};
|
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Mocked git (graph) diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
draw,
|
||||
};
|
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* Mocked pie (picChart) diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
export const setConf = vi.fn();
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
setConf,
|
||||
draw,
|
||||
};
|
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* Mocked pie (picChart) diagram renderer
|
||||
*/
|
||||
import { vi } from 'vitest';
|
||||
|
||||
const draw = vi.fn().mockImplementation(() => '');
|
||||
|
||||
export const renderer = { draw };
|
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Mocked requirement diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
draw,
|
||||
};
|
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Mocked Sankey diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
draw,
|
||||
};
|
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* Mocked sequence diagram renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const bounds = vi.fn();
|
||||
export const drawActors = vi.fn();
|
||||
export const drawActorsPopup = vi.fn();
|
||||
|
||||
export const setConf = vi.fn();
|
||||
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
bounds,
|
||||
drawActors,
|
||||
drawActorsPopup,
|
||||
setConf,
|
||||
draw,
|
||||
};
|
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Mocked state diagram v2 renderer
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
|
||||
export const setConf = vi.fn();
|
||||
export const getClasses = vi.fn().mockImplementation(() => {
|
||||
return {};
|
||||
});
|
||||
export const stateDomId = vi.fn().mockImplementation(() => {
|
||||
return 'mocked-stateDiagram-stateDomId';
|
||||
});
|
||||
export const draw = vi.fn().mockImplementation(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
export default {
|
||||
setConf,
|
||||
getClasses,
|
||||
draw,
|
||||
};
|
@@ -1,4 +1,6 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin';
|
||||
import coverage from '@cypress/code-coverage/task';
|
||||
import eyesPlugin from '@applitools/eyes-cypress';
|
||||
@@ -17,6 +19,19 @@ export default eyesPlugin(
|
||||
}
|
||||
return launchOptions;
|
||||
});
|
||||
on('task', {
|
||||
recordRenderTime({ fileName, testName, timeTaken }) {
|
||||
const resultsPath = path.join('cypress', 'snapshots', 'runtimes', 'current');
|
||||
if (!fs.existsSync(resultsPath)) {
|
||||
fs.mkdirSync(resultsPath, { recursive: true });
|
||||
}
|
||||
fs.appendFileSync(
|
||||
path.join(resultsPath, `${fileName}.csv`),
|
||||
`${testName},${timeTaken}\n`
|
||||
);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
addMatchImageSnapshotPlugin(on, config);
|
||||
// copy any needed variables from process.env to config.env
|
||||
config.env.useAppli = process.env.USE_APPLI ? true : false;
|
||||
|
@@ -110,6 +110,14 @@ export const openURLAndVerifyRendering = (
|
||||
|
||||
cy.visit(url);
|
||||
cy.window().should('have.property', 'rendered', true);
|
||||
cy.window().then((win) => {
|
||||
cy.task('recordRenderTime', {
|
||||
fileName: Cypress.spec.name,
|
||||
testName: name,
|
||||
// @ts-ignore Dynamically added property.
|
||||
timeTaken: win.renderTime,
|
||||
});
|
||||
});
|
||||
cy.get('svg').should('be.visible');
|
||||
|
||||
if (validation) {
|
||||
|
14
cypress/integration/other/flowchart-elk.spec.js
Normal file
14
cypress/integration/other/flowchart-elk.spec.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { urlSnapshotTest, openURLAndVerifyRendering } from '../../helpers/util.ts';
|
||||
|
||||
describe('Flowchart elk', () => {
|
||||
it('should use dagre as fallback', () => {
|
||||
urlSnapshotTest('http://localhost:9000/flow-elk.html', {
|
||||
name: 'flow-elk fallback to dagre',
|
||||
});
|
||||
});
|
||||
it('should allow overriding with external package', () => {
|
||||
urlSnapshotTest('http://localhost:9000/flow-elk.html?elk=true', {
|
||||
name: 'flow-elk overriding dagre with elk',
|
||||
});
|
||||
});
|
||||
});
|
11
cypress/integration/other/iife.spec.js
Normal file
11
cypress/integration/other/iife.spec.js
Normal file
@@ -0,0 +1,11 @@
|
||||
describe('IIFE', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:9000/iife.html');
|
||||
});
|
||||
|
||||
it('should render when using mermaid.min.js', () => {
|
||||
cy.window().should('have.property', 'rendered', true);
|
||||
cy.get('svg').should('be.visible');
|
||||
cy.get('#d2').should('contain', 'Hello');
|
||||
});
|
||||
});
|
@@ -1,16 +0,0 @@
|
||||
describe('Sequencediagram', () => {
|
||||
it('should render a simple sequence diagrams', () => {
|
||||
const url = 'http://localhost:9000/webpackUsage.html';
|
||||
|
||||
cy.visit(url);
|
||||
cy.get('body').find('svg').should('have.length', 1);
|
||||
});
|
||||
it('should handle html escapings properly', () => {
|
||||
const url = 'http://localhost:9000/webpackUsage.html?test-html-escaping=true';
|
||||
|
||||
cy.visit(url);
|
||||
cy.get('body').find('svg').should('have.length', 1);
|
||||
|
||||
cy.get('g.label > foreignobject > div').should('not.contain.text', '<b>');
|
||||
});
|
||||
});
|
@@ -137,9 +137,4 @@ describe('XSS', () => {
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should sanitize backticks block diagram labels properly', () => {
|
||||
cy.visit('http://localhost:9000/xss25.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
67
cypress/integration/rendering/packet.spec.ts
Normal file
67
cypress/integration/rendering/packet.spec.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('packet structure', () => {
|
||||
it('should render a simple packet diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`packet-beta
|
||||
title Hello world
|
||||
0-10: "hello"
|
||||
`
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a complex packet diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`packet-beta
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
64-95: "Acknowledgment Number"
|
||||
96-99: "Data Offset"
|
||||
100-105: "Reserved"
|
||||
106: "URG"
|
||||
107: "ACK"
|
||||
108: "PSH"
|
||||
109: "RST"
|
||||
110: "SYN"
|
||||
111: "FIN"
|
||||
112-127: "Window"
|
||||
128-143: "Checksum"
|
||||
144-159: "Urgent Pointer"
|
||||
160-191: "(Options and Padding)"
|
||||
192-223: "data"
|
||||
`
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a complex packet diagram with showBits false', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
---
|
||||
title: "Packet Diagram"
|
||||
config:
|
||||
packet:
|
||||
showBits: false
|
||||
---
|
||||
packet-beta
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
64-95: "Acknowledgment Number"
|
||||
96-99: "Data Offset"
|
||||
100-105: "Reserved"
|
||||
106: "URG"
|
||||
107: "ACK"
|
||||
108: "PSH"
|
||||
109: "RST"
|
||||
110: "SYN"
|
||||
111: "FIN"
|
||||
112-127: "Window"
|
||||
128-143: "Checksum"
|
||||
144-159: "Urgent Pointer"
|
||||
160-191: "(Options and Padding)"
|
||||
192-223: "data"
|
||||
`
|
||||
);
|
||||
});
|
||||
});
|
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script src="./viewer.js" type="module"></script>
|
||||
<script type="module" src="./viewer.js"></script>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
||||
rel="stylesheet"
|
||||
|
@@ -11,8 +11,7 @@ example-diagram
|
||||
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
|
||||
<!-- <script type="module" src="./external-diagrams-mindmap.mjs" /> -->
|
||||
<script type="module">
|
||||
import exampleDiagram from '../../packages/mermaid-example-diagram/dist/mermaid-example-diagram.core.mjs';
|
||||
// import example from '../../packages/mermaid-example-diagram/src/detector';
|
||||
import exampleDiagram from './mermaid-example-diagram.esm.mjs';
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
|
||||
await mermaid.registerExternalDiagrams([exampleDiagram]);
|
||||
|
28
cypress/platform/flow-elk.html
Normal file
28
cypress/platform/flow-elk.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<html>
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
flowchart-elk
|
||||
a[hello] --> b[world]
|
||||
b --> c{test}
|
||||
c --> one
|
||||
c --> two
|
||||
c --> three
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import elk from './mermaid-flowchart-elk.esm.min.mjs';
|
||||
if (window.location.search.includes('elk')) {
|
||||
await mermaid.registerExternalDiagrams([elk]);
|
||||
}
|
||||
mermaid.initialize({
|
||||
logLevel: 3,
|
||||
startOnLoad: false,
|
||||
});
|
||||
await mermaid.run();
|
||||
if (window.Cypress) {
|
||||
window.rendered = true;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
29
cypress/platform/iife.html
Normal file
29
cypress/platform/iife.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<body>
|
||||
<pre id="diagram" class="mermaid">
|
||||
graph TB
|
||||
a --> b
|
||||
a --> c
|
||||
b --> d
|
||||
c --> d
|
||||
</pre>
|
||||
|
||||
<div id="d2"></div>
|
||||
|
||||
<script src="/mermaid.min.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
startOnLoad: true,
|
||||
});
|
||||
const value = `graph TD\nHello --> World`;
|
||||
const el = document.getElementById('d2');
|
||||
mermaid.render('did', value).then(({ svg }) => {
|
||||
console.log(svg);
|
||||
el.innerHTML = svg;
|
||||
if (window.Cypress) {
|
||||
window.rendered = true;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -17,20 +17,20 @@
|
||||
graph TB
|
||||
Function-->URL
|
||||
click Function clickByFlow "Add a div"
|
||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
click URL "http://localhost:9000/info.html" "Visit <strong>mermaid docs</strong>"
|
||||
</pre>
|
||||
<pre id="FirstLine" class="mermaid2">
|
||||
graph TB
|
||||
1Function-->2URL
|
||||
click 1Function clickByFlow "Add a div"
|
||||
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
click 2URL "http://localhost:9000/info.html" "Visit <strong>mermaid docs</strong>"
|
||||
</pre>
|
||||
|
||||
<pre id="FirstLine" class="mermaid2">
|
||||
classDiagram
|
||||
class Test
|
||||
class ShapeLink
|
||||
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||
link ShapeLink "http://localhost:9000/info.html" "This is a tooltip for a link"
|
||||
class ShapeCallback
|
||||
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
||||
</pre>
|
||||
@@ -42,7 +42,7 @@
|
||||
<pre id="FirstLine" class="mermaid">
|
||||
classDiagram-v2
|
||||
class ShapeLink
|
||||
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||
link ShapeLink "http://localhost:9000/info.html" "This is a tooltip for a link"
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||
Calling a Callback with args :cl3, after cl1, 3d
|
||||
|
||||
click cl1 href "http://localhost:9000/webpackUsage.html"
|
||||
click cl1 href "http://localhost:9000/info.html"
|
||||
click cl2 call clickByGantt()
|
||||
click cl3 call clickByGantt("test1", test2, test3)
|
||||
|
||||
@@ -102,9 +102,15 @@
|
||||
div.className = 'created-by-gant-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Gant';
|
||||
if (arg1) div.innerText += ' ' + arg1;
|
||||
if (arg2) div.innerText += ' ' + arg2;
|
||||
if (arg3) div.innerText += ' ' + arg3;
|
||||
if (arg1) {
|
||||
div.innerText += ' ' + arg1;
|
||||
}
|
||||
if (arg2) {
|
||||
div.innerText += ' ' + arg2;
|
||||
}
|
||||
if (arg3) {
|
||||
div.innerText += ' ' + arg3;
|
||||
}
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
|
@@ -1,6 +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';
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import externalExample from './mermaid-example-diagram.esm.mjs';
|
||||
import zenUml from './mermaid-zenuml.esm.mjs';
|
||||
|
||||
function b64ToUtf8(str) {
|
||||
return decodeURIComponent(escape(window.atob(str)));
|
||||
@@ -8,6 +8,7 @@ function b64ToUtf8(str) {
|
||||
|
||||
// Adds a rendered flag to window when rendering is done, so cypress can wait for it.
|
||||
function markRendered() {
|
||||
window.renderTime = Date.now() - window.loadTime;
|
||||
if (window.Cypress) {
|
||||
window.rendered = true;
|
||||
}
|
||||
@@ -45,9 +46,9 @@ const contentLoaded = async function () {
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
|
||||
await mermaid2.registerExternalDiagrams([externalExample, zenUml]);
|
||||
mermaid2.initialize(graphObj.mermaid);
|
||||
await mermaid2.run();
|
||||
await mermaid.registerExternalDiagrams([externalExample, zenUml]);
|
||||
mermaid.initialize(graphObj.mermaid);
|
||||
await mermaid.run();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -95,18 +96,14 @@ const contentLoadedApi = async function () {
|
||||
divs[i] = div;
|
||||
}
|
||||
|
||||
const defaultE2eCnf = { theme: 'forest' };
|
||||
const defaultE2eCnf = { theme: 'forest', startOnLoad: false };
|
||||
|
||||
const cnf = merge(defaultE2eCnf, graphObj.mermaid);
|
||||
|
||||
mermaid2.initialize(cnf);
|
||||
mermaid.initialize(cnf);
|
||||
|
||||
for (let i = 0; i < numCodes; i++) {
|
||||
const { svg, bindFunctions } = await mermaid2.render(
|
||||
'newid' + i,
|
||||
graphObj.code[i],
|
||||
divs[i]
|
||||
);
|
||||
const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
|
||||
div.innerHTML = svg;
|
||||
bindFunctions(div);
|
||||
}
|
||||
@@ -114,24 +111,28 @@ const contentLoadedApi = async function () {
|
||||
const div = document.createElement('div');
|
||||
div.id = 'block';
|
||||
div.className = 'mermaid';
|
||||
console.warn('graphObj.mermaid', graphObj.mermaid);
|
||||
console.warn('graphObj', graphObj);
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
mermaid2.initialize(graphObj.mermaid);
|
||||
|
||||
const { svg, bindFunctions } = await mermaid2.render('newid', graphObj.code, div);
|
||||
mermaid.initialize(graphObj.mermaid);
|
||||
const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
|
||||
div.innerHTML = svg;
|
||||
console.log(div.innerHTML);
|
||||
bindFunctions(div);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
});
|
||||
/*!
|
||||
* Wait for document loaded before starting the execution
|
||||
*/
|
||||
window.addEventListener(
|
||||
'load',
|
||||
function () {
|
||||
this.window.loadTime = Date.now();
|
||||
if (this.location.href.match('xss.html')) {
|
||||
this.console.log('Using api');
|
||||
void contentLoadedApi().finally(markRendered);
|
||||
|
@@ -1,19 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
/* .mermaid {
|
||||
font-family: "trebuchet ms", verdana, arial;;
|
||||
} */
|
||||
/* .mermaid {
|
||||
font-family: 'arial';
|
||||
} */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="graph-to-be"></div>
|
||||
<script type="module" charset="utf-8">
|
||||
import './bundle-test.js';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,6 +1,5 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="./viewer.js" type="module"></script>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
.malware {
|
||||
@@ -33,12 +32,6 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
useMaxWidth: true,
|
||||
});
|
||||
</script>
|
||||
<script type="module" src="./viewer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,108 +0,0 @@
|
||||
<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>
|
||||
<script>
|
||||
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');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div>Security check</div>
|
||||
<div class="flex">
|
||||
<div id="diagram" class="mermaid"></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: 'forest',
|
||||
arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
state: {
|
||||
defaultRenderer: 'dagre-wrapper',
|
||||
},
|
||||
flowchart: {
|
||||
// defaultRenderer: 'dagre-wrapper',
|
||||
nodeSpacing: 10,
|
||||
curve: 'cardinal',
|
||||
htmlLabels: true,
|
||||
},
|
||||
htmlLabels: false,
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
// fontFamily: '"times", sans-serif',
|
||||
// fontFamily: 'courier',
|
||||
fontSize: 18,
|
||||
curve: 'basis',
|
||||
securityLevel: 'strict',
|
||||
startOnLoad: false,
|
||||
secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
|
||||
// themeVariables: {relationLabelColor: 'red'}
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
|
||||
let diagram = 'block-beta\n';
|
||||
diagram += '`A-- "X<img src=x on';
|
||||
diagram += 'error=xssAttack()>" -->B';
|
||||
|
||||
console.log(diagram);
|
||||
// document.querySelector('#diagram').innerHTML = diagram;
|
||||
const { svg } = await mermaid.render('diagram', diagram);
|
||||
document.querySelector('#res').innerHTML = svg;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -3,6 +3,22 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Mermaid development page</title>
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#code {
|
||||
max-width: 30vw;
|
||||
width: 30vw;
|
||||
}
|
||||
|
||||
#dynamicDiagram {
|
||||
padding-left: 2em;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="diagram" class="mermaid">
|
||||
@@ -13,22 +29,37 @@ graph TB
|
||||
c --> d
|
||||
</pre>
|
||||
|
||||
<div id="dynamicDiagram"></div>
|
||||
<hr />
|
||||
Type code to view diagram:
|
||||
<div class="container">
|
||||
<textarea name="code" id="code" cols="30" rows="10"></textarea>
|
||||
<div id="dynamicDiagram"></div>
|
||||
</div>
|
||||
<pre class="mermaid">info</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from '/mermaid.esm.mjs';
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('Mermaid error: ', err);
|
||||
};
|
||||
async function render(str) {
|
||||
const { svg } = await mermaid.render('dynamic', str);
|
||||
document.getElementById('dynamicDiagram').innerHTML = svg;
|
||||
}
|
||||
const storeKey = window.location.pathname;
|
||||
const code = localStorage.getItem(storeKey);
|
||||
if (code) {
|
||||
document.getElementById('code').value = code;
|
||||
await render(code);
|
||||
}
|
||||
mermaid.initialize({
|
||||
startOnLoad: true,
|
||||
logLevel: 0,
|
||||
});
|
||||
const value = `graph TD\nHello --> World`;
|
||||
const el = document.getElementById('dynamicDiagram');
|
||||
const { svg } = await mermaid.render('dd', value);
|
||||
console.log(svg);
|
||||
el.innerHTML = svg;
|
||||
document.getElementById('code').addEventListener('input', async (e) => {
|
||||
const value = e.target.value;
|
||||
localStorage.setItem(storeKey, value);
|
||||
await render(value);
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="/dev/reload.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
22
demos/dev/reload.js
Normal file
22
demos/dev/reload.js
Normal file
@@ -0,0 +1,22 @@
|
||||
// Connect to the server and reload the page if the server sends a reload message
|
||||
const connectToEvents = () => {
|
||||
const events = new EventSource('/events');
|
||||
const loadTime = Date.now();
|
||||
events.onmessage = (event) => {
|
||||
const time = JSON.parse(event.data);
|
||||
if (time && time > loadTime) {
|
||||
location.reload();
|
||||
}
|
||||
};
|
||||
events.onerror = (error) => {
|
||||
console.error(error);
|
||||
events.close();
|
||||
// Try to reconnect after 1 second in case of errors
|
||||
setTimeout(connectToEvents, 1000);
|
||||
};
|
||||
events.onopen = () => {
|
||||
console.log('Connected to live reload server');
|
||||
};
|
||||
};
|
||||
|
||||
setTimeout(connectToEvents, 500);
|
35
demos/flowchart-elk.html
Normal file
35
demos/flowchart-elk.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Mermaid Flowchart ELK Test Page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Flowchart ELK</h1>
|
||||
<pre class="mermaid">
|
||||
flowchart-elk TD
|
||||
A([Start]) ==> B[Step 1]
|
||||
B ==> C{Flow 1}
|
||||
C -- Choice 1.1 --> D[Step 2.1]
|
||||
C -- Choice 1.3 --> I[Step 2.3]
|
||||
C == Choice 1.2 ==> E[Step 2.2]
|
||||
D --> F{Flow 2}
|
||||
E ==> F{Flow 2}
|
||||
F{Flow 2} == Choice 2.1 ==> H[Feedback node]
|
||||
H[Feedback node] ==> B[Step 1]
|
||||
F{Flow 2} == Choice 2.2 ==> G((Finish))
|
||||
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import flowchartELK from './mermaid-flowchart-elk.esm.mjs';
|
||||
await mermaid.registerExternalDiagrams([flowchartELK]);
|
||||
mermaid.initialize({
|
||||
logLevel: 3,
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -81,6 +81,9 @@
|
||||
<li>
|
||||
<h2><a href="./sankey.html">Sankey</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a href="./packet.html">Packet</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a href="./block.html">Layered Blocks</a></h2>
|
||||
</li>
|
||||
|
141
demos/packet.html
Normal file
141
demos/packet.html
Normal file
@@ -0,0 +1,141 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
font-family: 'Courier New', Courier, monospace !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Packet diagram demo</h1>
|
||||
|
||||
<div class="diagrams">
|
||||
<pre class="mermaid">
|
||||
packet-beta
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
64-95: "Acknowledgment Number"
|
||||
96-99: "Data Offset"
|
||||
100-105: "Reserved"
|
||||
106: "URG"
|
||||
107: "ACK"
|
||||
108: "PSH"
|
||||
109: "RST"
|
||||
110: "SYN"
|
||||
111: "FIN"
|
||||
112-127: "Window"
|
||||
128-143: "Checksum"
|
||||
144-159: "Urgent Pointer"
|
||||
160-191: "(Options and Padding)"
|
||||
192-223: "data"
|
||||
</pre
|
||||
>
|
||||
|
||||
<pre class="mermaid">
|
||||
---
|
||||
config:
|
||||
packet:
|
||||
showBits: false
|
||||
---
|
||||
packet-beta
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
64-95: "Acknowledgment Number"
|
||||
96-99: "Data Offset"
|
||||
100-105: "Reserved"
|
||||
106: "URG"
|
||||
107: "ACK"
|
||||
108: "PSH"
|
||||
109: "RST"
|
||||
110: "SYN"
|
||||
111: "FIN"
|
||||
112-127: "Window"
|
||||
128-143: "Checksum"
|
||||
144-159: "Urgent Pointer"
|
||||
160-191: "(Options and Padding)"
|
||||
192-223: "data"
|
||||
</pre
|
||||
>
|
||||
|
||||
<pre class="mermaid">
|
||||
---
|
||||
config:
|
||||
theme: forest
|
||||
---
|
||||
packet-beta
|
||||
title Forest theme
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
64-95: "Acknowledgment Number"
|
||||
96-99: "Data Offset"
|
||||
100-105: "Reserved"
|
||||
106: "URG"
|
||||
107: "ACK"
|
||||
108: "PSH"
|
||||
109: "RST"
|
||||
110: "SYN"
|
||||
111: "FIN"
|
||||
112-127: "Window"
|
||||
128-143: "Checksum"
|
||||
144-159: "Urgent Pointer"
|
||||
160-191: "(Options and Padding)"
|
||||
192-223: "data"
|
||||
</pre
|
||||
>
|
||||
|
||||
<pre class="mermaid" style="background-color: black">
|
||||
---
|
||||
config:
|
||||
theme: dark
|
||||
---
|
||||
packet-beta
|
||||
title Dark theme
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
64-95: "Acknowledgment Number"
|
||||
96-99: "Data Offset"
|
||||
100-105: "Reserved"
|
||||
106: "URG"
|
||||
107: "ACK"
|
||||
108: "PSH"
|
||||
109: "RST"
|
||||
110: "SYN"
|
||||
111: "FIN"
|
||||
112-127: "Window"
|
||||
128-143: "Checksum"
|
||||
144-159: "Urgent Pointer"
|
||||
160-191: "(Options and Padding)"
|
||||
192-223: "data"
|
||||
</pre
|
||||
>
|
||||
</div>
|
||||
<script type="module">
|
||||
import mermaid from '/mermaid.esm.mjs';
|
||||
mermaid.initialize({
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.diagrams {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
pre {
|
||||
width: 45vw;
|
||||
padding: 2em;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
@@ -50,7 +50,7 @@
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import mermaid from '/mermaid.esm.mjs';
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
logLevel: 3,
|
||||
|
@@ -1,222 +0,0 @@
|
||||
> **Warning**
|
||||
>
|
||||
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
||||
>
|
||||
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/community/new-diagram-jison.md](../../packages/mermaid/src/docs/community/new-diagram-jison.md).
|
||||
|
||||
# Adding a New Diagram/Chart (Deprecated) 📊
|
||||
|
||||
> **Warning**
|
||||
> JISON grammars are deprecated in mermaid. Please use Langium instead. See [New Diagram](./new-diagram.md) for more information.
|
||||
>
|
||||
> **New diagrams with JISON grammars will not be accepted.**
|
||||
|
||||
### Step 1: Grammar & Parsing
|
||||
|
||||
#### Grammar
|
||||
|
||||
This would be to define a JISON grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
|
||||
|
||||
For instance:
|
||||
|
||||
- the flowchart starts with the keyword _graph_
|
||||
- the sequence diagram starts with the keyword _sequenceDiagram_
|
||||
|
||||
#### Store data found during parsing
|
||||
|
||||
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call an object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
|
||||
|
||||
```jison
|
||||
statement
|
||||
: 'participant' actor { $$='actor'; }
|
||||
| signal { $$='signal'; }
|
||||
| note_statement { $$='note'; }
|
||||
| 'title' message { yy.setTitle($2); }
|
||||
;
|
||||
```
|
||||
|
||||
In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered.
|
||||
|
||||
> **Note**
|
||||
> Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
|
||||
|
||||
For more info look at the example diagram type:
|
||||
|
||||
The `yy` object has the following function:
|
||||
|
||||
```javascript
|
||||
exports.parseError = function (err, hash) {
|
||||
mermaid.parseError(err, hash);
|
||||
};
|
||||
```
|
||||
|
||||
when parsing the `yy` object is initialized as per below:
|
||||
|
||||
```javascript
|
||||
const parser = exampleParser.parser;
|
||||
parser.yy = db;
|
||||
```
|
||||
|
||||
### Step 2: Rendering
|
||||
|
||||
Write a renderer that given the data found during parsing renders the diagram. To look at an example look at sequenceRenderer.js rather than the flowchart renderer as this is a more generic example.
|
||||
|
||||
Place the renderer in the diagram folder.
|
||||
|
||||
### Step 3: Detection of the new diagram type
|
||||
|
||||
The second thing to do is to add the capability to detect the new diagram to type to the detectType in `diagram-api/detectType.ts`. The detection should return a key for the new diagram type.
|
||||
[This key will be used to as the aria roledescription](#aria-roledescription), so it should be a word that clearly describes the diagram type.
|
||||
For example, if your new diagram uses a UML deployment diagram, a good key would be "UMLDeploymentDiagram" because assistive technologies such as a screen reader
|
||||
would voice that as "U-M-L Deployment diagram." Another good key would be "deploymentDiagram" because that would be voiced as "Deployment Diagram." A bad key would be "deployment" because that would not sufficiently describe the diagram.
|
||||
|
||||
Note that the diagram type key does not have to be the same as the diagram keyword chosen for the [grammar](#grammar), but it is helpful if they are the same.
|
||||
|
||||
### Step 4: The final piece - triggering the rendering
|
||||
|
||||
At this point when mermaid is trying to render the diagram, it will detect it as being of the new type but there will be no match when trying to render the diagram. To fix this add a new case in the switch statement in main.js:init this should match the diagram type returned from step #2. The code in this new case statement should call the renderer for the diagram type with the data found by the parser as an argument.
|
||||
|
||||
## Usage of the parser as a separate module
|
||||
|
||||
### Setup
|
||||
|
||||
```javascript
|
||||
const graph = require('./graphDb');
|
||||
const flow = require('./parser/flow');
|
||||
flow.parser.yy = graph;
|
||||
```
|
||||
|
||||
### Parsing
|
||||
|
||||
```javascript
|
||||
flow.parser.parse(text);
|
||||
```
|
||||
|
||||
### Data extraction
|
||||
|
||||
```javascript
|
||||
graph.getDirection();
|
||||
graph.getVertices();
|
||||
graph.getEdges();
|
||||
```
|
||||
|
||||
The parser is also exposed in the mermaid api by calling:
|
||||
|
||||
```javascript
|
||||
const parser = mermaid.getParser();
|
||||
```
|
||||
|
||||
Note that the parse needs a graph object to store the data as per:
|
||||
|
||||
```javascript
|
||||
flow.parser.yy = graph;
|
||||
```
|
||||
|
||||
Look at `graphDb.js` for more details on that object.
|
||||
|
||||
## Layout
|
||||
|
||||
If you are using a dagre based layout, please use flowchart-v2 as a template and by doing that you will be using dagre-wrapper instead of dagreD3 which we are migrating away from.
|
||||
|
||||
### Common parts of a diagram
|
||||
|
||||
There are a few features that are common between the different types of diagrams. We try to standardize the diagrams that work as similar as possible for the end user. The commonalities are:
|
||||
|
||||
- Directives, a way of modifying the diagram configuration from within the diagram code.
|
||||
- Accessibility, a way for an author to provide additional information like titles and descriptions to people accessing a text with diagrams using a screen reader.
|
||||
- Themes, there is a common way to modify the styling of diagrams in Mermaid.
|
||||
- Comments should follow mermaid standards
|
||||
|
||||
Here are some pointers on how to handle these different areas.
|
||||
|
||||
## Accessibility
|
||||
|
||||
Mermaid automatically adds the following accessibility information for the diagram SVG HTML element:
|
||||
|
||||
- aria-roledescription
|
||||
- accessible title
|
||||
- accessible description
|
||||
|
||||
### aria-roledescription
|
||||
|
||||
The aria-roledescription is automatically set to [the diagram type](#step-3--detection-of-the-new-diagram-type) and inserted into the SVG element.
|
||||
|
||||
See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/#aria-roledescription) in [the Accessible Rich Internet Applications W3 standard.](https://www.w3.org/WAI/standards-guidelines/aria/)
|
||||
|
||||
### accessible title and description
|
||||
|
||||
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
|
||||
|
||||
As a design goal, the jison syntax should be similar between the diagrams.
|
||||
|
||||
```jison
|
||||
|
||||
* lexical grammar */
|
||||
%lex
|
||||
%x acc_title
|
||||
%x acc_descr
|
||||
%x acc_descr_multiline
|
||||
|
||||
%%
|
||||
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
|
||||
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
|
||||
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
|
||||
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
|
||||
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
|
||||
<acc_descr_multiline>[\}] { this.popState(); }
|
||||
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
|
||||
|
||||
statement
|
||||
: acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
|
||||
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
|
||||
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
|
||||
|
||||
```
|
||||
|
||||
The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
|
||||
|
||||
import {
|
||||
setAccTitle,
|
||||
getAccTitle,
|
||||
getAccDescription,
|
||||
setAccDescription,
|
||||
clear as commonClear,
|
||||
} from '../../commonDb';
|
||||
|
||||
The accessibility title and description are inserted into the SVG element in the `render` function in mermaidAPI.
|
||||
|
||||
## Theming
|
||||
|
||||
Mermaid supports themes and has an integrated theming engine. You can read more about how the themes can be used [in the docs](../config/theming.md).
|
||||
|
||||
When adding themes to a diagram it comes down to a few important locations in the code.
|
||||
|
||||
The entry point for the styling engine is in **src/styles.js**. The getStyles function will be called by Mermaid when the styles are being applied to the diagram.
|
||||
|
||||
This function will in turn call a function _your diagram should provide_ returning the css for the new diagram. The diagram specific, also which is commonly also called getStyles and located in the folder for your diagram under src/diagrams and should be named styles.js. The getStyles function will be called with the theme options as an argument like in the following example:
|
||||
|
||||
```js
|
||||
const getStyles = (options) =>
|
||||
`
|
||||
.line {
|
||||
stroke-width: 1;
|
||||
stroke: ${options.lineColor};
|
||||
stroke-dasharray: 2;
|
||||
}
|
||||
// ...
|
||||
`;
|
||||
```
|
||||
|
||||
Note that you need to provide your function to the main getStyles by adding it into the themes object in **src/styles.js** like in the xyzDiagram in the provided example:
|
||||
|
||||
```js
|
||||
const themes = {
|
||||
flowchart,
|
||||
'flowchart-v2': flowchart,
|
||||
sequence,
|
||||
xyzDiagram,
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
The actual options and values for the colors are defined in **src/theme/theme-\[xyz].js**. If you provide the options your diagram needs in the existing theme files then the theming will work smoothly without hiccups.
|
@@ -6,18 +6,52 @@
|
||||
|
||||
# Adding a New Diagram/Chart 📊
|
||||
|
||||
### Examples
|
||||
|
||||
Please refer to the following PRs on how to use Langium to add a new diagram grammar.
|
||||
|
||||
- <https://github.com/mermaid-js/mermaid/pull/4839>
|
||||
- <https://github.com/mermaid-js/mermaid/pull/4751>
|
||||
|
||||
> **Warning**
|
||||
> The below steps are a work in progress and will be updated soon.
|
||||
|
||||
### Step 1: Grammar & Parsing
|
||||
|
||||
#### Grammar
|
||||
|
||||
This would be to define a JISON grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
|
||||
|
||||
For instance:
|
||||
|
||||
- the flowchart starts with the keyword _graph_
|
||||
- the sequence diagram starts with the keyword _sequenceDiagram_
|
||||
|
||||
#### Store data found during parsing
|
||||
|
||||
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call an object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
|
||||
|
||||
```jison
|
||||
statement
|
||||
: 'participant' actor { $$='actor'; }
|
||||
| signal { $$='signal'; }
|
||||
| note_statement { $$='note'; }
|
||||
| 'title' message { yy.setTitle($2); }
|
||||
;
|
||||
```
|
||||
|
||||
In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered.
|
||||
|
||||
> **Note**
|
||||
> Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
|
||||
|
||||
For more info look at the example diagram type:
|
||||
|
||||
The `yy` object has the following function:
|
||||
|
||||
```javascript
|
||||
exports.parseError = function (err, hash) {
|
||||
mermaid.parseError(err, hash);
|
||||
};
|
||||
```
|
||||
|
||||
when parsing the `yy` object is initialized as per below:
|
||||
|
||||
```javascript
|
||||
const parser = exampleParser.parser;
|
||||
parser.yy = db;
|
||||
```
|
||||
|
||||
### Step 2: Rendering
|
||||
|
||||
Write a renderer that given the data found during parsing renders the diagram. To look at an example look at sequenceRenderer.js rather than the flowchart renderer as this is a more generic example.
|
||||
@@ -33,6 +67,52 @@ would voice that as "U-M-L Deployment diagram." Another good key would be "deplo
|
||||
|
||||
Note that the diagram type key does not have to be the same as the diagram keyword chosen for the [grammar](#grammar), but it is helpful if they are the same.
|
||||
|
||||
### Step 4: The final piece - triggering the rendering
|
||||
|
||||
At this point when mermaid is trying to render the diagram, it will detect it as being of the new type but there will be no match when trying to render the diagram. To fix this add a new case in the switch statement in main.js:init this should match the diagram type returned from step #2. The code in this new case statement should call the renderer for the diagram type with the data found by the parser as an argument.
|
||||
|
||||
## Usage of the parser as a separate module
|
||||
|
||||
### Setup
|
||||
|
||||
```javascript
|
||||
const graph = require('./graphDb');
|
||||
const flow = require('./parser/flow');
|
||||
flow.parser.yy = graph;
|
||||
```
|
||||
|
||||
### Parsing
|
||||
|
||||
```javascript
|
||||
flow.parser.parse(text);
|
||||
```
|
||||
|
||||
### Data extraction
|
||||
|
||||
```javascript
|
||||
graph.getDirection();
|
||||
graph.getVertices();
|
||||
graph.getEdges();
|
||||
```
|
||||
|
||||
The parser is also exposed in the mermaid api by calling:
|
||||
|
||||
```javascript
|
||||
const parser = mermaid.getParser();
|
||||
```
|
||||
|
||||
Note that the parse needs a graph object to store the data as per:
|
||||
|
||||
```javascript
|
||||
flow.parser.yy = graph;
|
||||
```
|
||||
|
||||
Look at `graphDb.js` for more details on that object.
|
||||
|
||||
## Layout
|
||||
|
||||
If you are using a dagre based layout, please use flowchart-v2 as a template and by doing that you will be using dagre-wrapper instead of dagreD3 which we are migrating away from.
|
||||
|
||||
### Common parts of a diagram
|
||||
|
||||
There are a few features that are common between the different types of diagrams. We try to standardize the diagrams that work as similar as possible for the end user. The commonalities are:
|
||||
@@ -62,7 +142,33 @@ See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/
|
||||
|
||||
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
|
||||
|
||||
The functions for setting title and description are provided by a common module. This is the import in flowDb.js:
|
||||
As a design goal, the jison syntax should be similar between the diagrams.
|
||||
|
||||
```jison
|
||||
|
||||
* lexical grammar */
|
||||
%lex
|
||||
%x acc_title
|
||||
%x acc_descr
|
||||
%x acc_descr_multiline
|
||||
|
||||
%%
|
||||
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
|
||||
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
|
||||
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
|
||||
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
|
||||
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
|
||||
<acc_descr_multiline>[\}] { this.popState(); }
|
||||
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
|
||||
|
||||
statement
|
||||
: acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
|
||||
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
|
||||
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
|
||||
|
||||
```
|
||||
|
||||
The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
|
||||
|
||||
import {
|
||||
setAccTitle,
|
||||
|
@@ -4,7 +4,7 @@
|
||||
>
|
||||
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/math.md](../../packages/mermaid/src/docs/config/math.md).
|
||||
|
||||
# Math Configuration (v10.9.0+)
|
||||
# Math Configuration (v\<MERMAID_RELEASE_VERSION>+)
|
||||
|
||||
Mermaid supports rendering mathematical expressions through the [KaTeX](https://katex.org/) typesetter.
|
||||
|
||||
|
@@ -14,6 +14,9 @@
|
||||
|
||||
• `Optional` **suppressErrors**: `boolean`
|
||||
|
||||
If `true`, parse will return `false` instead of throwing error when the diagram is invalid.
|
||||
The `parseError` function will not be called.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:60](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L60)
|
||||
[mermaidAPI.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L64)
|
||||
|
21
docs/config/setup/interfaces/mermaidAPI.ParseResult.md
Normal file
21
docs/config/setup/interfaces/mermaidAPI.ParseResult.md
Normal file
@@ -0,0 +1,21 @@
|
||||
> **Warning**
|
||||
>
|
||||
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
||||
>
|
||||
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaidAPI.ParseResult.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaidAPI.ParseResult.md).
|
||||
|
||||
# Interface: ParseResult
|
||||
|
||||
[mermaidAPI](../modules/mermaidAPI.md).ParseResult
|
||||
|
||||
## Properties
|
||||
|
||||
### diagramType
|
||||
|
||||
• **diagramType**: `string`
|
||||
|
||||
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:71](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L71)
|
@@ -39,7 +39,19 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80)
|
||||
[mermaidAPI.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L94)
|
||||
|
||||
---
|
||||
|
||||
### diagramType
|
||||
|
||||
• **diagramType**: `string`
|
||||
|
||||
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L84)
|
||||
|
||||
---
|
||||
|
||||
@@ -51,4 +63,4 @@ The svg code for the rendered graph.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:70](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L70)
|
||||
[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80)
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
#### Defined in
|
||||
|
||||
[defaultConfig.ts:272](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L272)
|
||||
[defaultConfig.ts:275](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L275)
|
||||
|
||||
---
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
## Interfaces
|
||||
|
||||
- [ParseOptions](../interfaces/mermaidAPI.ParseOptions.md)
|
||||
- [ParseResult](../interfaces/mermaidAPI.ParseResult.md)
|
||||
- [RenderResult](../interfaces/mermaidAPI.RenderResult.md)
|
||||
|
||||
## References
|
||||
@@ -25,13 +26,13 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L64)
|
||||
[mermaidAPI.ts:74](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L74)
|
||||
|
||||
## Variables
|
||||
|
||||
### mermaidAPI
|
||||
|
||||
• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<`boolean`> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
|
||||
• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseOptions`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md) & { `suppressErrors`: `true` }) => `Promise`<[`ParseResult`](../interfaces/mermaidAPI.ParseResult.md) | `false`>(`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<[`ParseResult`](../interfaces/mermaidAPI.ParseResult.md)> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
|
||||
|
||||
## mermaidAPI configuration defaults
|
||||
|
||||
@@ -96,7 +97,7 @@ mermaid.initialize(config);
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:607](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L607)
|
||||
[mermaidAPI.ts:622](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L622)
|
||||
|
||||
## Functions
|
||||
|
||||
@@ -127,7 +128,7 @@ Return the last node appended
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:263](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L263)
|
||||
[mermaidAPI.ts:277](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L277)
|
||||
|
||||
---
|
||||
|
||||
@@ -153,7 +154,7 @@ the cleaned up svgCode
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:209](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L209)
|
||||
[mermaidAPI.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L223)
|
||||
|
||||
---
|
||||
|
||||
@@ -178,7 +179,7 @@ the string with all the user styles
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:139](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L139)
|
||||
[mermaidAPI.ts:153](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L153)
|
||||
|
||||
---
|
||||
|
||||
@@ -201,7 +202,7 @@ the string with all the user styles
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:186](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L186)
|
||||
[mermaidAPI.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L200)
|
||||
|
||||
---
|
||||
|
||||
@@ -228,7 +229,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:124](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L124)
|
||||
[mermaidAPI.ts:138](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L138)
|
||||
|
||||
---
|
||||
|
||||
@@ -254,7 +255,7 @@ Put the svgCode into an iFrame. Return the iFrame code
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:240](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L240)
|
||||
[mermaidAPI.ts:254](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L254)
|
||||
|
||||
---
|
||||
|
||||
@@ -279,4 +280,4 @@ Remove any existing elements from the given document
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:313](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L313)
|
||||
[mermaidAPI.ts:327](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L327)
|
||||
|
@@ -64,7 +64,7 @@ Example:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -83,7 +83,7 @@ Example:
|
||||
B-->D(fa:fa-spinner);
|
||||
</pre>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -331,15 +331,17 @@ module.exports = (options) ->
|
||||
|
||||
## Advanced usage
|
||||
|
||||
**Syntax validation without rendering (Work in Progress)**
|
||||
### Syntax validation without rendering
|
||||
|
||||
The **mermaid.parse(txt)** function validates graph definitions without rendering a graph. **[This function is still a work in progress](https://github.com/mermaid-js/mermaid/issues/1066), find alternatives below.**
|
||||
The `mermaid.parse(text, parseOptions)` function validates graph definitions without rendering a graph.
|
||||
|
||||
The function **mermaid.parse(txt)**, takes a text string as an argument and returns true if the definition follows mermaid's syntax and
|
||||
false if it does not. The parseError function will be called when the parse function returns false.
|
||||
The function `mermaid.parse(text, parseOptions)`, takes a text string as an argument and returns `{ diagramType: string }` if the definition follows mermaid's syntax.
|
||||
|
||||
When the parser encounters invalid syntax the **mermaid.parseError** function is called. It is possible to override this
|
||||
function in order to handle the error in an application-specific way.
|
||||
If the definition is invalid, the function returns `false` if `parseOptions.suppressErrors` is set to `true`. Otherwise, it throws an error.
|
||||
|
||||
The parseError function will be called when the parse function throws an error. It will not be called if `parseOptions.suppressErrors` is set to `true`.
|
||||
|
||||
It is possible to override this function in order to handle the error in an application-specific way.
|
||||
|
||||
The code-example below in meta code illustrates how this could work:
|
||||
|
||||
@@ -359,26 +361,10 @@ const textFieldUpdated = async function () {
|
||||
bindEventHandler('change', 'code', textFieldUpdated);
|
||||
```
|
||||
|
||||
**Alternative to mermaid.parse():**
|
||||
One effective and more future-proof method of validating your graph definitions, is to paste and render them via the [Mermaid Live Editor](https://mermaid.live/). This will ensure that your code is compliant with the syntax of Mermaid's most recent version.
|
||||
|
||||
## Configuration
|
||||
|
||||
Mermaid takes a number of options which lets you tweak the rendering of the diagrams. Currently there are three ways of
|
||||
setting the options in mermaid.
|
||||
|
||||
1. Instantiation of the configuration using the initialize call
|
||||
2. _Using the global mermaid object_ - **Deprecated**
|
||||
3. _using the global mermaid_config object_ - **Deprecated**
|
||||
4. Instantiation of the configuration using the **mermaid.init** call- **Deprecated**
|
||||
|
||||
The list above has two ways too many of doing this. Three are deprecated and will eventually be removed. The list of
|
||||
configuration objects are described [in the mermaidAPI documentation](./setup/README.md).
|
||||
|
||||
## Using the `mermaidAPI.initialize`/`mermaid.initialize` call
|
||||
|
||||
The future proof way of setting the configuration is by using the initialization call to mermaid or mermaidAPI depending
|
||||
on what kind of integration you use.
|
||||
You can pass the required configuration to the `mermaid.initialize` call. This is the preferred way of configuring mermaid.
|
||||
The list of configuration objects are described [in the mermaidAPI documentation](./setup/README.md).
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
@@ -408,35 +394,6 @@ mermaid.startOnLoad = true;
|
||||
> **Warning**
|
||||
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
|
||||
|
||||
## Using the mermaid_config
|
||||
|
||||
It is possible to set some configuration via the mermaid object. The two parameters that are supported using this
|
||||
approach are:
|
||||
|
||||
- mermaid_config.startOnLoad
|
||||
- mermaid_config.htmlLabels
|
||||
|
||||
```javascript
|
||||
mermaid_config.startOnLoad = true;
|
||||
```
|
||||
|
||||
> **Warning**
|
||||
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
|
||||
|
||||
## Using the mermaid.init call
|
||||
|
||||
To set some configuration via the mermaid object. The two parameters that are supported using this approach are:
|
||||
|
||||
- mermaid_config.startOnLoad
|
||||
- mermaid_config.htmlLabels
|
||||
|
||||
```javascript
|
||||
mermaid_config.startOnLoad = true;
|
||||
```
|
||||
|
||||
> **Warning**
|
||||
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
|
||||
|
||||
<!---
|
||||
cspell:locale en,en-gb
|
||||
cspell:ignore pumbaa
|
||||
|
@@ -118,7 +118,7 @@ Communication tools and platforms
|
||||
- [phpBB](https://phpbb.com)
|
||||
- [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
|
||||
- [Slack](https://slack.com)
|
||||
- [Mermaid Preview](https://mermaid-preview.com)
|
||||
- [Mermaid Preview](https://github.com/JackuB/mermaid-for-slack)
|
||||
|
||||
### Wikis
|
||||
|
||||
|
@@ -6,10 +6,6 @@
|
||||
|
||||
# Mermaid Chart
|
||||
|
||||
The Future of Diagramming & Visual Collaboration
|
||||
|
||||
Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.producthunt.com/posts/mermaid-chart?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-mermaid-chart" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=416671&theme=light" alt="Mermaid Chart - A smarter way to create diagrams | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
@@ -22,26 +18,22 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun
|
||||
|
||||
- **Editor** - A web based editor for creating and editing Mermaid diagrams.
|
||||
|
||||
- **Visual Editor** - The Visual Editor enables users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options.
|
||||
- **Presentation** - A presentation mode for viewing Mermaid diagrams in a slideshow format.
|
||||
|
||||
- **AI Chat** - Use our embedded AI Chat to generate diagrams from natural language descriptions.
|
||||
- **Collaboration** - A web based collaboration feature for multi-user editing on Mermaid diagrams in real-time (Pro plan).
|
||||
|
||||
- **Plugins** - A plugin system for extending the functionality of Mermaid.
|
||||
|
||||
Official Mermaid Chart plugins:
|
||||
Plugins are available for:
|
||||
|
||||
- [Mermaid Chart GPT](https://chat.openai.com/g/g-1IRFKwq4G-mermaid-chart)
|
||||
- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart)
|
||||
- [ChatGPT](https://docs.mermaidchart.com/plugins/chatgpt)
|
||||
- [JetBrains IDE](https://plugins.jetbrains.com/plugin/23043-mermaid-chart)
|
||||
- [Microsoft PowerPoint and Word](https://appsource.microsoft.com/en-us/product/office/WA200006214?tab=Overview)
|
||||
- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart)
|
||||
|
||||
Visit our [Plugins](https://www.mermaidchart.com/plugins) page for more information.
|
||||
- **AI diagramming** - A feature for generating Mermaid diagrams from text using AI (Pro plan).
|
||||
|
||||
- **Collaboration** - A web based collaboration feature for multi-user editing on Mermaid diagrams in real-time (Pro and Enterprise plans).
|
||||
|
||||
- **Comments** - Enhance collaboration by adding comments to diagrams.
|
||||
|
||||
- **Presentations** - A presentation mode for viewing Mermaid diagrams in a slideshow format.
|
||||
- **More** - To learn more, visit our [Product](https://www.mermaidchart.com/product) page.
|
||||
|
||||
## Plans
|
||||
|
||||
@@ -51,9 +43,11 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun
|
||||
|
||||
- **Enterprise** - A paid plan for enterprise use that includes all Pro features, and more.
|
||||
|
||||
To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page.
|
||||
## Access
|
||||
|
||||
Mermaid Chart is currently offering a 14-day free trial on our Pro and Enterprise tiers. Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
|
||||
Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
|
||||
|
||||
Mermaid Chart is currently offering a 14-day free trial of our newly-launched Pro tier. To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page.
|
||||
|
||||
## Mermaid JS contributions
|
||||
|
||||
|
@@ -224,7 +224,7 @@ b. The importing of the Mermaid library through the `mermaid.esm.mjs` or `mermai
|
||||
```html
|
||||
<body>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@@ -246,23 +246,23 @@ In this example, the `mermaidAPI` is being called through the `CDN`:
|
||||
<body>
|
||||
Here is one mermaid diagram:
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
A[Client] --> B[Load Balancer]
|
||||
B --> C[Server1]
|
||||
graph TD
|
||||
A[Client] --> B[Load Balancer]
|
||||
B --> C[Server1]
|
||||
B --> D[Server2]
|
||||
</pre>
|
||||
|
||||
And here is another:
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
graph TD
|
||||
A[Client] -->|tcp_123| B
|
||||
B(Load Balancer)
|
||||
B -->|tcp_456| C[Server1]
|
||||
B(Load Balancer)
|
||||
B -->|tcp_456| C[Server1]
|
||||
B -->|tcp_456| D[Server2]
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@@ -278,15 +278,15 @@ In this example, `mermaid.js` is referenced in `src` as a separate JavaScript fi
|
||||
</head>
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
A --- B
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
graph LR
|
||||
A --- B
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
A[Client] --> B[Load Balancer]
|
||||
B --> C[Server1]
|
||||
graph TD
|
||||
A[Client] --> B[Load Balancer]
|
||||
B --> C[Server1]
|
||||
B --> D[Server2]
|
||||
</pre>
|
||||
<script type="module">
|
||||
|
@@ -317,7 +317,7 @@ To select a version:
|
||||
|
||||
Replace `<version>` with the desired version number.
|
||||
|
||||
Latest Version: <https://cdn.jsdelivr.net/npm/mermaid@10>
|
||||
Latest Version: <https://cdn.jsdelivr.net/npm/mermaid@11>
|
||||
|
||||
## Deploying Mermaid
|
||||
|
||||
@@ -335,7 +335,7 @@ To Deploy Mermaid:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
@@ -6,45 +6,13 @@
|
||||
|
||||
# Announcements
|
||||
|
||||
## 🚀 Exciting News from Mermaid Chart! 🚀
|
||||
## 🚀 Mermaid Chart's Visual Editor for Flowcharts
|
||||
|
||||
We're thrilled to announce that Mermaid Chart has successfully raised $7.5 million in Seed funding! 🌟 This achievement marks the beginning of a new era for Mermaid and Mermaid Chart.
|
||||
The Mermaid Chart team is excited to introduce a new Visual Editor for flowcharts, enabling users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options.
|
||||
|
||||
**Why It Matters for Mermaid Chart:**
|
||||
Create flowchart nodes, connect them with edges, update shapes, change colors, and edit labels with just a few clicks that automatically reflect in your diagram’s code for easy customizability.
|
||||
|
||||
- **Empowering Collaboration**: Our tools are designed to enable faster, more efficient team collaboration across any distance, leveraging the best of text, voice, and automation.
|
||||
- **Opening New Doors**: Mermaid AI and our Visual Editor are breaking down barriers, making sophisticated diagramming accessible to everyone, not just software engineers.
|
||||
- **Looking Forward**: We're not stopping here! Expect groundbreaking features like automated documentation tools, advanced AI diagramming, and high-security on-premise solutions.
|
||||
|
||||
**Why It Matters for Mermaid JS:**
|
||||
|
||||
- **Continued support from Mermaid Chart**: At Mermaid Chart, we value our still-growing Mermaid JS roots. As such, we have funneled back development and support to the project. Thanks to the successful seed round, we can continue to ramp up these efforts.
|
||||
|
||||
We are incredibly excited about the future and are grateful to the community, our team, and our investors for being part of this journey. Together, we're not just creating diagrams; we're designing the future of collaboration.
|
||||
|
||||
🌐 Learn more about our groundbreaking tools and what's next for Mermaid Chart by visiting [our website](https://www.mermaidchart.com/blog/posts/mermaid-chart-raises-7.5m-to-reinvent-visual-collaoration-for-enterprises).
|
||||
|
||||
Thank you for being part of our story. Here's to creating, innovating, and collaborating on a global scale!
|
||||
|
||||
Knut Sveidqvist 🧜♂️✨
|
||||
|
||||
## Mermaid Chart's Visual Editor for Flowcharts and Sequence diagrams
|
||||
|
||||
The Mermaid Chart team is excited to introduce a new Visual Editor for Flowcharts and Sequence diagrams, enabling users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options.
|
||||
|
||||
Learn more:
|
||||
|
||||
- Visual Editor For Flowcharts
|
||||
|
||||
- [Blog post](https://www.mermaidchart.com/blog/posts/mermaid-chart-releases-new-visual-editor-for-flowcharts)
|
||||
|
||||
- [Demo video](https://www.youtube.com/watch?v=5aja0gijoO0)
|
||||
|
||||
- Visual Editor For Sequence diagrams
|
||||
|
||||
- [Blog post](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams)
|
||||
|
||||
- [Demo video](https://youtu.be/imc2u5_N6Dc)
|
||||
Read more about it in our latest [BLOG POST](https://www.mermaidchart.com/blog/posts/mermaid-chart-releases-new-visual-editor-for-flowcharts) and watch a [DEMO VIDEO](https://www.youtube.com/watch?v=5aja0gijoO0) on our YouTube page.
|
||||
|
||||
## 📖 Blog posts
|
||||
|
||||
|
@@ -6,48 +6,6 @@
|
||||
|
||||
# Blog
|
||||
|
||||
## [How to Choose the Right Documentation Software](https://www.mermaidchart.com/blog/posts/how-to-choose-the-right-documentation-software/)
|
||||
|
||||
7 May 2024 · 5 mins
|
||||
|
||||
How to Choose the Right Documentation Software. Reliable and efficient documentation software is crucial in the fast-paced world of software development.
|
||||
|
||||
## [AI in software diagramming: What trends will define the future?](https://www.mermaidchart.com/blog/posts/ai-in-software-diagramming/)
|
||||
|
||||
24 April 2024 · 5 mins
|
||||
|
||||
Artificial intelligence (AI) tools are changing the way developers work.
|
||||
|
||||
## [Mermaid Chart Unveils Visual Editor for Sequence Diagrams](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams/)
|
||||
|
||||
8 April 2024 · 5 mins
|
||||
|
||||
Sequence diagrams are excellent tools for communication and documentation.
|
||||
|
||||
## [Modeling system states: It starts with a Turing machine](https://www.mermaidchart.com/blog/posts/modeling-system-states/)
|
||||
|
||||
27 March 2024 · 12 mins
|
||||
|
||||
In computer science, there are a few fundamental papers that, without exaggeration, changed everything.
|
||||
|
||||
## [Mermaid Chart Raises $7.5M to Reinvent Visual Collaboration for Enterprises](https://www.mermaidchart.com/blog/posts/mermaid-chart-raises-7.5m-to-reinvent-visual-collaoration-for-enterprises/)
|
||||
|
||||
20 March 2024 · 4 mins
|
||||
|
||||
Mermaid Chart, the company offering text-based diagramming and workflow management tools, today announced it has raised $7.5 million in Seed funding.
|
||||
|
||||
## [Mermaid Chart GPT Is Now Available In the GPT Store!](https://www.mermaidchart.com/blog/posts/mermaid-chart-gpt-is-now-available-in-the-gpt-store/)
|
||||
|
||||
7 March 2024 · 3 mins
|
||||
|
||||
Mermaid Chart GPT is Now Available In the GPT Store!
|
||||
|
||||
## [How to Make a Flowchart with Mermaid Chart](https://www.mermaidchart.com/blog/posts/how-to-make-flowcharts-with-mermaid-chart/)
|
||||
|
||||
30 January 2024 · 6 mins
|
||||
|
||||
Learn how to make a flowchart with Mermaid Chart, the leading text-to-diagram platform for both developers and non-developers.
|
||||
|
||||
## [How one data scientist uses Mermaid Chart to quickly and easily build flowcharts](https://www.mermaidchart.com/blog/posts/customer-spotlight-ari-tal/)
|
||||
|
||||
23 January 2024 · 4 mins
|
||||
|
@@ -143,7 +143,7 @@ After processing the tags, the remaining metadata items are interpreted as follo
|
||||
| `until <otherTaskId>` | End date of preceding task | Start date of previously specified task `otherTaskID` | n/a |
|
||||
|
||||
> **Note**
|
||||
> Support for keyword `until` was added in (v10.9.0+). This can be used to define a task which is running until some other specific task or milestone starts.
|
||||
> Support for keyword `until` was added in (v\<MERMAID_RELEASE_VERSION>+). This can be used to define a task which is running until some other specific task or milestone starts.
|
||||
|
||||
For simplicity, the table does not show the use of multiple tasks listed with the `after` keyword. Here is an example of how to use it and how it's interpreted:
|
||||
|
||||
|
@@ -300,7 +300,7 @@ From version 9.4.0 you can simplify this code to:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
</script>
|
||||
```
|
||||
|
||||
|
141
docs/syntax/packet.md
Normal file
141
docs/syntax/packet.md
Normal file
@@ -0,0 +1,141 @@
|
||||
> **Warning**
|
||||
>
|
||||
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
||||
>
|
||||
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/packet.md](../../packages/mermaid/src/docs/syntax/packet.md).
|
||||
|
||||
# Packet Diagram (v\<MERMAID_RELEASE_VERSION>+)
|
||||
|
||||
## Introduction
|
||||
|
||||
A packet diagram is a visual representation used to illustrate the structure and contents of a network packet. Network packets are the fundamental units of data transferred over a network.
|
||||
|
||||
## Usage
|
||||
|
||||
This diagram type is particularly useful for network engineers, educators, and students who require a clear and concise way to represent the structure of network packets.
|
||||
|
||||
## Syntax
|
||||
|
||||
```md
|
||||
packet-beta
|
||||
start: "Block name" %% Single-bit block
|
||||
start-end: "Block name" %% Multi-bit blocks
|
||||
... More Fields ...
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```mermaid-example
|
||||
---
|
||||
title: "TCP Packet"
|
||||
---
|
||||
packet-beta
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
64-95: "Acknowledgment Number"
|
||||
96-99: "Data Offset"
|
||||
100-105: "Reserved"
|
||||
106: "URG"
|
||||
107: "ACK"
|
||||
108: "PSH"
|
||||
109: "RST"
|
||||
110: "SYN"
|
||||
111: "FIN"
|
||||
112-127: "Window"
|
||||
128-143: "Checksum"
|
||||
144-159: "Urgent Pointer"
|
||||
160-191: "(Options and Padding)"
|
||||
192-255: "Data (variable length)"
|
||||
```
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: "TCP Packet"
|
||||
---
|
||||
packet-beta
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
64-95: "Acknowledgment Number"
|
||||
96-99: "Data Offset"
|
||||
100-105: "Reserved"
|
||||
106: "URG"
|
||||
107: "ACK"
|
||||
108: "PSH"
|
||||
109: "RST"
|
||||
110: "SYN"
|
||||
111: "FIN"
|
||||
112-127: "Window"
|
||||
128-143: "Checksum"
|
||||
144-159: "Urgent Pointer"
|
||||
160-191: "(Options and Padding)"
|
||||
192-255: "Data (variable length)"
|
||||
```
|
||||
|
||||
```mermaid-example
|
||||
packet-beta
|
||||
title UDP Packet
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-47: "Length"
|
||||
48-63: "Checksum"
|
||||
64-95: "Data (variable length)"
|
||||
```
|
||||
|
||||
```mermaid
|
||||
packet-beta
|
||||
title UDP Packet
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-47: "Length"
|
||||
48-63: "Checksum"
|
||||
64-95: "Data (variable length)"
|
||||
```
|
||||
|
||||
## Details of Syntax
|
||||
|
||||
- **Ranges**: Each line after the title represents a different field in the packet. The range (e.g., `0-15`) indicates the bit positions in the packet.
|
||||
- **Field Description**: A brief description of what the field represents, enclosed in quotes.
|
||||
|
||||
## Configuration
|
||||
|
||||
Please refer to the [configuration](/config/schema-docs/config-defs-packet-diagram-config.html) guide for details.
|
||||
|
||||
<!--
|
||||
|
||||
Theme variables are not currently working due to a mermaid bug. The passed values are not being propagated into styles function.
|
||||
|
||||
## Theme Variables
|
||||
|
||||
| Property | Description | Default Value |
|
||||
| ---------------- | -------------------------- | ------------- |
|
||||
| byteFontSize | Font size of the bytes | '10px' |
|
||||
| startByteColor | Color of the starting byte | 'black' |
|
||||
| endByteColor | Color of the ending byte | 'black' |
|
||||
| labelColor | Color of the labels | 'black' |
|
||||
| labelFontSize | Font size of the labels | '12px' |
|
||||
| titleColor | Color of the title | 'black' |
|
||||
| titleFontSize | Font size of the title | '14px' |
|
||||
| blockStrokeColor | Color of the block stroke | 'black' |
|
||||
| blockStrokeWidth | Width of the block stroke | '1' |
|
||||
| blockFillColor | Fill color of the block | '#efefef' |
|
||||
|
||||
## Example on config and theme
|
||||
|
||||
```mermaid-example
|
||||
---
|
||||
config:
|
||||
packet:
|
||||
showBits: true
|
||||
themeVariables:
|
||||
packet:
|
||||
startByteColor: red
|
||||
---
|
||||
packet-beta
|
||||
0-15: "Source Port"
|
||||
16-31: "Destination Port"
|
||||
32-63: "Sequence Number"
|
||||
```
|
||||
|
||||
-->
|
@@ -469,7 +469,7 @@ You can use this method to add mermaid including the timeline diagram to a web p
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
</script>
|
||||
```
|
||||
|
||||
|
@@ -7,9 +7,9 @@
|
||||
base = ""
|
||||
|
||||
# Directory that contains the deploy-ready HTML files and
|
||||
# assets generated by the build. This is an absolute path relative
|
||||
# assets generated by the build. This is an absolute path relative
|
||||
# to the base directory, which is the root by default (/).
|
||||
# This sample publishes the directory located at the absolute
|
||||
# This sample publishes the directory located at the absolute
|
||||
# path "root/project/build-output"
|
||||
|
||||
publish = "mermaid-live-editor/docs"
|
||||
|
23
package.json
23
package.json
@@ -15,15 +15,15 @@
|
||||
"git graph"
|
||||
],
|
||||
"scripts": {
|
||||
"build:vite": "tsx .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-zenuml/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-example-diagram/tsconfig.json --emitDeclarationOnly",
|
||||
"build": "pnpm build:esbuild && pnpm build:types",
|
||||
"build:esbuild": "pnpm run -r clean && tsx .esbuild/build.ts",
|
||||
"build:mermaid": "pnpm build:esbuild --mermaid",
|
||||
"build:viz": "pnpm build:esbuild --visualize",
|
||||
"build:types": "tsx .build/types.ts",
|
||||
"build:types:watch": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly --watch",
|
||||
"build:watch": "pnpm build:vite --watch",
|
||||
"build": "pnpm run -r clean && pnpm build:types && pnpm build:vite",
|
||||
"dev": "concurrently \"pnpm build:vite --watch\" \"tsx .vite/server.ts\"",
|
||||
"dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev",
|
||||
"dev": "tsx .esbuild/server.ts",
|
||||
"dev:vite": "tsx .vite/server.ts",
|
||||
"dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite",
|
||||
"release": "pnpm build",
|
||||
"lint": "eslint --cache --cache-strategy content --ignore-path .gitignore . && pnpm lint:jison && prettier --cache --check .",
|
||||
"lint:fix": "eslint --cache --cache-strategy content --fix --ignore-path .gitignore . && prettier --write . && tsx scripts/fixCSpell.ts",
|
||||
@@ -32,8 +32,8 @@
|
||||
"cypress": "cypress run",
|
||||
"cypress:open": "cypress open",
|
||||
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
|
||||
"e2e:coverage": "start-server-and-test dev:coverage http://localhost:9000/ cypress",
|
||||
"coverage:cypress:clean": "rimraf .nyc_output coverage/cypress",
|
||||
"e2e:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm e2e",
|
||||
"coverage:merge": "tsx scripts/coverage.ts",
|
||||
"coverage": "pnpm test:coverage --run && pnpm e2e:coverage && pnpm coverage:merge",
|
||||
"ci": "vitest run",
|
||||
@@ -74,7 +74,7 @@
|
||||
"@types/jsdom": "^21.1.1",
|
||||
"@types/lodash": "^4.14.194",
|
||||
"@types/mdast": "^3.0.11",
|
||||
"@types/node": "^20.11.10",
|
||||
"@types/node": "^20.11.17",
|
||||
"@types/prettier": "^2.7.2",
|
||||
"@types/rollup-plugin-visualizer": "^4.2.1",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
||||
@@ -83,6 +83,7 @@
|
||||
"@vitest/spy": "^0.34.0",
|
||||
"@vitest/ui": "^0.34.0",
|
||||
"ajv": "^8.12.0",
|
||||
"chokidar": "^3.5.3",
|
||||
"concurrently": "^8.0.1",
|
||||
"cors": "^2.8.5",
|
||||
"cspell": "^8.3.2",
|
||||
@@ -108,7 +109,9 @@
|
||||
"jison": "^0.4.18",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jsdom": "^22.0.0",
|
||||
"langium-cli": "3.0.1",
|
||||
"lint-staged": "^13.2.1",
|
||||
"markdown-table": "^3.0.3",
|
||||
"nyc": "^15.1.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"pnpm": "^8.6.8",
|
||||
|
45
packages/mermaid-flowchart-elk/package.json
Normal file
45
packages/mermaid-flowchart-elk/package.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@mermaid-js/flowchart-elk",
|
||||
"version": "1.0.0-rc.1",
|
||||
"description": "Flowchart plugin for mermaid with ELK layout",
|
||||
"module": "dist/mermaid-flowchart-elk.core.mjs",
|
||||
"types": "dist/packages/mermaid-flowchart-elk/src/detector.d.ts",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/mermaid-flowchart-elk.core.mjs",
|
||||
"types": "./dist/packages/mermaid-flowchart-elk/src/detector.d.ts"
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
"keywords": [
|
||||
"diagram",
|
||||
"markdown",
|
||||
"flowchart",
|
||||
"elk",
|
||||
"mermaid"
|
||||
],
|
||||
"scripts": {
|
||||
"prepublishOnly": "pnpm -w run build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mermaid-js/mermaid"
|
||||
},
|
||||
"author": "Knut Sveidqvist",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"d3": "^7.4.0",
|
||||
"dagre-d3-es": "7.0.10",
|
||||
"khroma": "^2.0.0",
|
||||
"elkjs": "^0.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^8.0.0",
|
||||
"rimraf": "^5.0.0",
|
||||
"mermaid": "workspace:^"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
32
packages/mermaid-flowchart-elk/src/detector.ts
Normal file
32
packages/mermaid-flowchart-elk/src/detector.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import type {
|
||||
ExternalDiagramDefinition,
|
||||
DiagramDetector,
|
||||
DiagramLoader,
|
||||
} from '../../mermaid/src/diagram-api/types.js';
|
||||
|
||||
const id = 'flowchart-elk';
|
||||
|
||||
const detector: DiagramDetector = (txt, config): boolean => {
|
||||
if (
|
||||
// If diagram explicitly states flowchart-elk
|
||||
/^\s*flowchart-elk/.test(txt) ||
|
||||
// If a flowchart/graph diagram has their default renderer set to elk
|
||||
(/^\s*flowchart|graph/.test(txt) && config?.flowchart?.defaultRenderer === 'elk')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const loader: DiagramLoader = async () => {
|
||||
const { diagram } = await import('./diagram-definition.js');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
12
packages/mermaid-flowchart-elk/src/diagram-definition.ts
Normal file
12
packages/mermaid-flowchart-elk/src/diagram-definition.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
// @ts-ignore: JISON typing missing
|
||||
import parser from '../../mermaid/src/diagrams/flowchart/parser/flow.jison';
|
||||
import * as db from '../../mermaid/src/diagrams/flowchart/flowDb.js';
|
||||
import styles from '../../mermaid/src/diagrams/flowchart/styles.js';
|
||||
import renderer from './flowRenderer-elk.js';
|
||||
|
||||
export const diagram = {
|
||||
db,
|
||||
renderer,
|
||||
parser,
|
||||
styles,
|
||||
};
|
@@ -1,17 +1,17 @@
|
||||
import { select, line, curveLinear } from 'd3';
|
||||
import { insertNode } from '../../../dagre-wrapper/nodes.js';
|
||||
import insertMarkers from '../../../dagre-wrapper/markers.js';
|
||||
import { insertEdgeLabel } from '../../../dagre-wrapper/edges.js';
|
||||
import { insertNode } from '../../mermaid/src/dagre-wrapper/nodes.js';
|
||||
import insertMarkers from '../../mermaid/src/dagre-wrapper/markers.js';
|
||||
import { insertEdgeLabel } from '../../mermaid/src/dagre-wrapper/edges.js';
|
||||
import { findCommonAncestor } from './render-utils.js';
|
||||
import { labelHelper } from '../../../dagre-wrapper/shapes/util.js';
|
||||
import { getConfig } from '../../../config.js';
|
||||
import { log } from '../../../logger.js';
|
||||
import { setupGraphViewbox } from '../../../setupGraphViewbox.js';
|
||||
import common from '../../common/common.js';
|
||||
import { interpolateToCurve, getStylesFromArray } from '../../../utils.js';
|
||||
import { labelHelper } from '../../mermaid/src/dagre-wrapper/shapes/util.js';
|
||||
import { getConfig } from '../../mermaid/src/config.js';
|
||||
import { log } from '../../mermaid/src/logger.js';
|
||||
import { setupGraphViewbox } from '../../mermaid/src/setupGraphViewbox.js';
|
||||
import common from '../../mermaid/src/diagrams/common/common.js';
|
||||
import { interpolateToCurve, getStylesFromArray } from '../../mermaid/src/utils.js';
|
||||
import ELK from 'elkjs/lib/elk.bundled.js';
|
||||
import { getLineFunctionsWithOffset } from '../../../utils/lineWithOffset.js';
|
||||
import { addEdgeMarkers } from '../../../dagre-wrapper/edgeMarker.js';
|
||||
import { getLineFunctionsWithOffset } from '../../mermaid/src/utils/lineWithOffset.js';
|
||||
import { addEdgeMarkers } from '../../mermaid/src/dagre-wrapper/edgeMarker.js';
|
||||
|
||||
const elk = new ELK();
|
||||
|
||||
@@ -594,7 +594,7 @@ const addMarkersToEdge = function (svgPath, edgeData, diagramType, arrowMarkerAb
|
||||
*
|
||||
* @param text
|
||||
* @param diagObj
|
||||
* @returns {Record<string, import('../../../diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
|
||||
* @returns {Record<string, import('../../mermaid/src/diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
|
||||
*/
|
||||
export const getClasses = function (text, diagObj) {
|
||||
log.info('Extracting classes');
|
10
packages/mermaid-flowchart-elk/tsconfig.json
Normal file
10
packages/mermaid-flowchart-elk/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "../..",
|
||||
"outDir": "./dist",
|
||||
"types": ["vitest/importMeta", "vitest/globals"]
|
||||
},
|
||||
"include": ["./src/**/*.ts"],
|
||||
"typeRoots": ["./src/types"]
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mermaid-js/mermaid-zenuml",
|
||||
"version": "0.2.0",
|
||||
"version": "0.1.2",
|
||||
"description": "MermaidJS plugin for ZenUML integration",
|
||||
"module": "dist/mermaid-zenuml.core.mjs",
|
||||
"types": "dist/detector.d.ts",
|
||||
@@ -19,6 +19,7 @@
|
||||
"mermaid"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"prepublishOnly": "pnpm -w run build"
|
||||
},
|
||||
"repository": {
|
||||
|
@@ -5,7 +5,6 @@
|
||||
* This is a dummy parser that satisfies the mermaid API logic.
|
||||
*/
|
||||
export default {
|
||||
parser: { yy: {} },
|
||||
parse: () => {
|
||||
// no op
|
||||
},
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user