mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-21 01:06:43 +02:00
Compare commits
242 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7fec51f322 | ||
![]() |
1659ace65d | ||
![]() |
3340608689 | ||
![]() |
a43cd55c53 | ||
![]() |
70d236244f | ||
![]() |
171a2019ec | ||
![]() |
70df6bbbca | ||
![]() |
5807d521b7 | ||
![]() |
2b2bbe35d0 | ||
![]() |
d11bfaa6c4 | ||
![]() |
25cd86feec | ||
![]() |
062176d8d0 | ||
![]() |
a344d88020 | ||
![]() |
30b180d77b | ||
![]() |
00423ed152 | ||
![]() |
48ff3b2c11 | ||
![]() |
eee0d4bf31 | ||
![]() |
e047755a21 | ||
![]() |
b30d609d19 | ||
![]() |
191ea24e29 | ||
![]() |
72a6fad1db | ||
![]() |
a2a99485f9 | ||
![]() |
969e2c1ff1 | ||
![]() |
55be75c974 | ||
![]() |
47a6ce4342 | ||
![]() |
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
|
getBoundarys
|
||||||
grammr
|
grammr
|
||||||
graphtype
|
graphtype
|
||||||
|
iife
|
||||||
interp
|
interp
|
||||||
introdcued
|
introdcued
|
||||||
INVTRAPEND
|
INVTRAPEND
|
||||||
@@ -74,11 +75,13 @@ loglevel
|
|||||||
LOGMSG
|
LOGMSG
|
||||||
lookaheads
|
lookaheads
|
||||||
mdast
|
mdast
|
||||||
|
metafile
|
||||||
minlen
|
minlen
|
||||||
Mstartx
|
Mstartx
|
||||||
MULT
|
MULT
|
||||||
NODIR
|
NODIR
|
||||||
NSTR
|
NSTR
|
||||||
|
outdir
|
||||||
Qcontrolx
|
Qcontrolx
|
||||||
reinit
|
reinit
|
||||||
rels
|
rels
|
||||||
|
@@ -36,6 +36,7 @@ jsfiddle
|
|||||||
jsonschema
|
jsonschema
|
||||||
katex
|
katex
|
||||||
khroma
|
khroma
|
||||||
|
langium
|
||||||
mathml
|
mathml
|
||||||
matplotlib
|
matplotlib
|
||||||
mdbook
|
mdbook
|
||||||
|
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
|
coverage
|
||||||
*.json
|
*.json
|
||||||
node_modules
|
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.
|
# Turing off for now as code coverage isn't stable and causes unnecessary build failures.
|
||||||
# default:
|
# default:
|
||||||
# threshold: 2%
|
# threshold: 2%
|
||||||
|
patch: off
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -46,4 +46,8 @@ stats/
|
|||||||
|
|
||||||
demos/dev/**
|
demos/dev/**
|
||||||
!/demos/dev/example.html
|
!/demos/dev/example.html
|
||||||
|
!/demos/dev/reload.js
|
||||||
tsx-0/**
|
tsx-0/**
|
||||||
|
|
||||||
|
# autogenereated by langium-cli
|
||||||
|
generated/
|
@@ -11,6 +11,8 @@ stats
|
|||||||
.nyc_output
|
.nyc_output
|
||||||
# Autogenerated by `pnpm run --filter mermaid types:build-config`
|
# Autogenerated by `pnpm run --filter mermaid types:build-config`
|
||||||
packages/mermaid/src/config.type.ts
|
packages/mermaid/src/config.type.ts
|
||||||
|
# autogenereated by langium-cli
|
||||||
|
generated/
|
||||||
# Ignore the files creates in /demos/dev except for example.html
|
# Ignore the files creates in /demos/dev except for example.html
|
||||||
demos/dev/**
|
demos/dev/**
|
||||||
!/demos/dev/example.html
|
!/demos/dev/example.html
|
||||||
|
@@ -3,11 +3,12 @@ import { resolve } from 'path';
|
|||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import jisonPlugin from './jisonPlugin.js';
|
import jisonPlugin from './jisonPlugin.js';
|
||||||
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
|
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
|
||||||
import { readFileSync } from 'fs';
|
|
||||||
import typescript from '@rollup/plugin-typescript';
|
import typescript from '@rollup/plugin-typescript';
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js';
|
import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js';
|
||||||
import istanbul from 'vite-plugin-istanbul';
|
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 visualize = process.argv.includes('--visualize');
|
||||||
const watch = process.argv.includes('--watch');
|
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 {
|
interface BuildOptions {
|
||||||
minify: boolean | 'esbuild';
|
minify: boolean | 'esbuild';
|
||||||
core?: boolean;
|
core?: boolean;
|
||||||
@@ -72,34 +55,8 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
|||||||
sourcemap,
|
sourcemap,
|
||||||
entryFileNames: `${name}.esm${minify ? '.min' : ''}.mjs`,
|
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 = {
|
const config: InlineConfig = {
|
||||||
configFile: false,
|
configFile: false,
|
||||||
build: {
|
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
|
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
|
||||||
typescript({ compilerOptions: { declaration: false } }),
|
typescript({ compilerOptions: { declaration: false } }),
|
||||||
istanbul({
|
istanbul({
|
||||||
exclude: ['node_modules', 'test/', '__mocks__'],
|
exclude: ['node_modules', 'test/', '__mocks__', 'generated'],
|
||||||
extension: ['.js', '.ts'],
|
extension: ['.js', '.ts'],
|
||||||
requireEnv: true,
|
requireEnv: true,
|
||||||
forceBuildInstrument: coverage,
|
forceBuildInstrument: coverage,
|
||||||
@@ -149,24 +106,28 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
|||||||
|
|
||||||
const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
||||||
await build(getBuildConfig({ minify: false, entryName }));
|
await build(getBuildConfig({ minify: false, entryName }));
|
||||||
await build(getBuildConfig({ minify: 'esbuild', entryName }));
|
|
||||||
await build(getBuildConfig({ minify: false, core: true, entryName }));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
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 buildPackage(pkg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
await generateLangium();
|
||||||
|
|
||||||
if (watch) {
|
if (watch) {
|
||||||
|
await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' }));
|
||||||
build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
|
build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
|
||||||
if (!mermaidOnly) {
|
if (!mermaidOnly) {
|
||||||
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
|
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
|
||||||
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' }));
|
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' }));
|
||||||
}
|
}
|
||||||
} else if (visualize) {
|
} 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: true, entryName: 'mermaid' }));
|
||||||
await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }));
|
await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }));
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import { transformJison } from './jisonTransformer.js';
|
import { transformJison } from '../.build/jisonTransformer.js';
|
||||||
|
|
||||||
const fileRegex = /\.(jison)$/;
|
const fileRegex = /\.(jison)$/;
|
||||||
|
|
||||||
export default function jison() {
|
export default function jison() {
|
||||||
return {
|
return {
|
||||||
name: 'jison',
|
name: 'jison',
|
||||||
|
|
||||||
transform(src: string, id: string) {
|
transform(src: string, id: string) {
|
||||||
if (fileRegex.test(id)) {
|
if (fileRegex.test(id)) {
|
||||||
return {
|
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 { PluginOption } from 'vite';
|
||||||
|
import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.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',
|
|
||||||
] 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vite plugin that handles JSON Schemas saved as a `.schema.yaml` file.
|
* Vite plugin that handles JSON Schemas saved as a `.schema.yaml` file.
|
||||||
@@ -121,32 +16,13 @@ export default function jsonSchemaPlugin(): PluginOption {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idAsUrl.searchParams.get('only-defaults')) {
|
const jsonSchema = loadSchema(src, idAsUrl.pathname);
|
||||||
const jsonSchema = load(src, {
|
return {
|
||||||
filename: idAsUrl.pathname,
|
code: idAsUrl.searchParams.get('only-defaults')
|
||||||
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
|
? getDefaults(jsonSchema)
|
||||||
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
|
: getSchema(jsonSchema),
|
||||||
schema: JSON_SCHEMA,
|
map: null, // no source map
|
||||||
}) 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
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { createServer as createViteServer } from 'vite';
|
import { createServer as createViteServer } from 'vite';
|
||||||
|
import { packageOptions } from '../.build/common.js';
|
||||||
|
|
||||||
async function createServer() {
|
async function createServer() {
|
||||||
const app = express();
|
const app = express();
|
||||||
@@ -14,9 +15,9 @@ async function createServer() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
app.use(express.static('./packages/mermaid/dist'));
|
for (const { packageName } of Object.values(packageOptions)) {
|
||||||
app.use(express.static('./packages/mermaid-zenuml/dist'));
|
app.use(express.static(`./packages/${packageName}/dist`));
|
||||||
app.use(express.static('./packages/mermaid-example-diagram/dist'));
|
}
|
||||||
app.use(vite.middlewares);
|
app.use(vite.middlewares);
|
||||||
app.use(express.static('demos'));
|
app.use(express.static('demos'));
|
||||||
app.use(express.static('cypress/platform'));
|
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,
|
|
||||||
};
|
|
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>');
|
|
||||||
});
|
|
||||||
});
|
|
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>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<script src="./viewer.js" type="module"></script>
|
<script type="module" src="./viewer.js"></script>
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
|
@@ -11,8 +11,7 @@ example-diagram
|
|||||||
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
|
<!-- <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" src="./external-diagrams-mindmap.mjs" /> -->
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import exampleDiagram from '../../packages/mermaid-example-diagram/dist/mermaid-example-diagram.core.mjs';
|
import exampleDiagram from './mermaid-example-diagram.esm.mjs';
|
||||||
// import example from '../../packages/mermaid-example-diagram/src/detector';
|
|
||||||
import mermaid from './mermaid.esm.mjs';
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
|
||||||
await mermaid.registerExternalDiagrams([exampleDiagram]);
|
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
|
graph TB
|
||||||
Function-->URL
|
Function-->URL
|
||||||
click Function clickByFlow "Add a div"
|
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>
|
||||||
<pre id="FirstLine" class="mermaid2">
|
<pre id="FirstLine" class="mermaid2">
|
||||||
graph TB
|
graph TB
|
||||||
1Function-->2URL
|
1Function-->2URL
|
||||||
click 1Function clickByFlow "Add a div"
|
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>
|
||||||
|
|
||||||
<pre id="FirstLine" class="mermaid2">
|
<pre id="FirstLine" class="mermaid2">
|
||||||
classDiagram
|
classDiagram
|
||||||
class Test
|
class Test
|
||||||
class ShapeLink
|
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
|
class ShapeCallback
|
||||||
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
||||||
</pre>
|
</pre>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<pre id="FirstLine" class="mermaid">
|
<pre id="FirstLine" class="mermaid">
|
||||||
classDiagram-v2
|
classDiagram-v2
|
||||||
class ShapeLink
|
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>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||||
Calling a Callback with args :cl3, 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 cl2 call clickByGantt()
|
||||||
click cl3 call clickByGantt("test1", test2, test3)
|
click cl3 call clickByGantt("test1", test2, test3)
|
||||||
|
|
||||||
@@ -102,9 +102,15 @@
|
|||||||
div.className = 'created-by-gant-click';
|
div.className = 'created-by-gant-click';
|
||||||
div.style = 'padding: 20px; background: green; color: white;';
|
div.style = 'padding: 20px; background: green; color: white;';
|
||||||
div.innerText = 'Clicked By Gant';
|
div.innerText = 'Clicked By Gant';
|
||||||
if (arg1) div.innerText += ' ' + arg1;
|
if (arg1) {
|
||||||
if (arg2) div.innerText += ' ' + arg2;
|
div.innerText += ' ' + arg1;
|
||||||
if (arg3) div.innerText += ' ' + arg3;
|
}
|
||||||
|
if (arg2) {
|
||||||
|
div.innerText += ' ' + arg2;
|
||||||
|
}
|
||||||
|
if (arg3) {
|
||||||
|
div.innerText += ' ' + arg3;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementsByTagName('body')[0].appendChild(div);
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import mermaid2 from './mermaid.esm.mjs';
|
import mermaid from './mermaid.esm.mjs';
|
||||||
import externalExample from '../../packages/mermaid-example-diagram/dist/mermaid-example-diagram.core.mjs';
|
import externalExample from './mermaid-example-diagram.esm.mjs';
|
||||||
import zenUml from '../../packages/mermaid-zenuml/dist/mermaid-zenuml.core.mjs';
|
import zenUml from './mermaid-zenuml.esm.mjs';
|
||||||
|
|
||||||
function b64ToUtf8(str) {
|
function b64ToUtf8(str) {
|
||||||
return decodeURIComponent(escape(window.atob(str)));
|
return decodeURIComponent(escape(window.atob(str)));
|
||||||
@@ -45,9 +45,9 @@ const contentLoaded = async function () {
|
|||||||
document.getElementsByTagName('body')[0].appendChild(div);
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
await mermaid2.registerExternalDiagrams([externalExample, zenUml]);
|
await mermaid.registerExternalDiagrams([externalExample, zenUml]);
|
||||||
mermaid2.initialize(graphObj.mermaid);
|
mermaid.initialize(graphObj.mermaid);
|
||||||
await mermaid2.run();
|
await mermaid.run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,18 +95,14 @@ const contentLoadedApi = async function () {
|
|||||||
divs[i] = div;
|
divs[i] = div;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultE2eCnf = { theme: 'forest' };
|
const defaultE2eCnf = { theme: 'forest', startOnLoad: false };
|
||||||
|
|
||||||
const cnf = merge(defaultE2eCnf, graphObj.mermaid);
|
const cnf = merge(defaultE2eCnf, graphObj.mermaid);
|
||||||
|
|
||||||
mermaid2.initialize(cnf);
|
mermaid.initialize(cnf);
|
||||||
|
|
||||||
for (let i = 0; i < numCodes; i++) {
|
for (let i = 0; i < numCodes; i++) {
|
||||||
const { svg, bindFunctions } = await mermaid2.render(
|
const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
|
||||||
'newid' + i,
|
|
||||||
graphObj.code[i],
|
|
||||||
divs[i]
|
|
||||||
);
|
|
||||||
div.innerHTML = svg;
|
div.innerHTML = svg;
|
||||||
bindFunctions(div);
|
bindFunctions(div);
|
||||||
}
|
}
|
||||||
@@ -114,18 +110,21 @@ const contentLoadedApi = async function () {
|
|||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.id = 'block';
|
div.id = 'block';
|
||||||
div.className = 'mermaid';
|
div.className = 'mermaid';
|
||||||
console.warn('graphObj.mermaid', graphObj.mermaid);
|
console.warn('graphObj', graphObj);
|
||||||
document.getElementsByTagName('body')[0].appendChild(div);
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
mermaid2.initialize(graphObj.mermaid);
|
mermaid.initialize(graphObj.mermaid);
|
||||||
|
const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
|
||||||
const { svg, bindFunctions } = await mermaid2.render('newid', graphObj.code, div);
|
|
||||||
div.innerHTML = svg;
|
div.innerHTML = svg;
|
||||||
|
console.log(div.innerHTML);
|
||||||
bindFunctions(div);
|
bindFunctions(div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
|
mermaid.initialize({
|
||||||
|
startOnLoad: false,
|
||||||
|
});
|
||||||
/*!
|
/*!
|
||||||
* Wait for document loaded before starting the execution
|
* Wait for document loaded before starting the execution
|
||||||
*/
|
*/
|
||||||
|
@@ -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>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script src="./viewer.js" type="module"></script>
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||||
<style>
|
<style>
|
||||||
.malware {
|
.malware {
|
||||||
@@ -33,12 +32,6 @@
|
|||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="module">
|
<script type="module" src="./viewer.js"></script>
|
||||||
import mermaid from './mermaid.esm.mjs';
|
|
||||||
mermaid.initialize({
|
|
||||||
startOnLoad: false,
|
|
||||||
useMaxWidth: true,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -3,6 +3,22 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Mermaid development page</title>
|
<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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
@@ -13,22 +29,37 @@ graph TB
|
|||||||
c --> d
|
c --> d
|
||||||
</pre>
|
</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">
|
<script type="module">
|
||||||
import mermaid from '/mermaid.esm.mjs';
|
import mermaid from '/mermaid.esm.mjs';
|
||||||
mermaid.parseError = function (err, hash) {
|
async function render(str) {
|
||||||
console.error('Mermaid error: ', err);
|
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({
|
mermaid.initialize({
|
||||||
startOnLoad: true,
|
startOnLoad: true,
|
||||||
logLevel: 0,
|
logLevel: 0,
|
||||||
});
|
});
|
||||||
const value = `graph TD\nHello --> World`;
|
document.getElementById('code').addEventListener('input', async (e) => {
|
||||||
const el = document.getElementById('dynamicDiagram');
|
const value = e.target.value;
|
||||||
const { svg } = await mermaid.render('dd', value);
|
localStorage.setItem(storeKey, value);
|
||||||
console.log(svg);
|
await render(value);
|
||||||
el.innerHTML = svg;
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script src="/dev/reload.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</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>
|
<li>
|
||||||
<h2><a href="./sankey.html">Sankey</a></h2>
|
<h2><a href="./sankey.html">Sankey</a></h2>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<h2><a href="./packet.html">Packet</a></h2>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h2><a href="./block.html">Layered Blocks</a></h2>
|
<h2><a href="./block.html">Layered Blocks</a></h2>
|
||||||
</li>
|
</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>
|
</pre>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from './mermaid.esm.mjs';
|
import mermaid from '/mermaid.esm.mjs';
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
theme: 'forest',
|
theme: 'forest',
|
||||||
logLevel: 3,
|
logLevel: 3,
|
||||||
|
@@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
• `Optional` **suppressErrors**: `boolean`
|
• `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
|
#### 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
|
#### 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
|
#### 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
|
#### 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
|
## Interfaces
|
||||||
|
|
||||||
- [ParseOptions](../interfaces/mermaidAPI.ParseOptions.md)
|
- [ParseOptions](../interfaces/mermaidAPI.ParseOptions.md)
|
||||||
|
- [ParseResult](../interfaces/mermaidAPI.ParseResult.md)
|
||||||
- [RenderResult](../interfaces/mermaidAPI.RenderResult.md)
|
- [RenderResult](../interfaces/mermaidAPI.RenderResult.md)
|
||||||
|
|
||||||
## References
|
## References
|
||||||
@@ -25,13 +26,13 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
|
|||||||
|
|
||||||
#### Defined in
|
#### 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
|
## Variables
|
||||||
|
|
||||||
### mermaidAPI
|
### 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
|
## mermaidAPI configuration defaults
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ mermaid.initialize(config);
|
|||||||
|
|
||||||
#### Defined in
|
#### 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
|
## Functions
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ Return the last node appended
|
|||||||
|
|
||||||
#### Defined in
|
#### 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
|
#### 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
|
#### 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
|
#### 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
|
#### 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
|
#### 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
|
#### 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
|
```html
|
||||||
<script type="module">
|
<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>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ Example:
|
|||||||
B-->D(fa:fa-spinner);
|
B-->D(fa:fa-spinner);
|
||||||
</pre>
|
</pre>
|
||||||
<script type="module">
|
<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>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -331,15 +331,17 @@ module.exports = (options) ->
|
|||||||
|
|
||||||
## Advanced usage
|
## 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
|
The function `mermaid.parse(text, parseOptions)`, takes a text string as an argument and returns `{ diagramType: string }` if the definition follows mermaid's syntax.
|
||||||
false if it does not. The parseError function will be called when the parse function returns false.
|
|
||||||
|
|
||||||
When the parser encounters invalid syntax the **mermaid.parseError** function is called. It is possible to override this
|
If the definition is invalid, the function returns `false` if `parseOptions.suppressErrors` is set to `true`. Otherwise, it throws an error.
|
||||||
function in order to handle the error in an application-specific way.
|
|
||||||
|
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:
|
The code-example below in meta code illustrates how this could work:
|
||||||
|
|
||||||
@@ -359,26 +361,10 @@ const textFieldUpdated = async function () {
|
|||||||
bindEventHandler('change', 'code', textFieldUpdated);
|
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
|
## Configuration
|
||||||
|
|
||||||
Mermaid takes a number of options which lets you tweak the rendering of the diagrams. Currently there are three ways of
|
You can pass the required configuration to the `mermaid.initialize` call. This is the preferred way of configuring mermaid.
|
||||||
setting the options in mermaid.
|
The list of configuration objects are described [in the mermaidAPI documentation](./setup/README.md).
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<script type="module">
|
||||||
@@ -408,35 +394,6 @@ mermaid.startOnLoad = true;
|
|||||||
> **Warning**
|
> **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.
|
> 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:locale en,en-gb
|
||||||
cspell:ignore pumbaa
|
cspell:ignore pumbaa
|
||||||
|
@@ -224,7 +224,7 @@ b. The importing of the Mermaid library through the `mermaid.esm.mjs` or `mermai
|
|||||||
```html
|
```html
|
||||||
<body>
|
<body>
|
||||||
<script type="module">
|
<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 });
|
mermaid.initialize({ startOnLoad: true });
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
@@ -246,23 +246,23 @@ In this example, the `mermaidAPI` is being called through the `CDN`:
|
|||||||
<body>
|
<body>
|
||||||
Here is one mermaid diagram:
|
Here is one mermaid diagram:
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
graph TD
|
graph TD
|
||||||
A[Client] --> B[Load Balancer]
|
A[Client] --> B[Load Balancer]
|
||||||
B --> C[Server1]
|
B --> C[Server1]
|
||||||
B --> D[Server2]
|
B --> D[Server2]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
And here is another:
|
And here is another:
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
graph TD
|
graph TD
|
||||||
A[Client] -->|tcp_123| B
|
A[Client] -->|tcp_123| B
|
||||||
B(Load Balancer)
|
B(Load Balancer)
|
||||||
B -->|tcp_456| C[Server1]
|
B -->|tcp_456| C[Server1]
|
||||||
B -->|tcp_456| D[Server2]
|
B -->|tcp_456| D[Server2]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<script type="module">
|
<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 });
|
mermaid.initialize({ startOnLoad: true });
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
@@ -278,15 +278,15 @@ In this example, `mermaid.js` is referenced in `src` as a separate JavaScript fi
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
graph LR
|
graph LR
|
||||||
A --- B
|
A --- B
|
||||||
B-->C[fa:fa-ban forbidden]
|
B-->C[fa:fa-ban forbidden]
|
||||||
B-->D(fa:fa-spinner);
|
B-->D(fa:fa-spinner);
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
graph TD
|
graph TD
|
||||||
A[Client] --> B[Load Balancer]
|
A[Client] --> B[Load Balancer]
|
||||||
B --> C[Server1]
|
B --> C[Server1]
|
||||||
B --> D[Server2]
|
B --> D[Server2]
|
||||||
</pre>
|
</pre>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
@@ -317,7 +317,7 @@ To select a version:
|
|||||||
|
|
||||||
Replace `<version>` with the desired version number.
|
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
|
## Deploying Mermaid
|
||||||
|
|
||||||
@@ -335,7 +335,7 @@ To Deploy Mermaid:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<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 });
|
mermaid.initialize({ startOnLoad: true });
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
@@ -300,7 +300,7 @@ From version 9.4.0 you can simplify this code to:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<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>
|
</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
|
```html
|
||||||
<script type="module">
|
<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>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -7,9 +7,9 @@
|
|||||||
base = ""
|
base = ""
|
||||||
|
|
||||||
# Directory that contains the deploy-ready HTML files and
|
# 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 (/).
|
# 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"
|
# path "root/project/build-output"
|
||||||
|
|
||||||
publish = "mermaid-live-editor/docs"
|
publish = "mermaid-live-editor/docs"
|
||||||
|
22
package.json
22
package.json
@@ -15,15 +15,15 @@
|
|||||||
"git graph"
|
"git graph"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:vite": "tsx .vite/build.ts",
|
"build": "pnpm build:esbuild && pnpm build:types",
|
||||||
"build:mermaid": "pnpm build:vite --mermaid",
|
"build:esbuild": "pnpm run -r clean && tsx .esbuild/build.ts",
|
||||||
"build:viz": "pnpm build:mermaid --visualize",
|
"build:mermaid": "pnpm build:esbuild --mermaid",
|
||||||
"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:viz": "pnpm build:esbuild --visualize",
|
||||||
|
"build:types": "tsx .build/types.ts",
|
||||||
"build:types:watch": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly --watch",
|
"build:types:watch": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly --watch",
|
||||||
"build:watch": "pnpm build:vite --watch",
|
"dev": "tsx .esbuild/server.ts",
|
||||||
"build": "pnpm run -r clean && pnpm build:types && pnpm build:vite",
|
"dev:vite": "tsx .vite/server.ts",
|
||||||
"dev": "concurrently \"pnpm build:vite --watch\" \"tsx .vite/server.ts\"",
|
"dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite",
|
||||||
"dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev",
|
|
||||||
"release": "pnpm build",
|
"release": "pnpm build",
|
||||||
"lint": "eslint --cache --cache-strategy content --ignore-path .gitignore . && pnpm lint:jison && prettier --cache --check .",
|
"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",
|
"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": "cypress run",
|
||||||
"cypress:open": "cypress open",
|
"cypress:open": "cypress open",
|
||||||
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
|
"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",
|
"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:merge": "tsx scripts/coverage.ts",
|
||||||
"coverage": "pnpm test:coverage --run && pnpm e2e:coverage && pnpm coverage:merge",
|
"coverage": "pnpm test:coverage --run && pnpm e2e:coverage && pnpm coverage:merge",
|
||||||
"ci": "vitest run",
|
"ci": "vitest run",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"@types/jsdom": "^21.1.1",
|
"@types/jsdom": "^21.1.1",
|
||||||
"@types/lodash": "^4.14.194",
|
"@types/lodash": "^4.14.194",
|
||||||
"@types/mdast": "^3.0.11",
|
"@types/mdast": "^3.0.11",
|
||||||
"@types/node": "^20.11.10",
|
"@types/node": "^20.11.17",
|
||||||
"@types/prettier": "^2.7.2",
|
"@types/prettier": "^2.7.2",
|
||||||
"@types/rollup-plugin-visualizer": "^4.2.1",
|
"@types/rollup-plugin-visualizer": "^4.2.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
||||||
@@ -83,6 +83,7 @@
|
|||||||
"@vitest/spy": "^0.34.0",
|
"@vitest/spy": "^0.34.0",
|
||||||
"@vitest/ui": "^0.34.0",
|
"@vitest/ui": "^0.34.0",
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
|
"chokidar": "^3.5.3",
|
||||||
"concurrently": "^8.0.1",
|
"concurrently": "^8.0.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cspell": "^8.3.2",
|
"cspell": "^8.3.2",
|
||||||
@@ -108,6 +109,7 @@
|
|||||||
"jison": "^0.4.18",
|
"jison": "^0.4.18",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jsdom": "^22.0.0",
|
"jsdom": "^22.0.0",
|
||||||
|
"langium-cli": "3.0.1",
|
||||||
"lint-staged": "^13.2.1",
|
"lint-staged": "^13.2.1",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
|
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 { select, line, curveLinear } from 'd3';
|
||||||
import { insertNode } from '../../../dagre-wrapper/nodes.js';
|
import { insertNode } from '../../mermaid/src/dagre-wrapper/nodes.js';
|
||||||
import insertMarkers from '../../../dagre-wrapper/markers.js';
|
import insertMarkers from '../../mermaid/src/dagre-wrapper/markers.js';
|
||||||
import { insertEdgeLabel } from '../../../dagre-wrapper/edges.js';
|
import { insertEdgeLabel } from '../../mermaid/src/dagre-wrapper/edges.js';
|
||||||
import { findCommonAncestor } from './render-utils.js';
|
import { findCommonAncestor } from './render-utils.js';
|
||||||
import { labelHelper } from '../../../dagre-wrapper/shapes/util.js';
|
import { labelHelper } from '../../mermaid/src/dagre-wrapper/shapes/util.js';
|
||||||
import { getConfig } from '../../../config.js';
|
import { getConfig } from '../../mermaid/src/config.js';
|
||||||
import { log } from '../../../logger.js';
|
import { log } from '../../mermaid/src/logger.js';
|
||||||
import { setupGraphViewbox } from '../../../setupGraphViewbox.js';
|
import { setupGraphViewbox } from '../../mermaid/src/setupGraphViewbox.js';
|
||||||
import common from '../../common/common.js';
|
import common from '../../mermaid/src/diagrams/common/common.js';
|
||||||
import { interpolateToCurve, getStylesFromArray } from '../../../utils.js';
|
import { interpolateToCurve, getStylesFromArray } from '../../mermaid/src/utils.js';
|
||||||
import ELK from 'elkjs/lib/elk.bundled.js';
|
import ELK from 'elkjs/lib/elk.bundled.js';
|
||||||
import { getLineFunctionsWithOffset } from '../../../utils/lineWithOffset.js';
|
import { getLineFunctionsWithOffset } from '../../mermaid/src/utils/lineWithOffset.js';
|
||||||
import { addEdgeMarkers } from '../../../dagre-wrapper/edgeMarker.js';
|
import { addEdgeMarkers } from '../../mermaid/src/dagre-wrapper/edgeMarker.js';
|
||||||
|
|
||||||
const elk = new ELK();
|
const elk = new ELK();
|
||||||
|
|
||||||
@@ -594,7 +594,7 @@ const addMarkersToEdge = function (svgPath, edgeData, diagramType, arrowMarkerAb
|
|||||||
*
|
*
|
||||||
* @param text
|
* @param text
|
||||||
* @param diagObj
|
* @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) {
|
export const getClasses = function (text, diagObj) {
|
||||||
log.info('Extracting classes');
|
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"]
|
||||||
|
}
|
@@ -19,6 +19,7 @@
|
|||||||
"mermaid"
|
"mermaid"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"clean": "rimraf dist",
|
||||||
"prepublishOnly": "pnpm -w run build"
|
"prepublishOnly": "pnpm -w run build"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
* This is a dummy parser that satisfies the mermaid API logic.
|
* This is a dummy parser that satisfies the mermaid API logic.
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
parser: { yy: {} },
|
|
||||||
parse: () => {
|
parse: () => {
|
||||||
// no op
|
// no op
|
||||||
},
|
},
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mermaid",
|
"name": "mermaid",
|
||||||
"version": "10.8.0",
|
"version": "11.0.0-alpha.6",
|
||||||
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "./dist/mermaid.core.mjs",
|
"module": "./dist/mermaid.core.mjs",
|
||||||
@@ -60,8 +60,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@braintree/sanitize-url": "^6.0.1",
|
"@braintree/sanitize-url": "^6.0.1",
|
||||||
"@types/d3-scale": "^4.0.3",
|
"@mermaid-js/parser": "workspace:^",
|
||||||
"@types/d3-scale-chromatic": "^3.0.0",
|
|
||||||
"cytoscape": "^3.28.1",
|
"cytoscape": "^3.28.1",
|
||||||
"cytoscape-cose-bilkent": "^4.1.0",
|
"cytoscape-cose-bilkent": "^4.1.0",
|
||||||
"d3": "^7.4.0",
|
"d3": "^7.4.0",
|
||||||
@@ -74,11 +73,9 @@
|
|||||||
"khroma": "^2.0.0",
|
"khroma": "^2.0.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mdast-util-from-markdown": "^1.3.0",
|
"mdast-util-from-markdown": "^1.3.0",
|
||||||
"non-layered-tidy-tree-layout": "^2.0.2",
|
|
||||||
"stylis": "^4.1.3",
|
"stylis": "^4.1.3",
|
||||||
"ts-dedent": "^2.2.0",
|
"ts-dedent": "^2.2.0",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0"
|
||||||
"web-worker": "^1.2.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@adobe/jsonschema2md": "^7.1.4",
|
"@adobe/jsonschema2md": "^7.1.4",
|
||||||
@@ -86,6 +83,7 @@
|
|||||||
"@types/d3": "^7.4.0",
|
"@types/d3": "^7.4.0",
|
||||||
"@types/d3-sankey": "^0.12.1",
|
"@types/d3-sankey": "^0.12.1",
|
||||||
"@types/d3-scale": "^4.0.3",
|
"@types/d3-scale": "^4.0.3",
|
||||||
|
"@types/d3-scale-chromatic": "^3.0.0",
|
||||||
"@types/d3-selection": "^3.0.5",
|
"@types/d3-selection": "^3.0.5",
|
||||||
"@types/d3-shape": "^3.1.1",
|
"@types/d3-shape": "^3.1.1",
|
||||||
"@types/dompurify": "^3.0.2",
|
"@types/dompurify": "^3.0.2",
|
||||||
|
@@ -233,6 +233,23 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType<MermaidCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workaround for type duplication when a $ref property has siblings.
|
||||||
|
*
|
||||||
|
* @param json - The input JSON object.
|
||||||
|
*
|
||||||
|
* @see https://github.com/bcherny/json-schema-to-typescript/issues/193
|
||||||
|
*/
|
||||||
|
function removeProp(json: any, name: string) {
|
||||||
|
for (const prop in json) {
|
||||||
|
if (prop === name) {
|
||||||
|
delete json[prop];
|
||||||
|
} else if (typeof json[prop] === 'object') {
|
||||||
|
removeProp(json[prop], name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Main function */
|
/** Main function */
|
||||||
async function main() {
|
async function main() {
|
||||||
if (verifyOnly) {
|
if (verifyOnly) {
|
||||||
@@ -243,6 +260,8 @@ async function main() {
|
|||||||
|
|
||||||
const configJsonSchema = await loadJsonSchemaFromYaml();
|
const configJsonSchema = await loadJsonSchemaFromYaml();
|
||||||
|
|
||||||
|
removeProp(configJsonSchema, 'default');
|
||||||
|
|
||||||
validateSchema(configJsonSchema);
|
validateSchema(configJsonSchema);
|
||||||
|
|
||||||
// Generate types from JSON Schema
|
// Generate types from JSON Schema
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
import * as configApi from './config.js';
|
import * as configApi from './config.js';
|
||||||
import { log } from './logger.js';
|
|
||||||
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI.js';
|
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI.js';
|
||||||
import { detectType, getDiagramLoader } from './diagram-api/detectType.js';
|
import { detectType, getDiagramLoader } from './diagram-api/detectType.js';
|
||||||
import { UnknownDiagramError } from './errors.js';
|
import { UnknownDiagramError } from './errors.js';
|
||||||
import { encodeEntities } from './utils.js';
|
import { encodeEntities } from './utils.js';
|
||||||
|
|
||||||
import type { DetailedError } from './utils.js';
|
import type { DetailedError } from './utils.js';
|
||||||
import type { DiagramDefinition, DiagramMetadata } from './diagram-api/types.js';
|
import type { DiagramDefinition, DiagramMetadata } from './diagram-api/types.js';
|
||||||
|
|
||||||
@@ -15,48 +13,45 @@ export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?:
|
|||||||
* @privateRemarks This is exported as part of the public mermaidAPI.
|
* @privateRemarks This is exported as part of the public mermaidAPI.
|
||||||
*/
|
*/
|
||||||
export class Diagram {
|
export class Diagram {
|
||||||
type = 'graph';
|
public static async fromText(text: string, metadata: Pick<DiagramMetadata, 'title'> = {}) {
|
||||||
parser: DiagramDefinition['parser'];
|
|
||||||
renderer: DiagramDefinition['renderer'];
|
|
||||||
db: DiagramDefinition['db'];
|
|
||||||
private init?: DiagramDefinition['init'];
|
|
||||||
|
|
||||||
private detectError?: UnknownDiagramError;
|
|
||||||
constructor(public text: string, public metadata: Pick<DiagramMetadata, 'title'> = {}) {
|
|
||||||
this.text = encodeEntities(text);
|
|
||||||
this.text += '\n';
|
|
||||||
const cnf = configApi.getConfig();
|
|
||||||
try {
|
|
||||||
this.type = detectType(text, cnf);
|
|
||||||
} catch (e) {
|
|
||||||
this.type = 'error';
|
|
||||||
this.detectError = e as UnknownDiagramError;
|
|
||||||
}
|
|
||||||
const diagram = getDiagram(this.type);
|
|
||||||
log.debug('Type ' + this.type);
|
|
||||||
// Setup diagram
|
|
||||||
this.db = diagram.db;
|
|
||||||
this.renderer = diagram.renderer;
|
|
||||||
this.parser = diagram.parser;
|
|
||||||
this.parser.parser.yy = this.db;
|
|
||||||
this.init = diagram.init;
|
|
||||||
this.parse();
|
|
||||||
}
|
|
||||||
|
|
||||||
parse() {
|
|
||||||
if (this.detectError) {
|
|
||||||
throw this.detectError;
|
|
||||||
}
|
|
||||||
this.db.clear?.();
|
|
||||||
const config = configApi.getConfig();
|
const config = configApi.getConfig();
|
||||||
this.init?.(config);
|
const type = detectType(text, config);
|
||||||
// This block was added for legacy compatibility. Use frontmatter instead of adding more special cases.
|
text = encodeEntities(text) + '\n';
|
||||||
if (this.metadata.title) {
|
try {
|
||||||
this.db.setDiagramTitle?.(this.metadata.title);
|
getDiagram(type);
|
||||||
|
} catch (e) {
|
||||||
|
const loader = getDiagramLoader(type);
|
||||||
|
if (!loader) {
|
||||||
|
throw new UnknownDiagramError(`Diagram ${type} not found.`);
|
||||||
|
}
|
||||||
|
// Diagram not available, loading it.
|
||||||
|
// new diagram will try getDiagram again and if fails then it is a valid throw
|
||||||
|
const { id, diagram } = await loader();
|
||||||
|
registerDiagram(id, diagram);
|
||||||
}
|
}
|
||||||
this.parser.parse(this.text);
|
const { db, parser, renderer, init } = getDiagram(type);
|
||||||
|
if (parser.parser) {
|
||||||
|
// The parser.parser.yy is only present in JISON parsers. So, we'll only set if required.
|
||||||
|
parser.parser.yy = db;
|
||||||
|
}
|
||||||
|
db.clear?.();
|
||||||
|
init?.(config);
|
||||||
|
// This block was added for legacy compatibility. Use frontmatter instead of adding more special cases.
|
||||||
|
if (metadata.title) {
|
||||||
|
db.setDiagramTitle?.(metadata.title);
|
||||||
|
}
|
||||||
|
await parser.parse(text);
|
||||||
|
return new Diagram(type, text, db, parser, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private constructor(
|
||||||
|
public type: string,
|
||||||
|
public text: string,
|
||||||
|
public db: DiagramDefinition['db'],
|
||||||
|
public parser: DiagramDefinition['parser'],
|
||||||
|
public renderer: DiagramDefinition['renderer']
|
||||||
|
) {}
|
||||||
|
|
||||||
async render(id: string, version: string) {
|
async render(id: string, version: string) {
|
||||||
await this.renderer.draw(this.text, id, version, this);
|
await this.renderer.draw(this.text, id, version, this);
|
||||||
}
|
}
|
||||||
@@ -69,34 +64,3 @@ export class Diagram {
|
|||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the text asynchronously and generate a Diagram object asynchronously.
|
|
||||||
* **Warning:** This function may be changed in the future.
|
|
||||||
* @alpha
|
|
||||||
* @param text - The mermaid diagram definition.
|
|
||||||
* @param metadata - Diagram metadata, defined in YAML.
|
|
||||||
* @returns A the Promise of a Diagram object.
|
|
||||||
* @throws {@link UnknownDiagramError} if the diagram type can not be found.
|
|
||||||
* @privateRemarks This is exported as part of the public mermaidAPI.
|
|
||||||
*/
|
|
||||||
export const getDiagramFromText = async (
|
|
||||||
text: string,
|
|
||||||
metadata: Pick<DiagramMetadata, 'title'> = {}
|
|
||||||
): Promise<Diagram> => {
|
|
||||||
const type = detectType(text, configApi.getConfig());
|
|
||||||
try {
|
|
||||||
// Trying to find the diagram
|
|
||||||
getDiagram(type);
|
|
||||||
} catch (error) {
|
|
||||||
const loader = getDiagramLoader(type);
|
|
||||||
if (!loader) {
|
|
||||||
throw new UnknownDiagramError(`Diagram ${type} not found.`);
|
|
||||||
}
|
|
||||||
// Diagram not available, loading it.
|
|
||||||
// new diagram will try getDiagram again and if fails then it is a valid throw
|
|
||||||
const { id, diagram } = await loader();
|
|
||||||
registerDiagram(id, diagram);
|
|
||||||
}
|
|
||||||
return new Diagram(text, metadata);
|
|
||||||
};
|
|
||||||
|
@@ -61,7 +61,7 @@ export interface MermaidConfig {
|
|||||||
* You may also use `themeCSS` to override this value.
|
* You may also use `themeCSS` to override this value.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
theme?: string | 'default' | 'forest' | 'dark' | 'neutral' | 'null';
|
theme?: 'default' | 'forest' | 'dark' | 'neutral' | 'null';
|
||||||
themeVariables?: any;
|
themeVariables?: any;
|
||||||
themeCSS?: string;
|
themeCSS?: string;
|
||||||
/**
|
/**
|
||||||
@@ -87,26 +87,11 @@ export interface MermaidConfig {
|
|||||||
* This option decides the amount of logging to be used by mermaid.
|
* This option decides the amount of logging to be used by mermaid.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
logLevel?:
|
logLevel?: 'trace' | 0 | 'debug' | 1 | 'info' | 2 | 'warn' | 3 | 'error' | 4 | 'fatal' | 5;
|
||||||
| number
|
|
||||||
| string
|
|
||||||
| 0
|
|
||||||
| 2
|
|
||||||
| 1
|
|
||||||
| 'trace'
|
|
||||||
| 'debug'
|
|
||||||
| 'info'
|
|
||||||
| 'warn'
|
|
||||||
| 'error'
|
|
||||||
| 'fatal'
|
|
||||||
| 3
|
|
||||||
| 4
|
|
||||||
| 5
|
|
||||||
| undefined;
|
|
||||||
/**
|
/**
|
||||||
* Level of trust for parsed diagram
|
* Level of trust for parsed diagram
|
||||||
*/
|
*/
|
||||||
securityLevel?: string | 'strict' | 'loose' | 'antiscript' | 'sandbox' | undefined;
|
securityLevel?: 'strict' | 'loose' | 'antiscript' | 'sandbox';
|
||||||
/**
|
/**
|
||||||
* Dictates whether mermaid starts on Page load
|
* Dictates whether mermaid starts on Page load
|
||||||
*/
|
*/
|
||||||
@@ -169,19 +154,43 @@ export interface MermaidConfig {
|
|||||||
gitGraph?: GitGraphDiagramConfig;
|
gitGraph?: GitGraphDiagramConfig;
|
||||||
c4?: C4DiagramConfig;
|
c4?: C4DiagramConfig;
|
||||||
sankey?: SankeyDiagramConfig;
|
sankey?: SankeyDiagramConfig;
|
||||||
|
packet?: PacketDiagramConfig;
|
||||||
block?: BlockDiagramConfig;
|
block?: BlockDiagramConfig;
|
||||||
dompurifyConfig?: DOMPurifyConfiguration;
|
dompurifyConfig?: DOMPurifyConfiguration;
|
||||||
wrap?: boolean;
|
wrap?: boolean;
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* The object containing configurations specific for block diagrams.
|
* The object containing configurations specific for packet diagrams.
|
||||||
*
|
*
|
||||||
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
||||||
* via the `definition` "BlockDiagramConfig".
|
* via the `definition` "PacketDiagramConfig".
|
||||||
*/
|
*/
|
||||||
export interface BlockDiagramConfig extends BaseDiagramConfig {
|
export interface PacketDiagramConfig extends BaseDiagramConfig {
|
||||||
padding?: number;
|
/**
|
||||||
|
* The height of each row in the packet diagram.
|
||||||
|
*/
|
||||||
|
rowHeight?: number;
|
||||||
|
/**
|
||||||
|
* The width of each bit in the packet diagram.
|
||||||
|
*/
|
||||||
|
bitWidth?: number;
|
||||||
|
/**
|
||||||
|
* The number of bits to display per row.
|
||||||
|
*/
|
||||||
|
bitsPerRow?: number;
|
||||||
|
/**
|
||||||
|
* Toggle to display or hide bit numbers.
|
||||||
|
*/
|
||||||
|
showBits?: boolean;
|
||||||
|
/**
|
||||||
|
* The horizontal padding between the blocks in a row.
|
||||||
|
*/
|
||||||
|
paddingX?: number;
|
||||||
|
/**
|
||||||
|
* The vertical padding between the rows.
|
||||||
|
*/
|
||||||
|
paddingY?: number;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
||||||
@@ -197,6 +206,15 @@ export interface BaseDiagramConfig {
|
|||||||
*/
|
*/
|
||||||
useMaxWidth?: boolean;
|
useMaxWidth?: boolean;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* The object containing configurations specific for block diagrams.
|
||||||
|
*
|
||||||
|
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
||||||
|
* via the `definition` "BlockDiagramConfig".
|
||||||
|
*/
|
||||||
|
export interface BlockDiagramConfig extends BaseDiagramConfig {
|
||||||
|
padding?: number;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* The object containing configurations specific for c4 diagrams
|
* The object containing configurations specific for c4 diagrams
|
||||||
*
|
*
|
||||||
@@ -807,8 +825,8 @@ export interface XYChartConfig extends BaseDiagramConfig {
|
|||||||
* Should show the chart title
|
* Should show the chart title
|
||||||
*/
|
*/
|
||||||
showTitle?: boolean;
|
showTitle?: boolean;
|
||||||
xAxis?: XYChartAxisConfig1;
|
xAxis?: XYChartAxisConfig;
|
||||||
yAxis?: XYChartAxisConfig2;
|
yAxis?: XYChartAxisConfig;
|
||||||
/**
|
/**
|
||||||
* How to plot will be drawn horizontal or vertical
|
* How to plot will be drawn horizontal or vertical
|
||||||
*/
|
*/
|
||||||
@@ -818,104 +836,6 @@ export interface XYChartConfig extends BaseDiagramConfig {
|
|||||||
*/
|
*/
|
||||||
plotReservedSpacePercent?: number;
|
plotReservedSpacePercent?: number;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* This object contains configuration for XYChart axis config
|
|
||||||
*/
|
|
||||||
export interface XYChartAxisConfig1 {
|
|
||||||
/**
|
|
||||||
* Should show the axis labels (tick text)
|
|
||||||
*/
|
|
||||||
showLabel?: boolean;
|
|
||||||
/**
|
|
||||||
* font size of the axis labels (tick text)
|
|
||||||
*/
|
|
||||||
labelFontSize?: number;
|
|
||||||
/**
|
|
||||||
* top and bottom space from axis label (tick text)
|
|
||||||
*/
|
|
||||||
labelPadding?: number;
|
|
||||||
/**
|
|
||||||
* Should show the axis title
|
|
||||||
*/
|
|
||||||
showTitle?: boolean;
|
|
||||||
/**
|
|
||||||
* font size of the axis title
|
|
||||||
*/
|
|
||||||
titleFontSize?: number;
|
|
||||||
/**
|
|
||||||
* top and bottom space from axis title
|
|
||||||
*/
|
|
||||||
titlePadding?: number;
|
|
||||||
/**
|
|
||||||
* Should show the axis tick lines
|
|
||||||
*/
|
|
||||||
showTick?: boolean;
|
|
||||||
/**
|
|
||||||
* length of the axis tick lines
|
|
||||||
*/
|
|
||||||
tickLength?: number;
|
|
||||||
/**
|
|
||||||
* width of the axis tick lines
|
|
||||||
*/
|
|
||||||
tickWidth?: number;
|
|
||||||
/**
|
|
||||||
* Show line across the axis
|
|
||||||
*/
|
|
||||||
showAxisLine?: boolean;
|
|
||||||
/**
|
|
||||||
* Width of the axis line
|
|
||||||
*/
|
|
||||||
axisLineWidth?: number;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* This object contains configuration for XYChart axis config
|
|
||||||
*/
|
|
||||||
export interface XYChartAxisConfig2 {
|
|
||||||
/**
|
|
||||||
* Should show the axis labels (tick text)
|
|
||||||
*/
|
|
||||||
showLabel?: boolean;
|
|
||||||
/**
|
|
||||||
* font size of the axis labels (tick text)
|
|
||||||
*/
|
|
||||||
labelFontSize?: number;
|
|
||||||
/**
|
|
||||||
* top and bottom space from axis label (tick text)
|
|
||||||
*/
|
|
||||||
labelPadding?: number;
|
|
||||||
/**
|
|
||||||
* Should show the axis title
|
|
||||||
*/
|
|
||||||
showTitle?: boolean;
|
|
||||||
/**
|
|
||||||
* font size of the axis title
|
|
||||||
*/
|
|
||||||
titleFontSize?: number;
|
|
||||||
/**
|
|
||||||
* top and bottom space from axis title
|
|
||||||
*/
|
|
||||||
titlePadding?: number;
|
|
||||||
/**
|
|
||||||
* Should show the axis tick lines
|
|
||||||
*/
|
|
||||||
showTick?: boolean;
|
|
||||||
/**
|
|
||||||
* length of the axis tick lines
|
|
||||||
*/
|
|
||||||
tickLength?: number;
|
|
||||||
/**
|
|
||||||
* width of the axis tick lines
|
|
||||||
*/
|
|
||||||
tickWidth?: number;
|
|
||||||
/**
|
|
||||||
* Show line across the axis
|
|
||||||
*/
|
|
||||||
showAxisLine?: boolean;
|
|
||||||
/**
|
|
||||||
* Width of the axis line
|
|
||||||
*/
|
|
||||||
axisLineWidth?: number;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* The object containing configurations specific for entity relationship diagrams
|
* The object containing configurations specific for entity relationship diagrams
|
||||||
*
|
*
|
||||||
@@ -936,7 +856,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* Directional bias for layout of entities
|
* Directional bias for layout of entities
|
||||||
*/
|
*/
|
||||||
layoutDirection?: string | 'TB' | 'BT' | 'LR' | 'RL';
|
layoutDirection?: 'TB' | 'BT' | 'LR' | 'RL';
|
||||||
/**
|
/**
|
||||||
* The minimum width of an entity box. Expressed in pixels.
|
* The minimum width of an entity box. Expressed in pixels.
|
||||||
*/
|
*/
|
||||||
@@ -1001,7 +921,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Decides which rendering engine that is to be used for the rendering.
|
* Decides which rendering engine that is to be used for the rendering.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
defaultRenderer?: 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
||||||
@@ -1025,7 +945,7 @@ export interface ClassDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Decides which rendering engine that is to be used for the rendering.
|
* Decides which rendering engine that is to be used for the rendering.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
defaultRenderer?: 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
||||||
nodeSpacing?: number;
|
nodeSpacing?: number;
|
||||||
rankSpacing?: number;
|
rankSpacing?: number;
|
||||||
/**
|
/**
|
||||||
@@ -1085,7 +1005,7 @@ export interface JourneyDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* Multiline message alignment
|
* Multiline message alignment
|
||||||
*/
|
*/
|
||||||
messageAlign?: string | 'left' | 'center' | 'right';
|
messageAlign?: 'left' | 'center' | 'right';
|
||||||
/**
|
/**
|
||||||
* Prolongs the edge of the diagram downwards.
|
* Prolongs the edge of the diagram downwards.
|
||||||
*
|
*
|
||||||
@@ -1164,7 +1084,7 @@ export interface TimelineDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* Multiline message alignment
|
* Multiline message alignment
|
||||||
*/
|
*/
|
||||||
messageAlign?: string | 'left' | 'center' | 'right';
|
messageAlign?: 'left' | 'center' | 'right';
|
||||||
/**
|
/**
|
||||||
* Prolongs the edge of the diagram downwards.
|
* Prolongs the edge of the diagram downwards.
|
||||||
*
|
*
|
||||||
@@ -1275,7 +1195,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Controls the display mode.
|
* Controls the display mode.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
displayMode?: string | 'compact';
|
displayMode?: '' | 'compact';
|
||||||
/**
|
/**
|
||||||
* On which day a week-based interval should start
|
* On which day a week-based interval should start
|
||||||
*
|
*
|
||||||
@@ -1334,7 +1254,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* Multiline message alignment
|
* Multiline message alignment
|
||||||
*/
|
*/
|
||||||
messageAlign?: string | 'left' | 'center' | 'right';
|
messageAlign?: 'left' | 'center' | 'right';
|
||||||
/**
|
/**
|
||||||
* Mirror actors under diagram
|
* Mirror actors under diagram
|
||||||
*
|
*
|
||||||
@@ -1391,7 +1311,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* This sets the text alignment of actor-attached notes
|
* This sets the text alignment of actor-attached notes
|
||||||
*/
|
*/
|
||||||
noteAlign?: string | 'left' | 'center' | 'right';
|
noteAlign?: 'left' | 'center' | 'right';
|
||||||
/**
|
/**
|
||||||
* This sets the font size of actor messages
|
* This sets the font size of actor messages
|
||||||
*/
|
*/
|
||||||
@@ -1475,7 +1395,7 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Defines how mermaid renders curves for flowcharts.
|
* Defines how mermaid renders curves for flowcharts.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
curve?: string | 'basis' | 'linear' | 'cardinal';
|
curve?: 'basis' | 'linear' | 'cardinal';
|
||||||
/**
|
/**
|
||||||
* Represents the padding between the labels and the shape
|
* Represents the padding between the labels and the shape
|
||||||
*
|
*
|
||||||
@@ -1487,7 +1407,7 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Decides which rendering engine that is to be used for the rendering.
|
* Decides which rendering engine that is to be used for the rendering.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
defaultRenderer?: 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
||||||
/**
|
/**
|
||||||
* Width of nodes where text is wrapped.
|
* Width of nodes where text is wrapped.
|
||||||
*
|
*
|
||||||
@@ -1511,13 +1431,7 @@ export interface SankeyDiagramConfig extends BaseDiagramConfig {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
linkColor?: SankeyLinkColor | string;
|
linkColor?: SankeyLinkColor | string;
|
||||||
/**
|
nodeAlignment?: SankeyNodeAlignment;
|
||||||
* Controls the alignment of the Sankey diagrams.
|
|
||||||
*
|
|
||||||
* See <https://github.com/d3/d3-sankey#alignments>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
nodeAlignment?: 'left' | 'right' | 'center' | 'justify';
|
|
||||||
useMaxWidth?: boolean;
|
useMaxWidth?: boolean;
|
||||||
/**
|
/**
|
||||||
* Toggle to display or hide values along with title.
|
* Toggle to display or hide values along with title.
|
||||||
|
@@ -257,6 +257,9 @@ const config: RequiredDeep<MermaidConfig> = {
|
|||||||
// TODO: can we make this default to `true` instead?
|
// TODO: can we make this default to `true` instead?
|
||||||
useMaxWidth: false,
|
useMaxWidth: false,
|
||||||
},
|
},
|
||||||
|
packet: {
|
||||||
|
...defaultConfigJson.packet,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const keyify = (obj: any, prefix = ''): string[] =>
|
const keyify = (obj: any, prefix = ''): string[] =>
|
||||||
|
@@ -71,10 +71,9 @@ export const registerLazyLoadedDiagrams = (...diagrams: ExternalDiagramDefinitio
|
|||||||
|
|
||||||
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
|
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
|
||||||
if (detectors[key]) {
|
if (detectors[key]) {
|
||||||
log.error(`Detector with key ${key} already exists`);
|
log.warn(`Detector with key ${key} already exists. Overwriting.`);
|
||||||
} else {
|
|
||||||
detectors[key] = { detector, loader };
|
|
||||||
}
|
}
|
||||||
|
detectors[key] = { detector, loader };
|
||||||
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
|
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ import flowchartElk from '../diagrams/flowchart/elk/detector.js';
|
|||||||
import timeline from '../diagrams/timeline/detector.js';
|
import timeline from '../diagrams/timeline/detector.js';
|
||||||
import mindmap from '../diagrams/mindmap/detector.js';
|
import mindmap from '../diagrams/mindmap/detector.js';
|
||||||
import sankey from '../diagrams/sankey/sankeyDetector.js';
|
import sankey from '../diagrams/sankey/sankeyDetector.js';
|
||||||
|
import { packet } from '../diagrams/packet/detector.js';
|
||||||
import block from '../diagrams/block/blockDetector.js';
|
import block from '../diagrams/block/blockDetector.js';
|
||||||
import { registerLazyLoadedDiagrams } from './detectType.js';
|
import { registerLazyLoadedDiagrams } from './detectType.js';
|
||||||
import { registerDiagram } from './diagramAPI.js';
|
import { registerDiagram } from './diagramAPI.js';
|
||||||
@@ -51,7 +52,6 @@ export const addDiagrams = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parser: {
|
parser: {
|
||||||
parser: { yy: {} },
|
|
||||||
parse: () => {
|
parse: () => {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Diagrams beginning with --- are not valid. ' +
|
'Diagrams beginning with --- are not valid. ' +
|
||||||
@@ -88,6 +88,7 @@ export const addDiagrams = () => {
|
|||||||
journey,
|
journey,
|
||||||
quadrantChart,
|
quadrantChart,
|
||||||
sankey,
|
sankey,
|
||||||
|
packet,
|
||||||
xychart,
|
xychart,
|
||||||
block
|
block
|
||||||
);
|
);
|
||||||
|
@@ -2,12 +2,12 @@ import { detectType } from './detectType.js';
|
|||||||
import { getDiagram, registerDiagram } from './diagramAPI.js';
|
import { getDiagram, registerDiagram } from './diagramAPI.js';
|
||||||
import { addDiagrams } from './diagram-orchestration.js';
|
import { addDiagrams } from './diagram-orchestration.js';
|
||||||
import type { DiagramDetector } from './types.js';
|
import type { DiagramDetector } from './types.js';
|
||||||
import { getDiagramFromText } from '../Diagram.js';
|
import { Diagram } from '../Diagram.js';
|
||||||
import { it, describe, expect, beforeAll } from 'vitest';
|
import { it, describe, expect, beforeAll } from 'vitest';
|
||||||
|
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await getDiagramFromText('sequenceDiagram');
|
await Diagram.fromText('sequenceDiagram');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DiagramAPI', () => {
|
describe('DiagramAPI', () => {
|
||||||
@@ -39,7 +39,6 @@ describe('DiagramAPI', () => {
|
|||||||
parse: (_text) => {
|
parse: (_text) => {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
parser: { yy: {} },
|
|
||||||
},
|
},
|
||||||
renderer: {
|
renderer: {
|
||||||
draw: () => {
|
draw: () => {
|
||||||
|
@@ -49,7 +49,7 @@ export const registerDiagram = (
|
|||||||
detector?: DiagramDetector
|
detector?: DiagramDetector
|
||||||
) => {
|
) => {
|
||||||
if (diagrams[id]) {
|
if (diagrams[id]) {
|
||||||
throw new Error(`Diagram ${id} already registered.`);
|
log.warn(`Diagram with id ${id} already registered. Overwriting.`);
|
||||||
}
|
}
|
||||||
diagrams[id] = diagram;
|
diagrams[id] = diagram;
|
||||||
if (detector) {
|
if (detector) {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import type { MermaidConfig } from '../config.type.js';
|
import type { GanttDiagramConfig, MermaidConfig } from '../config.type.js';
|
||||||
import { frontMatterRegex } from './regexes.js';
|
import { frontMatterRegex } from './regexes.js';
|
||||||
// The "* as yaml" part is necessary for tree-shaking
|
// The "* as yaml" part is necessary for tree-shaking
|
||||||
import * as yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
@@ -6,7 +6,7 @@ import * as yaml from 'js-yaml';
|
|||||||
interface FrontMatterMetadata {
|
interface FrontMatterMetadata {
|
||||||
title?: string;
|
title?: string;
|
||||||
// Allows custom display modes. Currently used for compact mode in gantt charts.
|
// Allows custom display modes. Currently used for compact mode in gantt charts.
|
||||||
displayMode?: string;
|
displayMode?: GanttDiagramConfig['displayMode'];
|
||||||
config?: MermaidConfig;
|
config?: MermaidConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ export function extractFrontMatter(text: string): FrontMatterResult {
|
|||||||
|
|
||||||
// Only add properties that are explicitly supported, if they exist
|
// Only add properties that are explicitly supported, if they exist
|
||||||
if (parsed.displayMode) {
|
if (parsed.displayMode) {
|
||||||
metadata.displayMode = parsed.displayMode.toString();
|
metadata.displayMode = parsed.displayMode.toString() as GanttDiagramConfig['displayMode'];
|
||||||
}
|
}
|
||||||
if (parsed.title) {
|
if (parsed.title) {
|
||||||
metadata.title = parsed.title.toString();
|
metadata.title = parsed.title.toString();
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type * as d3 from 'd3';
|
||||||
|
import type { SetRequired } from 'type-fest';
|
||||||
import type { Diagram } from '../Diagram.js';
|
import type { Diagram } from '../Diagram.js';
|
||||||
import type { BaseDiagramConfig, MermaidConfig } from '../config.type.js';
|
import type { BaseDiagramConfig, MermaidConfig } from '../config.type.js';
|
||||||
import type * as d3 from 'd3';
|
|
||||||
|
|
||||||
export interface DiagramMetadata {
|
export interface DiagramMetadata {
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -39,6 +40,22 @@ export interface DiagramDB {
|
|||||||
bindFunctions?: (element: Element) => void;
|
bindFunctions?: (element: Element) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DiagramDB with fields that is required for all new diagrams.
|
||||||
|
*/
|
||||||
|
export type DiagramDBBase<T extends BaseDiagramConfig> = {
|
||||||
|
getConfig: () => Required<T>;
|
||||||
|
} & SetRequired<
|
||||||
|
DiagramDB,
|
||||||
|
| 'clear'
|
||||||
|
| 'getAccTitle'
|
||||||
|
| 'getDiagramTitle'
|
||||||
|
| 'getAccDescription'
|
||||||
|
| 'setAccDescription'
|
||||||
|
| 'setAccTitle'
|
||||||
|
| 'setDiagramTitle'
|
||||||
|
>;
|
||||||
|
|
||||||
// This is what is returned from getClasses(...) methods.
|
// This is what is returned from getClasses(...) methods.
|
||||||
// It is slightly renamed to ..StyleClassDef instead of just ClassDef because "class" is a greatly ambiguous and overloaded word.
|
// It is slightly renamed to ..StyleClassDef instead of just ClassDef because "class" is a greatly ambiguous and overloaded word.
|
||||||
// It makes it clear we're working with a style class definition, even though defining the type is currently difficult.
|
// It makes it clear we're working with a style class definition, even though defining the type is currently difficult.
|
||||||
@@ -104,8 +121,8 @@ export type DrawDefinition = (
|
|||||||
) => void | Promise<void>;
|
) => void | Promise<void>;
|
||||||
|
|
||||||
export interface ParserDefinition {
|
export interface ParserDefinition {
|
||||||
parse: (text: string) => void;
|
parse: (text: string) => void | Promise<void>;
|
||||||
parser: { yy: DiagramDB };
|
parser?: { yy: DiagramDB };
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HTML = d3.Selection<HTMLIFrameElement, unknown, Element | null, unknown>;
|
export type HTML = d3.Selection<HTMLIFrameElement, unknown, Element | null, unknown>;
|
||||||
|
@@ -1,16 +1,39 @@
|
|||||||
import { describe, test, expect } from 'vitest';
|
import { describe, test, expect } from 'vitest';
|
||||||
import { Diagram, getDiagramFromText } from './Diagram.js';
|
import { Diagram } from './Diagram.js';
|
||||||
import { addDetector } from './diagram-api/detectType.js';
|
import { addDetector } from './diagram-api/detectType.js';
|
||||||
import { addDiagrams } from './diagram-api/diagram-orchestration.js';
|
import { addDiagrams } from './diagram-api/diagram-orchestration.js';
|
||||||
|
import type { DiagramLoader } from './diagram-api/types.js';
|
||||||
|
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
|
|
||||||
|
const getDummyDiagram = (id: string, title?: string): Awaited<ReturnType<DiagramLoader>> => {
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
diagram: {
|
||||||
|
db: {
|
||||||
|
getDiagramTitle: () => title ?? id,
|
||||||
|
},
|
||||||
|
parser: {
|
||||||
|
parse: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
|
},
|
||||||
|
renderer: {
|
||||||
|
draw: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
|
},
|
||||||
|
styles: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
describe('diagram detection', () => {
|
describe('diagram detection', () => {
|
||||||
test('should detect inbuilt diagrams', async () => {
|
test('should detect inbuilt diagrams', async () => {
|
||||||
const graph = (await getDiagramFromText('graph TD; A-->B')) as Diagram;
|
const graph = (await Diagram.fromText('graph TD; A-->B')) as Diagram;
|
||||||
expect(graph).toBeInstanceOf(Diagram);
|
expect(graph).toBeInstanceOf(Diagram);
|
||||||
expect(graph.type).toBe('flowchart-v2');
|
expect(graph.type).toBe('flowchart-v2');
|
||||||
const sequence = (await getDiagramFromText(
|
const sequence = (await Diagram.fromText(
|
||||||
'sequenceDiagram; Alice->>+John: Hello John, how are you?'
|
'sequenceDiagram; Alice->>+John: Hello John, how are you?'
|
||||||
)) as Diagram;
|
)) as Diagram;
|
||||||
expect(sequence).toBeInstanceOf(Diagram);
|
expect(sequence).toBeInstanceOf(Diagram);
|
||||||
@@ -21,41 +44,33 @@ describe('diagram detection', () => {
|
|||||||
addDetector(
|
addDetector(
|
||||||
'loki',
|
'loki',
|
||||||
(str) => str.startsWith('loki'),
|
(str) => str.startsWith('loki'),
|
||||||
() =>
|
() => Promise.resolve(getDummyDiagram('loki'))
|
||||||
Promise.resolve({
|
|
||||||
id: 'loki',
|
|
||||||
diagram: {
|
|
||||||
db: {},
|
|
||||||
parser: {
|
|
||||||
parse: () => {
|
|
||||||
// no-op
|
|
||||||
},
|
|
||||||
parser: {
|
|
||||||
yy: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
renderer: {
|
|
||||||
draw: () => {
|
|
||||||
// no-op
|
|
||||||
},
|
|
||||||
},
|
|
||||||
styles: {},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
const diagram = (await getDiagramFromText('loki TD; A-->B')) as Diagram;
|
const diagram = await Diagram.fromText('loki TD; A-->B');
|
||||||
expect(diagram).toBeInstanceOf(Diagram);
|
expect(diagram).toBeInstanceOf(Diagram);
|
||||||
expect(diagram.type).toBe('loki');
|
expect(diagram.type).toBe('loki');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should allow external diagrams to override internal ones with same ID', async () => {
|
||||||
|
const title = 'overridden';
|
||||||
|
addDetector(
|
||||||
|
'flowchart-elk',
|
||||||
|
(str) => str.startsWith('flowchart-elk'),
|
||||||
|
() => Promise.resolve(getDummyDiagram('flowchart-elk', title))
|
||||||
|
);
|
||||||
|
const diagram = await Diagram.fromText('flowchart-elk TD; A-->B');
|
||||||
|
expect(diagram).toBeInstanceOf(Diagram);
|
||||||
|
expect(diagram.db.getDiagramTitle?.()).toBe(title);
|
||||||
|
});
|
||||||
|
|
||||||
test('should throw the right error for incorrect diagram', async () => {
|
test('should throw the right error for incorrect diagram', async () => {
|
||||||
await expect(getDiagramFromText('graph TD; A-->')).rejects.toThrowErrorMatchingInlineSnapshot(`
|
await expect(Diagram.fromText('graph TD; A-->')).rejects.toThrowErrorMatchingInlineSnapshot(`
|
||||||
"Parse error on line 2:
|
"Parse error on line 2:
|
||||||
graph TD; A-->
|
graph TD; A-->
|
||||||
--------------^
|
--------------^
|
||||||
Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF'"
|
Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF'"
|
||||||
`);
|
`);
|
||||||
await expect(getDiagramFromText('sequenceDiagram; A-->B')).rejects
|
await expect(Diagram.fromText('sequenceDiagram; A-->B')).rejects
|
||||||
.toThrowErrorMatchingInlineSnapshot(`
|
.toThrowErrorMatchingInlineSnapshot(`
|
||||||
"Parse error on line 1:
|
"Parse error on line 1:
|
||||||
...quenceDiagram; A-->B
|
...quenceDiagram; A-->B
|
||||||
@@ -65,13 +80,13 @@ Expecting 'TXT', got 'NEWLINE'"
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should throw the right error for unregistered diagrams', async () => {
|
test('should throw the right error for unregistered diagrams', async () => {
|
||||||
await expect(getDiagramFromText('thor TD; A-->B')).rejects.toThrowErrorMatchingInlineSnapshot(
|
await expect(Diagram.fromText('thor TD; A-->B')).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||||
'"No diagram type detected matching given configuration for text: thor TD; A-->B"'
|
'"No diagram type detected matching given configuration for text: thor TD; A-->B"'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should consider entity codes when present in diagram defination', async () => {
|
test('should consider entity codes when present in diagram defination', async () => {
|
||||||
const diagram = await getDiagramFromText(`sequenceDiagram
|
const diagram = await Diagram.fromText(`sequenceDiagram
|
||||||
A->>B: I #9829; you!
|
A->>B: I #9829; you!
|
||||||
B->>A: I #9829; you #infin; times more!`);
|
B->>A: I #9829; you #infin; times more!`);
|
||||||
// @ts-ignore: we need to add types for sequenceDb which will be done in separate PR
|
// @ts-ignore: we need to add types for sequenceDb which will be done in separate PR
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import type { DiagramDB } from '../../diagram-api/types.js';
|
|
||||||
import type { BlockConfig, BlockType, Block, ClassDef } from './blockTypes.js';
|
|
||||||
import * as configApi from '../../config.js';
|
|
||||||
import { clear as commonClear } from '../common/commonDb.js';
|
|
||||||
import { log } from '../../logger.js';
|
|
||||||
import clone from 'lodash-es/clone.js';
|
import clone from 'lodash-es/clone.js';
|
||||||
|
import * as configApi from '../../config.js';
|
||||||
|
import type { DiagramDB } from '../../diagram-api/types.js';
|
||||||
|
import { log } from '../../logger.js';
|
||||||
|
import { clear as commonClear } from '../common/commonDb.js';
|
||||||
|
import type { Block, ClassDef } from './blockTypes.js';
|
||||||
|
|
||||||
// Initialize the node database for simple lookups
|
// Initialize the node database for simple lookups
|
||||||
let blockDatabase: Record<string, Block> = {};
|
let blockDatabase: Record<string, Block> = {};
|
||||||
|
@@ -1,19 +1,17 @@
|
|||||||
import type { Diagram } from '../../Diagram.js';
|
|
||||||
import * as configApi from '../../config.js';
|
|
||||||
import { calculateBlockSizes, insertBlocks, insertEdges } from './renderHelpers.js';
|
|
||||||
import { layout } from './layout.js';
|
|
||||||
import type { MermaidConfig, BaseDiagramConfig } from '../../config.type.js';
|
|
||||||
import insertMarkers from '../../dagre-wrapper/markers.js';
|
|
||||||
import {
|
import {
|
||||||
select as d3select,
|
|
||||||
scaleOrdinal as d3scaleOrdinal,
|
scaleOrdinal as d3scaleOrdinal,
|
||||||
schemeTableau10 as d3schemeTableau10,
|
schemeTableau10 as d3schemeTableau10,
|
||||||
|
select as d3select,
|
||||||
} from 'd3';
|
} from 'd3';
|
||||||
import type { ContainerElement } from 'd3';
|
import type { Diagram } from '../../Diagram.js';
|
||||||
|
import * as configApi from '../../config.js';
|
||||||
|
import type { MermaidConfig } from '../../config.type.js';
|
||||||
|
import insertMarkers from '../../dagre-wrapper/markers.js';
|
||||||
import { log } from '../../logger.js';
|
import { log } from '../../logger.js';
|
||||||
import type { BlockDB } from './blockDB.js';
|
|
||||||
import type { Block } from './blockTypes.js';
|
|
||||||
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||||
|
import type { BlockDB } from './blockDB.js';
|
||||||
|
import { layout } from './layout.js';
|
||||||
|
import { calculateBlockSizes, insertBlocks, insertEdges } from './renderHelpers.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the all the styles from classDef statements in the graph definition.
|
* Returns the all the styles from classDef statements in the graph definition.
|
||||||
|
@@ -1,15 +1,10 @@
|
|||||||
import { getStylesFromArray } from '../../utils.js';
|
|
||||||
import { insertNode, positionNode } from '../../dagre-wrapper/nodes.js';
|
|
||||||
import { insertEdge, insertEdgeLabel, positionEdgeLabel } from '../../dagre-wrapper/edges.js';
|
|
||||||
import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
|
import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
|
||||||
import { getConfig } from '../../config.js';
|
import { getConfig } from '../../config.js';
|
||||||
import type { ContainerElement } from 'd3';
|
import { insertEdge, insertEdgeLabel, positionEdgeLabel } from '../../dagre-wrapper/edges.js';
|
||||||
import type { Block } from './blockTypes.js';
|
import { insertNode, positionNode } from '../../dagre-wrapper/nodes.js';
|
||||||
|
import { getStylesFromArray } from '../../utils.js';
|
||||||
import type { BlockDB } from './blockDB.js';
|
import type { BlockDB } from './blockDB.js';
|
||||||
|
import type { Block } from './blockTypes.js';
|
||||||
interface Node {
|
|
||||||
classes: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
|
function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
|
||||||
const vertex = block;
|
const vertex = block;
|
||||||
|
14
packages/mermaid/src/diagrams/common/populateCommonDb.ts
Normal file
14
packages/mermaid/src/diagrams/common/populateCommonDb.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import type { DiagramAST } from '@mermaid-js/parser';
|
||||||
|
import type { DiagramDB } from '../../diagram-api/types.js';
|
||||||
|
|
||||||
|
export function populateCommonDb(ast: DiagramAST, db: DiagramDB) {
|
||||||
|
if (ast.accDescr) {
|
||||||
|
db.setAccDescription?.(ast.accDescr);
|
||||||
|
}
|
||||||
|
if (ast.accTitle) {
|
||||||
|
db.setAccTitle?.(ast.accTitle);
|
||||||
|
}
|
||||||
|
if (ast.title) {
|
||||||
|
db.setDiagramTitle?.(ast.title);
|
||||||
|
}
|
||||||
|
}
|
@@ -5,7 +5,6 @@ const diagram: DiagramDefinition = {
|
|||||||
db: {},
|
db: {},
|
||||||
renderer,
|
renderer,
|
||||||
parser: {
|
parser: {
|
||||||
parser: { yy: {} },
|
|
||||||
parse: (): void => {
|
parse: (): void => {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
@@ -3,6 +3,7 @@ import type {
|
|||||||
DiagramDetector,
|
DiagramDetector,
|
||||||
DiagramLoader,
|
DiagramLoader,
|
||||||
} from '../../../diagram-api/types.js';
|
} from '../../../diagram-api/types.js';
|
||||||
|
import { log } from '../../../logger.js';
|
||||||
|
|
||||||
const id = 'flowchart-elk';
|
const id = 'flowchart-elk';
|
||||||
|
|
||||||
@@ -13,13 +14,21 @@ const detector: DiagramDetector = (txt, config): boolean => {
|
|||||||
// If a flowchart/graph diagram has their default renderer set to elk
|
// If a flowchart/graph diagram has their default renderer set to elk
|
||||||
(/^\s*flowchart|graph/.test(txt) && config?.flowchart?.defaultRenderer === 'elk')
|
(/^\s*flowchart|graph/.test(txt) && config?.flowchart?.defaultRenderer === 'elk')
|
||||||
) {
|
) {
|
||||||
|
// This will log at the end, hopefully.
|
||||||
|
setTimeout(
|
||||||
|
() =>
|
||||||
|
log.warn(
|
||||||
|
'flowchart-elk was moved to an external package in Mermaid v11. Please refer [release notes](link) for more details. This diagram will be rendered using `dagre` layout as a fallback.'
|
||||||
|
),
|
||||||
|
500
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const loader: DiagramLoader = async () => {
|
const loader: DiagramLoader = async () => {
|
||||||
const { diagram } = await import('./flowchart-elk-definition.js');
|
const { diagram } = await import('../flowDiagram-v2.js');
|
||||||
return { id, diagram };
|
return { id, diagram };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
// @ts-ignore: JISON typing missing
|
|
||||||
import parser from '../parser/flow.jison';
|
|
||||||
|
|
||||||
import * as db from '../flowDb.js';
|
|
||||||
import renderer from './flowRenderer-elk.js';
|
|
||||||
import styles from './styles.js';
|
|
||||||
|
|
||||||
export const diagram = {
|
|
||||||
db,
|
|
||||||
renderer,
|
|
||||||
parser,
|
|
||||||
styles,
|
|
||||||
};
|
|
@@ -1,14 +1,15 @@
|
|||||||
import flowDb from './flowDb.js';
|
import flowDb from './flowDb.js';
|
||||||
|
import type { FlowSubGraph } from './types.js';
|
||||||
|
|
||||||
describe('flow db subgraphs', () => {
|
describe('flow db subgraphs', () => {
|
||||||
let subgraphs;
|
let subgraphs: FlowSubGraph[];
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
subgraphs = [
|
subgraphs = [
|
||||||
{ nodes: ['a', 'b', 'c', 'e'] },
|
{ nodes: ['a', 'b', 'c', 'e'] },
|
||||||
{ nodes: ['f', 'g', 'h'] },
|
{ nodes: ['f', 'g', 'h'] },
|
||||||
{ nodes: ['i', 'j'] },
|
{ nodes: ['i', 'j'] },
|
||||||
{ nodes: ['k'] },
|
{ nodes: ['k'] },
|
||||||
];
|
] as FlowSubGraph[];
|
||||||
});
|
});
|
||||||
describe('exist', () => {
|
describe('exist', () => {
|
||||||
it('should return true when the is exists in a subgraph', () => {
|
it('should return true when the is exists in a subgraph', () => {
|
||||||
@@ -25,17 +26,17 @@ describe('flow db subgraphs', () => {
|
|||||||
|
|
||||||
describe('makeUniq', () => {
|
describe('makeUniq', () => {
|
||||||
it('should remove ids from sungraph that already exists in another subgraph even if it gets empty', () => {
|
it('should remove ids from sungraph that already exists in another subgraph even if it gets empty', () => {
|
||||||
const subgraph = flowDb.makeUniq({ nodes: ['i', 'j'] }, subgraphs);
|
const subgraph = flowDb.makeUniq({ nodes: ['i', 'j'] } as FlowSubGraph, subgraphs);
|
||||||
|
|
||||||
expect(subgraph.nodes).toEqual([]);
|
expect(subgraph.nodes).toEqual([]);
|
||||||
});
|
});
|
||||||
it('should remove ids from sungraph that already exists in another subgraph', () => {
|
it('should remove ids from sungraph that already exists in another subgraph', () => {
|
||||||
const subgraph = flowDb.makeUniq({ nodes: ['i', 'j', 'o'] }, subgraphs);
|
const subgraph = flowDb.makeUniq({ nodes: ['i', 'j', 'o'] } as FlowSubGraph, subgraphs);
|
||||||
|
|
||||||
expect(subgraph.nodes).toEqual(['o']);
|
expect(subgraph.nodes).toEqual(['o']);
|
||||||
});
|
});
|
||||||
it('should not remove ids from subgraph if they are unique', () => {
|
it('should not remove ids from subgraph if they are unique', () => {
|
||||||
const subgraph = flowDb.makeUniq({ nodes: ['q', 'r', 's'] }, subgraphs);
|
const subgraph = flowDb.makeUniq({ nodes: ['q', 'r', 's'] } as FlowSubGraph, subgraphs);
|
||||||
|
|
||||||
expect(subgraph.nodes).toEqual(['q', 'r', 's']);
|
expect(subgraph.nodes).toEqual(['q', 'r', 's']);
|
||||||
});
|
});
|
@@ -12,34 +12,34 @@ import {
|
|||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
} from '../common/commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
import type { FlowVertex, FlowClass, FlowSubGraph, FlowText, FlowEdge, FlowLink } from './types.js';
|
||||||
|
|
||||||
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
||||||
let vertexCounter = 0;
|
let vertexCounter = 0;
|
||||||
let config = getConfig();
|
let config = getConfig();
|
||||||
let vertices = {};
|
let vertices: Record<string, FlowVertex> = {};
|
||||||
let edges = [];
|
let edges: FlowEdge[] & { defaultInterpolate?: string; defaultStyle?: string[] } = [];
|
||||||
let classes = {};
|
let classes: Record<string, FlowClass> = {};
|
||||||
let subGraphs = [];
|
let subGraphs: FlowSubGraph[] = [];
|
||||||
let subGraphLookup = {};
|
let subGraphLookup: Record<string, FlowSubGraph> = {};
|
||||||
let tooltips = {};
|
let tooltips: Record<string, string> = {};
|
||||||
let subCount = 0;
|
let subCount = 0;
|
||||||
let firstGraphFlag = true;
|
let firstGraphFlag = true;
|
||||||
let direction;
|
let direction: string;
|
||||||
|
|
||||||
let version; // As in graph
|
let version: string; // As in graph
|
||||||
|
|
||||||
// Functions to be run after graph rendering
|
// Functions to be run after graph rendering
|
||||||
let funs = []; // cspell:ignore funs
|
let funs: ((element: Element) => void)[] = []; // cspell:ignore funs
|
||||||
|
|
||||||
const sanitizeText = (txt) => common.sanitizeText(txt, config);
|
const sanitizeText = (txt: string) => common.sanitizeText(txt, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to lookup domId from id in the graph definition.
|
* Function to lookup domId from id in the graph definition.
|
||||||
*
|
*
|
||||||
* @param id
|
* @param id - id of the node
|
||||||
* @public
|
|
||||||
*/
|
*/
|
||||||
export const lookUpDomId = function (id) {
|
export const lookUpDomId = function (id: string) {
|
||||||
const vertexKeys = Object.keys(vertices);
|
const vertexKeys = Object.keys(vertices);
|
||||||
for (const vertexKey of vertexKeys) {
|
for (const vertexKey of vertexKeys) {
|
||||||
if (vertices[vertexKey].id === id) {
|
if (vertices[vertexKey].id === id) {
|
||||||
@@ -52,30 +52,24 @@ export const lookUpDomId = function (id) {
|
|||||||
/**
|
/**
|
||||||
* Function called by parser when a node definition has been found
|
* Function called by parser when a node definition has been found
|
||||||
*
|
*
|
||||||
* @param _id
|
|
||||||
* @param text
|
|
||||||
* @param textObj
|
|
||||||
* @param type
|
|
||||||
* @param style
|
|
||||||
* @param classes
|
|
||||||
* @param dir
|
|
||||||
* @param props
|
|
||||||
*/
|
*/
|
||||||
export const addVertex = function (_id, textObj, type, style, classes, dir, props = {}) {
|
export const addVertex = function (
|
||||||
|
id: string,
|
||||||
|
textObj: FlowText,
|
||||||
|
type: 'group',
|
||||||
|
style: string[],
|
||||||
|
classes: string[],
|
||||||
|
dir: string,
|
||||||
|
props = {}
|
||||||
|
) {
|
||||||
|
if (!id || id.trim().length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let txt;
|
let txt;
|
||||||
let id = _id;
|
|
||||||
if (id === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (id.trim().length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
|
||||||
|
|
||||||
if (vertices[id] === undefined) {
|
if (vertices[id] === undefined) {
|
||||||
vertices[id] = {
|
vertices[id] = {
|
||||||
id: id,
|
id,
|
||||||
labelType: 'text',
|
labelType: 'text',
|
||||||
domId: MERMAID_DOM_ID_PREFIX + id + '-' + vertexCounter,
|
domId: MERMAID_DOM_ID_PREFIX + id + '-' + vertexCounter,
|
||||||
styles: [],
|
styles: [],
|
||||||
@@ -94,7 +88,7 @@ export const addVertex = function (_id, textObj, type, style, classes, dir, prop
|
|||||||
vertices[id].text = txt;
|
vertices[id].text = txt;
|
||||||
} else {
|
} else {
|
||||||
if (vertices[id].text === undefined) {
|
if (vertices[id].text === undefined) {
|
||||||
vertices[id].text = _id;
|
vertices[id].text = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type !== undefined) {
|
if (type !== undefined) {
|
||||||
@@ -123,20 +117,12 @@ export const addVertex = function (_id, textObj, type, style, classes, dir, prop
|
|||||||
/**
|
/**
|
||||||
* Function called by parser when a link/edge definition has been found
|
* Function called by parser when a link/edge definition has been found
|
||||||
*
|
*
|
||||||
* @param _start
|
|
||||||
* @param _end
|
|
||||||
* @param type
|
|
||||||
* @param linkText
|
|
||||||
* @param linkTextObj
|
|
||||||
*/
|
*/
|
||||||
export const addSingleLink = function (_start, _end, type) {
|
export const addSingleLink = function (_start: string, _end: string, type: any) {
|
||||||
let start = _start;
|
const start = _start;
|
||||||
let end = _end;
|
const end = _end;
|
||||||
// if (start[0].match(/\d/)) start = MERMAID_DOM_ID_PREFIX + start;
|
|
||||||
// if (end[0].match(/\d/)) end = MERMAID_DOM_ID_PREFIX + end;
|
|
||||||
// log.info('Got edge...', start, end);
|
|
||||||
|
|
||||||
const edge = { start: start, end: end, type: undefined, text: '', labelType: 'text' };
|
const edge: FlowEdge = { start: start, end: end, type: undefined, text: '', labelType: 'text' };
|
||||||
log.info('abc78 Got edge...', edge);
|
log.info('abc78 Got edge...', edge);
|
||||||
const linkTextObj = type.text;
|
const linkTextObj = type.text;
|
||||||
|
|
||||||
@@ -153,13 +139,11 @@ export const addSingleLink = function (_start, _end, type) {
|
|||||||
if (type !== undefined) {
|
if (type !== undefined) {
|
||||||
edge.type = type.type;
|
edge.type = type.type;
|
||||||
edge.stroke = type.stroke;
|
edge.stroke = type.stroke;
|
||||||
edge.length = type.length;
|
edge.length = type.length > 10 ? 10 : type.length;
|
||||||
}
|
|
||||||
if (edge?.length > 10) {
|
|
||||||
edge.length = 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (edges.length < (config.maxEdges ?? 500)) {
|
if (edges.length < (config.maxEdges ?? 500)) {
|
||||||
log.info('abc78 pushing edge...');
|
log.info('Pushing edge...');
|
||||||
edges.push(edge);
|
edges.push(edge);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -171,12 +155,12 @@ You have to call mermaid.initialize.`
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const addLink = function (_start, _end, type) {
|
|
||||||
log.info('addLink (abc78)', _start, _end, type);
|
export const addLink = function (_start: string[], _end: string[], type: unknown) {
|
||||||
let i, j;
|
log.info('addLink', _start, _end, type);
|
||||||
for (i = 0; i < _start.length; i++) {
|
for (const start of _start) {
|
||||||
for (j = 0; j < _end.length; j++) {
|
for (const end of _end) {
|
||||||
addSingleLink(_start[i], _end[j], type);
|
addSingleLink(start, end, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -184,15 +168,16 @@ export const addLink = function (_start, _end, type) {
|
|||||||
/**
|
/**
|
||||||
* Updates a link's line interpolation algorithm
|
* Updates a link's line interpolation algorithm
|
||||||
*
|
*
|
||||||
* @param positions
|
|
||||||
* @param interp
|
|
||||||
*/
|
*/
|
||||||
export const updateLinkInterpolate = function (positions, interp) {
|
export const updateLinkInterpolate = function (
|
||||||
|
positions: ('default' | number)[],
|
||||||
|
interpolate: string
|
||||||
|
) {
|
||||||
positions.forEach(function (pos) {
|
positions.forEach(function (pos) {
|
||||||
if (pos === 'default') {
|
if (pos === 'default') {
|
||||||
edges.defaultInterpolate = interp;
|
edges.defaultInterpolate = interpolate;
|
||||||
} else {
|
} else {
|
||||||
edges[pos].interpolate = interp;
|
edges[pos].interpolate = interpolate;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -200,12 +185,10 @@ export const updateLinkInterpolate = function (positions, interp) {
|
|||||||
/**
|
/**
|
||||||
* Updates a link with a style
|
* Updates a link with a style
|
||||||
*
|
*
|
||||||
* @param positions
|
|
||||||
* @param style
|
|
||||||
*/
|
*/
|
||||||
export const updateLink = function (positions, style) {
|
export const updateLink = function (positions: ('default' | number)[], style: string[]) {
|
||||||
positions.forEach(function (pos) {
|
positions.forEach(function (pos) {
|
||||||
if (pos >= edges.length) {
|
if (typeof pos === 'number' && pos >= edges.length) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The index ${pos} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${
|
`The index ${pos} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${
|
||||||
edges.length - 1
|
edges.length - 1
|
||||||
@@ -223,7 +206,7 @@ export const updateLink = function (positions, style) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addClass = function (ids, style) {
|
export const addClass = function (ids: string, style: string[]) {
|
||||||
ids.split(',').forEach(function (id) {
|
ids.split(',').forEach(function (id) {
|
||||||
if (classes[id] === undefined) {
|
if (classes[id] === undefined) {
|
||||||
classes[id] = { id, styles: [], textStyles: [] };
|
classes[id] = { id, styles: [], textStyles: [] };
|
||||||
@@ -244,9 +227,8 @@ export const addClass = function (ids, style) {
|
|||||||
/**
|
/**
|
||||||
* Called by parser when a graph definition is found, stores the direction of the chart.
|
* Called by parser when a graph definition is found, stores the direction of the chart.
|
||||||
*
|
*
|
||||||
* @param dir
|
|
||||||
*/
|
*/
|
||||||
export const setDirection = function (dir) {
|
export const setDirection = function (dir: string) {
|
||||||
direction = dir;
|
direction = dir;
|
||||||
if (direction.match(/.*</)) {
|
if (direction.match(/.*</)) {
|
||||||
direction = 'RL';
|
direction = 'RL';
|
||||||
@@ -268,34 +250,32 @@ export const setDirection = function (dir) {
|
|||||||
/**
|
/**
|
||||||
* Called by parser when a special node is found, e.g. a clickable element.
|
* Called by parser when a special node is found, e.g. a clickable element.
|
||||||
*
|
*
|
||||||
* @param ids Comma separated list of ids
|
* @param ids - Comma separated list of ids
|
||||||
* @param className Class to add
|
* @param className - Class to add
|
||||||
*/
|
*/
|
||||||
export const setClass = function (ids, className) {
|
export const setClass = function (ids: string, className: string) {
|
||||||
ids.split(',').forEach(function (_id) {
|
for (const id of ids.split(',')) {
|
||||||
// let id = version === 'gen-2' ? lookUpDomId(_id) : _id;
|
if (vertices[id]) {
|
||||||
let id = _id;
|
|
||||||
// if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
|
||||||
if (vertices[id] !== undefined) {
|
|
||||||
vertices[id].classes.push(className);
|
vertices[id].classes.push(className);
|
||||||
}
|
}
|
||||||
|
if (subGraphLookup[id]) {
|
||||||
if (subGraphLookup[id] !== undefined) {
|
|
||||||
subGraphLookup[id].classes.push(className);
|
subGraphLookup[id].classes.push(className);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setTooltip = function (ids, tooltip) {
|
const setTooltip = function (ids: string, tooltip: string) {
|
||||||
ids.split(',').forEach(function (id) {
|
if (tooltip === undefined) {
|
||||||
if (tooltip !== undefined) {
|
return;
|
||||||
tooltips[version === 'gen-1' ? lookUpDomId(id) : id] = sanitizeText(tooltip);
|
}
|
||||||
}
|
tooltip = sanitizeText(tooltip);
|
||||||
});
|
for (const id of ids.split(',')) {
|
||||||
|
tooltips[version === 'gen-1' ? lookUpDomId(id) : id] = tooltip;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setClickFun = function (id, functionName, functionArgs) {
|
const setClickFun = function (id: string, functionName: string, functionArgs: string) {
|
||||||
let domId = lookUpDomId(id);
|
const domId = lookUpDomId(id);
|
||||||
// if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
// if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
||||||
if (getConfig().securityLevel !== 'loose') {
|
if (getConfig().securityLevel !== 'loose') {
|
||||||
return;
|
return;
|
||||||
@@ -303,7 +283,7 @@ const setClickFun = function (id, functionName, functionArgs) {
|
|||||||
if (functionName === undefined) {
|
if (functionName === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let argList = [];
|
let argList: string[] = [];
|
||||||
if (typeof functionArgs === 'string') {
|
if (typeof functionArgs === 'string') {
|
||||||
/* Splits functionArgs by ',', ignoring all ',' in double quoted strings */
|
/* Splits functionArgs by ',', ignoring all ',' in double quoted strings */
|
||||||
argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
|
argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
|
||||||
@@ -343,11 +323,11 @@ const setClickFun = function (id, functionName, functionArgs) {
|
|||||||
/**
|
/**
|
||||||
* Called by parser when a link is found. Adds the URL to the vertex data.
|
* Called by parser when a link is found. Adds the URL to the vertex data.
|
||||||
*
|
*
|
||||||
* @param ids Comma separated list of ids
|
* @param ids - Comma separated list of ids
|
||||||
* @param linkStr URL to create a link for
|
* @param linkStr - URL to create a link for
|
||||||
* @param target
|
* @param target - Target attribute for the link
|
||||||
*/
|
*/
|
||||||
export const setLink = function (ids, linkStr, target) {
|
export const setLink = function (ids: string, linkStr: string, target: string) {
|
||||||
ids.split(',').forEach(function (id) {
|
ids.split(',').forEach(function (id) {
|
||||||
if (vertices[id] !== undefined) {
|
if (vertices[id] !== undefined) {
|
||||||
vertices[id].link = utils.formatUrl(linkStr, config);
|
vertices[id].link = utils.formatUrl(linkStr, config);
|
||||||
@@ -356,7 +336,8 @@ export const setLink = function (ids, linkStr, target) {
|
|||||||
});
|
});
|
||||||
setClass(ids, 'clickable');
|
setClass(ids, 'clickable');
|
||||||
};
|
};
|
||||||
export const getTooltip = function (id) {
|
|
||||||
|
export const getTooltip = function (id: string) {
|
||||||
if (tooltips.hasOwnProperty(id)) {
|
if (tooltips.hasOwnProperty(id)) {
|
||||||
return tooltips[id];
|
return tooltips[id];
|
||||||
}
|
}
|
||||||
@@ -366,18 +347,18 @@ export const getTooltip = function (id) {
|
|||||||
/**
|
/**
|
||||||
* Called by parser when a click definition is found. Registers an event handler.
|
* Called by parser when a click definition is found. Registers an event handler.
|
||||||
*
|
*
|
||||||
* @param ids Comma separated list of ids
|
* @param ids - Comma separated list of ids
|
||||||
* @param functionName Function to be called on click
|
* @param functionName - Function to be called on click
|
||||||
* @param functionArgs
|
* @param functionArgs - Arguments to be passed to the function
|
||||||
*/
|
*/
|
||||||
export const setClickEvent = function (ids, functionName, functionArgs) {
|
export const setClickEvent = function (ids: string, functionName: string, functionArgs: string) {
|
||||||
ids.split(',').forEach(function (id) {
|
ids.split(',').forEach(function (id) {
|
||||||
setClickFun(id, functionName, functionArgs);
|
setClickFun(id, functionName, functionArgs);
|
||||||
});
|
});
|
||||||
setClass(ids, 'clickable');
|
setClass(ids, 'clickable');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const bindFunctions = function (element) {
|
export const bindFunctions = function (element: Element) {
|
||||||
funs.forEach(function (fun) {
|
funs.forEach(function (fun) {
|
||||||
fun(element);
|
fun(element);
|
||||||
});
|
});
|
||||||
@@ -388,7 +369,6 @@ export const getDirection = function () {
|
|||||||
/**
|
/**
|
||||||
* Retrieval function for fetching the found nodes after parsing has completed.
|
* Retrieval function for fetching the found nodes after parsing has completed.
|
||||||
*
|
*
|
||||||
* @returns {{} | any | vertices}
|
|
||||||
*/
|
*/
|
||||||
export const getVertices = function () {
|
export const getVertices = function () {
|
||||||
return vertices;
|
return vertices;
|
||||||
@@ -397,7 +377,6 @@ export const getVertices = function () {
|
|||||||
/**
|
/**
|
||||||
* Retrieval function for fetching the found links after parsing has completed.
|
* Retrieval function for fetching the found links after parsing has completed.
|
||||||
*
|
*
|
||||||
* @returns {{} | any | edges}
|
|
||||||
*/
|
*/
|
||||||
export const getEdges = function () {
|
export const getEdges = function () {
|
||||||
return edges;
|
return edges;
|
||||||
@@ -406,15 +385,16 @@ export const getEdges = function () {
|
|||||||
/**
|
/**
|
||||||
* Retrieval function for fetching the found class definitions after parsing has completed.
|
* Retrieval function for fetching the found class definitions after parsing has completed.
|
||||||
*
|
*
|
||||||
* @returns {{} | any | classes}
|
|
||||||
*/
|
*/
|
||||||
export const getClasses = function () {
|
export const getClasses = function () {
|
||||||
return classes;
|
return classes;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setupToolTips = function (element) {
|
const setupToolTips = function (element: Element) {
|
||||||
let tooltipElem = select('.mermaidTooltip');
|
let tooltipElem = select('.mermaidTooltip');
|
||||||
|
// @ts-ignore TODO: fix this
|
||||||
if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
|
if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
|
||||||
|
// @ts-ignore TODO: fix this
|
||||||
tooltipElem = select('body').append('div').attr('class', 'mermaidTooltip').style('opacity', 0);
|
tooltipElem = select('body').append('div').attr('class', 'mermaidTooltip').style('opacity', 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,8 +410,9 @@ const setupToolTips = function (element) {
|
|||||||
if (title === null) {
|
if (title === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const rect = this.getBoundingClientRect();
|
const rect = (this as Element)?.getBoundingClientRect();
|
||||||
|
|
||||||
|
// @ts-ignore TODO: fix this
|
||||||
tooltipElem.transition().duration(200).style('opacity', '.9');
|
tooltipElem.transition().duration(200).style('opacity', '.9');
|
||||||
tooltipElem
|
tooltipElem
|
||||||
.text(el.attr('title'))
|
.text(el.attr('title'))
|
||||||
@@ -441,6 +422,7 @@ const setupToolTips = function (element) {
|
|||||||
el.classed('hover', true);
|
el.classed('hover', true);
|
||||||
})
|
})
|
||||||
.on('mouseout', function () {
|
.on('mouseout', function () {
|
||||||
|
// @ts-ignore TODO: fix this
|
||||||
tooltipElem.transition().duration(500).style('opacity', 0);
|
tooltipElem.transition().duration(500).style('opacity', 0);
|
||||||
const el = select(this);
|
const el = select(this);
|
||||||
el.classed('hover', false);
|
el.classed('hover', false);
|
||||||
@@ -451,7 +433,6 @@ funs.push(setupToolTips);
|
|||||||
/**
|
/**
|
||||||
* Clears the internal graph db so that a new graph can be parsed.
|
* Clears the internal graph db so that a new graph can be parsed.
|
||||||
*
|
*
|
||||||
* @param ver
|
|
||||||
*/
|
*/
|
||||||
export const clear = function (ver = 'gen-1') {
|
export const clear = function (ver = 'gen-1') {
|
||||||
vertices = {};
|
vertices = {};
|
||||||
@@ -467,31 +448,29 @@ export const clear = function (ver = 'gen-1') {
|
|||||||
config = getConfig();
|
config = getConfig();
|
||||||
commonClear();
|
commonClear();
|
||||||
};
|
};
|
||||||
export const setGen = (ver) => {
|
|
||||||
|
export const setGen = (ver: string) => {
|
||||||
version = ver || 'gen-2';
|
version = ver || 'gen-2';
|
||||||
};
|
};
|
||||||
/** @returns {string} */
|
|
||||||
export const defaultStyle = function () {
|
export const defaultStyle = function () {
|
||||||
return 'fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;';
|
return 'fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
export const addSubGraph = function (
|
||||||
* Clears the internal graph db so that a new graph can be parsed.
|
_id: { text: string },
|
||||||
*
|
list: string[],
|
||||||
* @param _id
|
_title: { text: string; type: string }
|
||||||
* @param list
|
) {
|
||||||
* @param _title
|
let id: string | undefined = _id.text.trim();
|
||||||
*/
|
|
||||||
export const addSubGraph = function (_id, list, _title) {
|
|
||||||
let id = _id.text.trim();
|
|
||||||
let title = _title.text;
|
let title = _title.text;
|
||||||
if (_id === _title && _title.text.match(/\s/)) {
|
if (_id === _title && _title.text.match(/\s/)) {
|
||||||
id = undefined;
|
id = undefined;
|
||||||
}
|
}
|
||||||
/** @param a */
|
|
||||||
function uniq(a) {
|
function uniq(a: any[]) {
|
||||||
const prims = { boolean: {}, number: {}, string: {} };
|
const prims: any = { boolean: {}, number: {}, string: {} };
|
||||||
const objs = [];
|
const objs: any[] = [];
|
||||||
|
|
||||||
let dir; // = undefined; direction.trim();
|
let dir; // = undefined; direction.trim();
|
||||||
const nodeList = a.filter(function (item) {
|
const nodeList = a.filter(function (item) {
|
||||||
@@ -512,10 +491,7 @@ export const addSubGraph = function (_id, list, _title) {
|
|||||||
return { nodeList, dir };
|
return { nodeList, dir };
|
||||||
}
|
}
|
||||||
|
|
||||||
let nodeList = [];
|
const { nodeList, dir } = uniq(list.flat());
|
||||||
|
|
||||||
const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list));
|
|
||||||
nodeList = nl;
|
|
||||||
if (version === 'gen-1') {
|
if (version === 'gen-1') {
|
||||||
for (let i = 0; i < nodeList.length; i++) {
|
for (let i = 0; i < nodeList.length; i++) {
|
||||||
nodeList[i] = lookUpDomId(nodeList[i]);
|
nodeList[i] = lookUpDomId(nodeList[i]);
|
||||||
@@ -523,7 +499,6 @@ export const addSubGraph = function (_id, list, _title) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id = id || 'subGraph' + subCount;
|
id = id || 'subGraph' + subCount;
|
||||||
// if (id[0].match(/\d/)) id = lookUpDomId(id);
|
|
||||||
title = title || '';
|
title = title || '';
|
||||||
title = sanitizeText(title);
|
title = sanitizeText(title);
|
||||||
subCount = subCount + 1;
|
subCount = subCount + 1;
|
||||||
@@ -538,19 +513,6 @@ export const addSubGraph = function (_id, list, _title) {
|
|||||||
|
|
||||||
log.info('Adding', subGraph.id, subGraph.nodes, subGraph.dir);
|
log.info('Adding', subGraph.id, subGraph.nodes, subGraph.dir);
|
||||||
|
|
||||||
/** Deletes an id from all subgraphs */
|
|
||||||
// const del = _id => {
|
|
||||||
// subGraphs.forEach(sg => {
|
|
||||||
// const pos = sg.nodes.indexOf(_id);
|
|
||||||
// if (pos >= 0) {
|
|
||||||
// sg.nodes.splice(pos, 1);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Removes the members of this subgraph from any other subgraphs, a node only belong to one subgraph
|
|
||||||
// subGraph.nodes.forEach(_id => del(_id));
|
|
||||||
|
|
||||||
// Remove the members in the new subgraph if they already belong to another subgraph
|
// Remove the members in the new subgraph if they already belong to another subgraph
|
||||||
subGraph.nodes = makeUniq(subGraph, subGraphs).nodes;
|
subGraph.nodes = makeUniq(subGraph, subGraphs).nodes;
|
||||||
subGraphs.push(subGraph);
|
subGraphs.push(subGraph);
|
||||||
@@ -558,7 +520,7 @@ export const addSubGraph = function (_id, list, _title) {
|
|||||||
return id;
|
return id;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPosForId = function (id) {
|
const getPosForId = function (id: string) {
|
||||||
for (const [i, subGraph] of subGraphs.entries()) {
|
for (const [i, subGraph] of subGraphs.entries()) {
|
||||||
if (subGraph.id === id) {
|
if (subGraph.id === id) {
|
||||||
return i;
|
return i;
|
||||||
@@ -567,12 +529,15 @@ const getPosForId = function (id) {
|
|||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
let secCount = -1;
|
let secCount = -1;
|
||||||
const posCrossRef = [];
|
const posCrossRef: number[] = [];
|
||||||
const indexNodes2 = function (id, pos) {
|
const indexNodes2 = function (id: string, pos: number): { result: boolean; count: number } {
|
||||||
const nodes = subGraphs[pos].nodes;
|
const nodes = subGraphs[pos].nodes;
|
||||||
secCount = secCount + 1;
|
secCount = secCount + 1;
|
||||||
if (secCount > 2000) {
|
if (secCount > 2000) {
|
||||||
return;
|
return {
|
||||||
|
result: false,
|
||||||
|
count: 0,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
posCrossRef[secCount] = pos;
|
posCrossRef[secCount] = pos;
|
||||||
// Check if match
|
// Check if match
|
||||||
@@ -608,13 +573,13 @@ const indexNodes2 = function (id, pos) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDepthFirstPos = function (pos) {
|
export const getDepthFirstPos = function (pos: number) {
|
||||||
return posCrossRef[pos];
|
return posCrossRef[pos];
|
||||||
};
|
};
|
||||||
export const indexNodes = function () {
|
export const indexNodes = function () {
|
||||||
secCount = -1;
|
secCount = -1;
|
||||||
if (subGraphs.length > 0) {
|
if (subGraphs.length > 0) {
|
||||||
indexNodes2('none', subGraphs.length - 1, 0);
|
indexNodes2('none', subGraphs.length - 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -630,7 +595,7 @@ export const firstGraph = () => {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const destructStartLink = (_str) => {
|
const destructStartLink = (_str: string): FlowLink => {
|
||||||
let str = _str.trim();
|
let str = _str.trim();
|
||||||
let type = 'arrow_open';
|
let type = 'arrow_open';
|
||||||
|
|
||||||
@@ -662,7 +627,7 @@ const destructStartLink = (_str) => {
|
|||||||
return { type, stroke };
|
return { type, stroke };
|
||||||
};
|
};
|
||||||
|
|
||||||
const countChar = (char, str) => {
|
const countChar = (char: string, str: string) => {
|
||||||
const length = str.length;
|
const length = str.length;
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (let i = 0; i < length; ++i) {
|
for (let i = 0; i < length; ++i) {
|
||||||
@@ -673,7 +638,7 @@ const countChar = (char, str) => {
|
|||||||
return count;
|
return count;
|
||||||
};
|
};
|
||||||
|
|
||||||
const destructEndLink = (_str) => {
|
const destructEndLink = (_str: string) => {
|
||||||
const str = _str.trim();
|
const str = _str.trim();
|
||||||
let line = str.slice(0, -1);
|
let line = str.slice(0, -1);
|
||||||
let type = 'arrow_open';
|
let type = 'arrow_open';
|
||||||
@@ -713,7 +678,7 @@ const destructEndLink = (_str) => {
|
|||||||
stroke = 'invisible';
|
stroke = 'invisible';
|
||||||
}
|
}
|
||||||
|
|
||||||
let dots = countChar('.', line);
|
const dots = countChar('.', line);
|
||||||
|
|
||||||
if (dots) {
|
if (dots) {
|
||||||
stroke = 'dotted';
|
stroke = 'dotted';
|
||||||
@@ -723,7 +688,7 @@ const destructEndLink = (_str) => {
|
|||||||
return { type, stroke, length };
|
return { type, stroke, length };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const destructLink = (_str, _startStr) => {
|
export const destructLink = (_str: string, _startStr: string) => {
|
||||||
const info = destructEndLink(_str);
|
const info = destructEndLink(_str);
|
||||||
let startInfo;
|
let startInfo;
|
||||||
if (_startStr) {
|
if (_startStr) {
|
||||||
@@ -757,7 +722,7 @@ export const destructLink = (_str, _startStr) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Todo optimizer this by caching existing nodes
|
// Todo optimizer this by caching existing nodes
|
||||||
const exists = (allSgs, _id) => {
|
const exists = (allSgs: FlowSubGraph[], _id: string) => {
|
||||||
let res = false;
|
let res = false;
|
||||||
allSgs.forEach((sg) => {
|
allSgs.forEach((sg) => {
|
||||||
const pos = sg.nodes.indexOf(_id);
|
const pos = sg.nodes.indexOf(_id);
|
||||||
@@ -770,11 +735,9 @@ const exists = (allSgs, _id) => {
|
|||||||
/**
|
/**
|
||||||
* Deletes an id from all subgraphs
|
* Deletes an id from all subgraphs
|
||||||
*
|
*
|
||||||
* @param sg
|
|
||||||
* @param allSubgraphs
|
|
||||||
*/
|
*/
|
||||||
const makeUniq = (sg, allSubgraphs) => {
|
const makeUniq = (sg: FlowSubGraph, allSubgraphs: FlowSubGraph[]) => {
|
||||||
const res = [];
|
const res: string[] = [];
|
||||||
sg.nodes.forEach((_id, pos) => {
|
sg.nodes.forEach((_id, pos) => {
|
||||||
if (!exists(allSubgraphs, _id)) {
|
if (!exists(allSubgraphs, _id)) {
|
||||||
res.push(sg.nodes[pos]);
|
res.push(sg.nodes[pos]);
|
||||||
@@ -786,6 +749,7 @@ const makeUniq = (sg, allSubgraphs) => {
|
|||||||
export const lex = {
|
export const lex = {
|
||||||
firstGraph,
|
firstGraph,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultConfig: () => defaultConfig.flowchart,
|
defaultConfig: () => defaultConfig.flowchart,
|
||||||
setAccTitle,
|
setAccTitle,
|
@@ -1,503 +0,0 @@
|
|||||||
/** mermaid
|
|
||||||
* https://mermaidjs.github.io/
|
|
||||||
* (c) 2015 Knut Sveidqvist
|
|
||||||
* MIT license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* lexical grammar */
|
|
||||||
%lex
|
|
||||||
%x string
|
|
||||||
|
|
||||||
%%
|
|
||||||
\%\%[^\n]* /* do nothing */
|
|
||||||
["] this.begin("string");
|
|
||||||
<string>["] this.popState();
|
|
||||||
<string>[^"]* return "STR";
|
|
||||||
"style" return 'STYLE';
|
|
||||||
"default" return 'DEFAULT';
|
|
||||||
"linkStyle" return 'LINKSTYLE';
|
|
||||||
"interpolate" return 'INTERPOLATE';
|
|
||||||
"classDef" return 'CLASSDEF';
|
|
||||||
"class" return 'CLASS';
|
|
||||||
"click" return 'CLICK';
|
|
||||||
"graph" return 'GRAPH';
|
|
||||||
"subgraph" return 'subgraph';
|
|
||||||
"end"\b\s* return 'end';
|
|
||||||
"LR" return 'DIR';
|
|
||||||
"RL" return 'DIR';
|
|
||||||
"TB" return 'DIR';
|
|
||||||
"BT" return 'DIR';
|
|
||||||
"TD" return 'DIR';
|
|
||||||
"BR" return 'DIR';
|
|
||||||
[0-9]+ return 'NUM';
|
|
||||||
\# return 'BRKT';
|
|
||||||
":" return 'COLON';
|
|
||||||
";" return 'SEMI';
|
|
||||||
"," return 'COMMA';
|
|
||||||
"*" return 'MULT';
|
|
||||||
\s*\-\-[x]\s* return 'ARROW_CROSS';
|
|
||||||
\s*[x]\-\-[x]\s* return 'DOUBLE_ARROW_CROSS';
|
|
||||||
\s*\-\-\>\s* return 'ARROW_POINT';
|
|
||||||
\s*\<\-\-\>\s* return 'DOUBLE_ARROW_POINT';
|
|
||||||
\s*\-\-[o]\s* return 'ARROW_CIRCLE';
|
|
||||||
\s*[o]\-\-[o]\s* return 'DOUBLE_ARROW_CIRCLE';
|
|
||||||
\s*\-\-\-\s* return 'ARROW_OPEN';
|
|
||||||
\s*\-\.\-[x]\s* return 'DOTTED_ARROW_CROSS';
|
|
||||||
\s*[x]\-\.\-[x]\s* return 'DOUBLE_DOTTED_ARROW_CROSS';
|
|
||||||
\s*\-\.\-\>\s* return 'DOTTED_ARROW_POINT';
|
|
||||||
\s*\<\-\.\-\>\s* return 'DOUBLE_DOTTED_ARROW_POINT';
|
|
||||||
\s*\-\.\-[o]\s* return 'DOTTED_ARROW_CIRCLE';
|
|
||||||
\s*[o]\-\.\-[o]\s* return 'DOUBLE_DOTTED_ARROW_CIRCLE';
|
|
||||||
\s*\-\.\-\s* return 'DOTTED_ARROW_OPEN';
|
|
||||||
\s*.\-[x]\s* return 'DOTTED_ARROW_CROSS';
|
|
||||||
\s*[x].\-[x]\s* return 'DOUBLE_DOTTED_ARROW_CROSS';
|
|
||||||
\s*\.\-\>\s* return 'DOTTED_ARROW_POINT';
|
|
||||||
\s*\<\.\-\>\s* return 'DOUBLE_DOTTED_ARROW_POINT';
|
|
||||||
\s*\.\-[o]\s* return 'DOTTED_ARROW_CIRCLE';
|
|
||||||
\s*[o]\.\-[o]\s* return 'DOUBLE_DOTTED_ARROW_CIRCLE';
|
|
||||||
\s*\.\-\s* return 'DOTTED_ARROW_OPEN';
|
|
||||||
\s*\=\=[x]\s* return 'THICK_ARROW_CROSS';
|
|
||||||
\s*[x]\=\=[x]\s* return 'DOUBLE_THICK_ARROW_CROSS';
|
|
||||||
\s*\=\=\>\s* return 'THICK_ARROW_POINT';
|
|
||||||
\s*\<\=\=\>\s* return 'DOUBLE_THICK_ARROW_POINT';
|
|
||||||
\s*\=\=[o]\s* return 'THICK_ARROW_CIRCLE';
|
|
||||||
\s*[o]\=\=[o]\s* return 'DOUBLE_THICK_ARROW_CIRCLE';
|
|
||||||
\s*\=\=[\=]\s* return 'THICK_ARROW_OPEN';
|
|
||||||
\s*\-\-\s* return '--';
|
|
||||||
\s*\-\.\s* return '-.';
|
|
||||||
\s*\=\=\s* return '==';
|
|
||||||
%\s*\<\-\-\s* return 'START_DOUBLE_ARROW_POINT';
|
|
||||||
%\s*\[x]\-\-\s* return 'START_DOUBLE_ARROW_CROSS';
|
|
||||||
%\s*\[o]\-\-\s* return 'START_DOUBLE_ARROW_CIRCLE';
|
|
||||||
%\s*\<\-\.\s* return 'START_DOUBLE_DOTTED_ARROW_POINT';
|
|
||||||
%\s*\[x]\-\.\s* return 'START_DOUBLE_DOTTED_ARROW_CROSS';
|
|
||||||
%\s*\[o]\-\.\s* return 'START_DOUBLE_DOTTED_ARROW_CIRCLE';
|
|
||||||
%\s*\<\=\=\s* return 'START_DOUBLE_THICK_ARROW_POINT';
|
|
||||||
%\s*\[x]\=\=\s* return 'START_DOUBLE_THICK_ARROW_CROSS';
|
|
||||||
%\s*\[o]\=\=\s* return 'START_DOUBLE_THICK_ARROW_CIRCLE';
|
|
||||||
"(-" return '(-';
|
|
||||||
"-)" return '-)';
|
|
||||||
\- return 'MINUS';
|
|
||||||
"." return 'DOT';
|
|
||||||
\+ return 'PLUS';
|
|
||||||
\% return 'PCT';
|
|
||||||
"=" return 'EQUALS';
|
|
||||||
\= return 'EQUALS';
|
|
||||||
"<" return 'TAGSTART';
|
|
||||||
">" return 'TAGEND';
|
|
||||||
"^" return 'UP';
|
|
||||||
"v" return 'DOWN';
|
|
||||||
[A-Za-z]+ return 'ALPHA';
|
|
||||||
[!"#$%&'*+,-.`?\\_/] return 'PUNCTUATION';
|
|
||||||
[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|
|
|
||||||
[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|
|
|
||||||
[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|
|
|
||||||
[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|
|
|
||||||
[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|
|
|
||||||
[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|
|
|
||||||
[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|
|
|
||||||
[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|
|
|
||||||
[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|
|
|
||||||
[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|
|
|
||||||
[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|
|
|
||||||
[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|
|
|
||||||
[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|
|
|
||||||
[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|
|
|
||||||
[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|
|
|
||||||
[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|
|
|
||||||
[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|
|
|
||||||
[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|
|
|
||||||
[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|
|
|
||||||
[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|
|
|
||||||
[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|
|
|
||||||
[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|
|
|
||||||
[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|
|
|
||||||
[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|
|
|
||||||
[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|
|
|
||||||
[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|
|
|
||||||
[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|
|
|
||||||
[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|
|
|
||||||
[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|
|
|
||||||
[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|
|
|
||||||
[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|
|
|
||||||
[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|
|
|
||||||
[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|
|
|
||||||
[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|
|
|
||||||
[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|
|
|
||||||
[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|
|
|
||||||
[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|
|
|
||||||
[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|
|
|
||||||
[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|
|
|
||||||
[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|
|
|
||||||
[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|
|
|
||||||
[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|
|
|
||||||
[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|
|
|
||||||
[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|
|
|
||||||
[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|
|
|
||||||
[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|
|
|
||||||
[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|
|
|
||||||
[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|
|
|
||||||
[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|
|
|
||||||
[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|
|
|
||||||
[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|
|
|
||||||
[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|
|
|
||||||
[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|
|
|
||||||
[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|
|
|
||||||
[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|
|
|
||||||
[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|
|
|
||||||
[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|
|
|
||||||
[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|
|
|
||||||
[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|
|
|
||||||
[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|
|
|
||||||
[\uFFD2-\uFFD7\uFFDA-\uFFDC]
|
|
||||||
return 'UNICODE_TEXT';
|
|
||||||
"|" return 'PIPE';
|
|
||||||
"(" return 'PS';
|
|
||||||
")" return 'PE';
|
|
||||||
"[" return 'SQS';
|
|
||||||
"]" return 'SQE';
|
|
||||||
"{" return 'DIAMOND_START'
|
|
||||||
"}" return 'DIAMOND_STOP'
|
|
||||||
"\"" return 'QUOTE';
|
|
||||||
\n+ return 'NEWLINE';
|
|
||||||
\s return 'SPACE';
|
|
||||||
<<EOF>> return 'EOF';
|
|
||||||
|
|
||||||
/lex
|
|
||||||
|
|
||||||
/* operator associations and precedence */
|
|
||||||
|
|
||||||
%left '^'
|
|
||||||
|
|
||||||
%start mermaidDoc
|
|
||||||
|
|
||||||
%% /* language grammar */
|
|
||||||
|
|
||||||
mermaidDoc: graphConfig document;
|
|
||||||
|
|
||||||
document
|
|
||||||
: /* empty */
|
|
||||||
{ $$ = [];}
|
|
||||||
| document line
|
|
||||||
{
|
|
||||||
if($2 !== []){
|
|
||||||
$1.push($2);
|
|
||||||
}
|
|
||||||
$$=$1;}
|
|
||||||
;
|
|
||||||
|
|
||||||
line
|
|
||||||
: statement
|
|
||||||
{$$=$1;}
|
|
||||||
| SEMI
|
|
||||||
| NEWLINE
|
|
||||||
| SPACE
|
|
||||||
| EOF
|
|
||||||
;
|
|
||||||
|
|
||||||
graphConfig
|
|
||||||
: SPACE graphConfig
|
|
||||||
| NEWLINE graphConfig
|
|
||||||
| GRAPH SPACE DIR FirstStmtSeperator
|
|
||||||
{ yy.setDirection($3);$$ = $3;}
|
|
||||||
| GRAPH SPACE TAGEND FirstStmtSeperator
|
|
||||||
{ yy.setDirection("LR");$$ = $3;}
|
|
||||||
| GRAPH SPACE TAGSTART FirstStmtSeperator
|
|
||||||
{ yy.setDirection("RL");$$ = $3;}
|
|
||||||
| GRAPH SPACE UP FirstStmtSeperator
|
|
||||||
{ yy.setDirection("BT");$$ = $3;}
|
|
||||||
| GRAPH SPACE DOWN FirstStmtSeperator
|
|
||||||
{ yy.setDirection("TB");$$ = $3;}
|
|
||||||
;
|
|
||||||
|
|
||||||
ending: endToken ending
|
|
||||||
| endToken
|
|
||||||
;
|
|
||||||
|
|
||||||
endToken: NEWLINE | SPACE | EOF;
|
|
||||||
|
|
||||||
FirstStmtSeperator
|
|
||||||
: SEMI | NEWLINE | spaceList NEWLINE ;
|
|
||||||
|
|
||||||
|
|
||||||
spaceListNewline
|
|
||||||
: SPACE spaceListNewline
|
|
||||||
| NEWLINE spaceListNewline
|
|
||||||
| NEWLINE
|
|
||||||
| SPACE
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
spaceList
|
|
||||||
: SPACE spaceList
|
|
||||||
| SPACE
|
|
||||||
;
|
|
||||||
|
|
||||||
statement
|
|
||||||
: verticeStatement separator
|
|
||||||
{$$=$1}
|
|
||||||
| styleStatement separator
|
|
||||||
{$$=[];}
|
|
||||||
| linkStyleStatement separator
|
|
||||||
{$$=[];}
|
|
||||||
| classDefStatement separator
|
|
||||||
{$$=[];}
|
|
||||||
| classStatement separator
|
|
||||||
{$$=[];}
|
|
||||||
| clickStatement separator
|
|
||||||
{$$=[];}
|
|
||||||
| subgraph SPACE alphaNum SQS text SQE separator document end
|
|
||||||
{$$=yy.addSubGraph($3,$8,$5);}
|
|
||||||
| subgraph SPACE STR separator document end
|
|
||||||
{$$=yy.addSubGraph(undefined,$5,$3);}
|
|
||||||
| subgraph SPACE alphaNum separator document end
|
|
||||||
{$$=yy.addSubGraph($3,$5,$3);}
|
|
||||||
| subgraph separator document end
|
|
||||||
{$$=yy.addSubGraph(undefined,$3,undefined);}
|
|
||||||
;
|
|
||||||
|
|
||||||
separator: NEWLINE | SEMI | EOF ;
|
|
||||||
|
|
||||||
verticeStatement:
|
|
||||||
vertex link vertex
|
|
||||||
{ yy.addLink($1,$3,$2);$$ = [$1,$3];}
|
|
||||||
| vertex
|
|
||||||
{$$ = [$1];}
|
|
||||||
;
|
|
||||||
|
|
||||||
vertex: alphaNum SQS text SQE
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'square');}
|
|
||||||
| alphaNum SQS text SQE spaceList
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'square');}
|
|
||||||
| alphaNum PS PS text PE PE
|
|
||||||
{$$ = $1;yy.addVertex($1,$4,'circle');}
|
|
||||||
| alphaNum PS PS text PE PE spaceList
|
|
||||||
{$$ = $1;yy.addVertex($1,$4,'circle');}
|
|
||||||
| alphaNum '(-' text '-)'
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'ellipse');}
|
|
||||||
| alphaNum '(-' text '-)' spaceList
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'ellipse');}
|
|
||||||
| alphaNum PS text PE
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'round');}
|
|
||||||
| alphaNum PS text PE spaceList
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'round');}
|
|
||||||
| alphaNum DIAMOND_START text DIAMOND_STOP
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'diamond');}
|
|
||||||
| alphaNum DIAMOND_START text DIAMOND_STOP spaceList
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'diamond');}
|
|
||||||
| alphaNum TAGEND text SQE
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'odd');}
|
|
||||||
| alphaNum TAGEND text SQE spaceList
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'odd');}
|
|
||||||
/* | alphaNum SQS text TAGSTART
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'odd_right');}
|
|
||||||
| alphaNum SQS text TAGSTART spaceList
|
|
||||||
{$$ = $1;yy.addVertex($1,$3,'odd_right');} */
|
|
||||||
| alphaNum
|
|
||||||
{$$ = $1;yy.addVertex($1);}
|
|
||||||
| alphaNum spaceList
|
|
||||||
{$$ = $1;yy.addVertex($1);}
|
|
||||||
;
|
|
||||||
|
|
||||||
alphaNum
|
|
||||||
: alphaNumStatement
|
|
||||||
{$$=$1;}
|
|
||||||
| alphaNum alphaNumStatement
|
|
||||||
{$$=$1+''+$2;}
|
|
||||||
;
|
|
||||||
|
|
||||||
alphaNumStatement
|
|
||||||
: DIR
|
|
||||||
{$$=$1;}
|
|
||||||
| alphaNumToken
|
|
||||||
{$$=$1;}
|
|
||||||
| DOWN
|
|
||||||
{$$='v';}
|
|
||||||
| MINUS
|
|
||||||
{$$='-';}
|
|
||||||
;
|
|
||||||
|
|
||||||
link: linkStatement arrowText
|
|
||||||
{$1.text = $2;$$ = $1;}
|
|
||||||
| linkStatement TESTSTR SPACE
|
|
||||||
{$1.text = $2;$$ = $1;}
|
|
||||||
| linkStatement arrowText SPACE
|
|
||||||
{$1.text = $2;$$ = $1;}
|
|
||||||
| linkStatement
|
|
||||||
{$$ = $1;}
|
|
||||||
| '--' text ARROW_POINT
|
|
||||||
{$$ = {"type":"arrow","stroke":"normal","text":$2};}
|
|
||||||
| 'START_DOUBLE_ARROW_POINT' text ARROW_POINT
|
|
||||||
{$$ = {"type":"double_arrow_point","stroke":"normal","text":$2};}
|
|
||||||
| '--' text ARROW_CIRCLE
|
|
||||||
{$$ = {"type":"arrow_circle","stroke":"normal","text":$2};}
|
|
||||||
| '--' text ARROW_CROSS
|
|
||||||
{$$ = {"type":"arrow_cross","stroke":"normal","text":$2};}
|
|
||||||
| '--' text ARROW_OPEN
|
|
||||||
{$$ = {"type":"arrow_open","stroke":"normal","text":$2};}
|
|
||||||
| '-.' text DOTTED_ARROW_POINT
|
|
||||||
{$$ = {"type":"arrow","stroke":"dotted","text":$2};}
|
|
||||||
| '-.' text DOTTED_ARROW_CIRCLE
|
|
||||||
{$$ = {"type":"arrow_circle","stroke":"dotted","text":$2};}
|
|
||||||
| '-.' text DOTTED_ARROW_CROSS
|
|
||||||
{$$ = {"type":"arrow_cross","stroke":"dotted","text":$2};}
|
|
||||||
| '-.' text DOTTED_ARROW_OPEN
|
|
||||||
{$$ = {"type":"arrow_open","stroke":"dotted","text":$2};}
|
|
||||||
| '==' text THICK_ARROW_POINT
|
|
||||||
{$$ = {"type":"arrow","stroke":"thick","text":$2};}
|
|
||||||
| '==' text THICK_ARROW_CIRCLE
|
|
||||||
{$$ = {"type":"arrow_circle","stroke":"thick","text":$2};}
|
|
||||||
| '==' text THICK_ARROW_CROSS
|
|
||||||
{$$ = {"type":"arrow_cross","stroke":"thick","text":$2};}
|
|
||||||
| '==' text THICK_ARROW_OPEN
|
|
||||||
{$$ = {"type":"arrow_open","stroke":"thick","text":$2};}
|
|
||||||
;
|
|
||||||
|
|
||||||
linkStatement: ARROW_POINT
|
|
||||||
{$$ = {"type":"arrow","stroke":"normal"};}
|
|
||||||
| DOUBLE_ARROW_POINT
|
|
||||||
{$$ = {"type":"double_arrow_point","stroke":"normal"};}
|
|
||||||
| ARROW_CIRCLE
|
|
||||||
{$$ = {"type":"arrow_circle","stroke":"normal"};}
|
|
||||||
% | DOUBLE_ARROW_CIRCLE
|
|
||||||
% {$$ = {"type":"double_arrow_circle","stroke":"normal"};}
|
|
||||||
| ARROW_CROSS
|
|
||||||
{$$ = {"type":"arrow_cross","stroke":"normal"};}
|
|
||||||
% | DOUBLE_ARROW_CROSS
|
|
||||||
% {$$ = {"type":"double_arrow_cross","stroke":"normal"};}
|
|
||||||
| ARROW_OPEN
|
|
||||||
{$$ = {"type":"arrow_open","stroke":"normal"};}
|
|
||||||
| DOTTED_ARROW_POINT
|
|
||||||
{$$ = {"type":"arrow","stroke":"dotted"};}
|
|
||||||
% | DOUEBL_DOTTED_ARROW_POINT
|
|
||||||
% {$$ = {"type":"doueble_arrow_point","stroke":"dotted"};}
|
|
||||||
| DOTTED_ARROW_CIRCLE
|
|
||||||
{$$ = {"type":"arrow_circle","stroke":"dotted"};}
|
|
||||||
% | DOTTED_ARROW_CIRCLE
|
|
||||||
% {$$ = {"type":"double_arrow_circle","stroke":"dotted"};}
|
|
||||||
| DOTTED_ARROW_CROSS
|
|
||||||
{$$ = {"type":"arrow_cross","stroke":"dotted"};}
|
|
||||||
% | DOTTED_ARROW_CROSS
|
|
||||||
% {$$ = {"type":"double_arrow_cross","stroke":"dotted"};}
|
|
||||||
| DOTTED_ARROW_OPEN
|
|
||||||
{$$ = {"type":"arrow_open","stroke":"dotted"};}
|
|
||||||
| THICK_ARROW_POINT
|
|
||||||
{$$ = {"type":"arrow","stroke":"thick"};}
|
|
||||||
% | THICK_ARROW_POINT
|
|
||||||
% {$$ = {"type":"double_arrow_point","stroke":"thick"};}
|
|
||||||
| THICK_ARROW_CIRCLE
|
|
||||||
{$$ = {"type":"arrow_circle","stroke":"thick"};}
|
|
||||||
% | THICK_ARROW_CIRCLE
|
|
||||||
% {$$ = {"type":"double_arrow_circle","stroke":"thick"};}
|
|
||||||
| THICK_ARROW_CROSS
|
|
||||||
{$$ = {"type":"arrow_cross","stroke":"thick"};}
|
|
||||||
% | THICK_ARROW_CROSS
|
|
||||||
% {$$ = {"type":"double_arrow_cross","stroke":"thick"};}
|
|
||||||
| THICK_ARROW_OPEN
|
|
||||||
{$$ = {"type":"arrow_open","stroke":"thick"};}
|
|
||||||
;
|
|
||||||
|
|
||||||
arrowText:
|
|
||||||
PIPE text PIPE
|
|
||||||
{$$ = $2;}
|
|
||||||
;
|
|
||||||
|
|
||||||
text: textToken
|
|
||||||
{$$=$1;}
|
|
||||||
| text textToken
|
|
||||||
{$$=$1+''+$2;}
|
|
||||||
| STR
|
|
||||||
{$$=$1;}
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
commentText: commentToken
|
|
||||||
{$$=$1;}
|
|
||||||
| commentText commentToken
|
|
||||||
{$$=$1+''+$2;}
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
keywords
|
|
||||||
: STYLE | LINKSTYLE | CLASSDEF | CLASS | CLICK | GRAPH | DIR | subgraph | end | DOWN | UP;
|
|
||||||
|
|
||||||
|
|
||||||
textNoTags: textNoTagsToken
|
|
||||||
{$$=$1;}
|
|
||||||
| textNoTags textNoTagsToken
|
|
||||||
{$$=$1+''+$2;}
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
classDefStatement:CLASSDEF SPACE DEFAULT SPACE stylesOpt
|
|
||||||
{$$ = $1;yy.addClass($3,$5);}
|
|
||||||
| CLASSDEF SPACE alphaNum SPACE stylesOpt
|
|
||||||
{$$ = $1;yy.addClass($3,$5);}
|
|
||||||
;
|
|
||||||
|
|
||||||
classStatement:CLASS SPACE alphaNum SPACE alphaNum
|
|
||||||
{$$ = $1;yy.setClass($3, $5);}
|
|
||||||
;
|
|
||||||
|
|
||||||
clickStatement
|
|
||||||
: CLICK SPACE alphaNum SPACE alphaNum {$$ = $1;yy.setClickEvent($3, $5, undefined);}
|
|
||||||
| CLICK SPACE alphaNum SPACE alphaNum SPACE STR {$$ = $1;yy.setClickEvent($3, $5, $7) ;}
|
|
||||||
| CLICK SPACE alphaNum SPACE STR {$$ = $1;yy.setLink($3, $5, undefined);}
|
|
||||||
| CLICK SPACE alphaNum SPACE STR SPACE STR {$$ = $1;yy.setLink($3, $5, $7 );}
|
|
||||||
;
|
|
||||||
|
|
||||||
styleStatement:STYLE SPACE alphaNum SPACE stylesOpt
|
|
||||||
{$$ = $1;yy.addVertex($3,undefined,undefined,$5);}
|
|
||||||
| STYLE SPACE HEX SPACE stylesOpt
|
|
||||||
{$$ = $1;yy.updateLink($3,$5);}
|
|
||||||
;
|
|
||||||
|
|
||||||
linkStyleStatement
|
|
||||||
: LINKSTYLE SPACE DEFAULT SPACE stylesOpt
|
|
||||||
{$$ = $1;yy.updateLink([$3],$5);}
|
|
||||||
| LINKSTYLE SPACE numList SPACE stylesOpt
|
|
||||||
{$$ = $1;yy.updateLink($3,$5);}
|
|
||||||
| LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
|
|
||||||
{$$ = $1;yy.updateLinkInterpolate([$3],$7);yy.updateLink([$3],$9);}
|
|
||||||
| LINKSTYLE SPACE numList SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
|
|
||||||
{$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);}
|
|
||||||
| LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum
|
|
||||||
{$$ = $1;yy.updateLinkInterpolate([$3],$7);}
|
|
||||||
| LINKSTYLE SPACE numList SPACE INTERPOLATE SPACE alphaNum
|
|
||||||
{$$ = $1;yy.updateLinkInterpolate($3,$7);}
|
|
||||||
;
|
|
||||||
|
|
||||||
commentStatement: PCT PCT commentText;
|
|
||||||
|
|
||||||
numList: NUM
|
|
||||||
{$$ = [$1]}
|
|
||||||
| numList COMMA NUM
|
|
||||||
{$1.push($3);$$ = $1;}
|
|
||||||
;
|
|
||||||
|
|
||||||
stylesOpt: style
|
|
||||||
{$$ = [$1]}
|
|
||||||
| stylesOpt COMMA style
|
|
||||||
{$1.push($3);$$ = $1;}
|
|
||||||
;
|
|
||||||
|
|
||||||
style: styleComponent
|
|
||||||
|style styleComponent
|
|
||||||
{$$ = $1 + $2;}
|
|
||||||
;
|
|
||||||
|
|
||||||
styleComponent: ALPHA | COLON | MINUS | NUM | UNIT | SPACE | HEX | BRKT | DOT | STYLE | PCT ;
|
|
||||||
|
|
||||||
/* Token lists */
|
|
||||||
|
|
||||||
commentToken : textToken | graphCodeTokens ;
|
|
||||||
|
|
||||||
textToken : textNoTagsToken | TAGSTART | TAGEND | '==' | '--' | PCT | DEFAULT;
|
|
||||||
|
|
||||||
textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ;
|
|
||||||
|
|
||||||
alphaNumToken : ALPHA | PUNCTUATION | UNICODE_TEXT | NUM | COLON | COMMA | PLUS | EQUALS | MULT | DOT | BRKT ;
|
|
||||||
|
|
||||||
graphCodeTokens: PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAG_START | TAG_END | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI ;
|
|
||||||
%%
|
|
53
packages/mermaid/src/diagrams/flowchart/types.ts
Normal file
53
packages/mermaid/src/diagrams/flowchart/types.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
export interface FlowVertex {
|
||||||
|
classes: string[];
|
||||||
|
dir?: string;
|
||||||
|
domId: string;
|
||||||
|
haveCallback?: boolean;
|
||||||
|
id: string;
|
||||||
|
labelType: 'text';
|
||||||
|
link?: string;
|
||||||
|
linkTarget?: string;
|
||||||
|
props?: any;
|
||||||
|
styles: string[];
|
||||||
|
text?: string;
|
||||||
|
type?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FlowText {
|
||||||
|
text: string;
|
||||||
|
type: 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FlowEdge {
|
||||||
|
start: string;
|
||||||
|
end: string;
|
||||||
|
interpolate?: string;
|
||||||
|
type?: string;
|
||||||
|
stroke?: string;
|
||||||
|
style?: string[];
|
||||||
|
length?: number;
|
||||||
|
text: string;
|
||||||
|
labelType: 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FlowClass {
|
||||||
|
id: string;
|
||||||
|
styles: string[];
|
||||||
|
textStyles: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FlowSubGraph {
|
||||||
|
classes: string[];
|
||||||
|
dir?: string;
|
||||||
|
id: string;
|
||||||
|
labelType: string;
|
||||||
|
nodes: string[];
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FlowLink {
|
||||||
|
length?: number;
|
||||||
|
stroke: string;
|
||||||
|
type: string;
|
||||||
|
text?: string;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user