mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-03 23:56:44 +02:00
Compare commits
61 Commits
develop_be
...
2979_arrow
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6ebfbb2f9e | ||
![]() |
320e105ffe | ||
![]() |
96cde8a15a | ||
![]() |
972d025578 | ||
![]() |
09bc7e0acd | ||
![]() |
693616b00d | ||
![]() |
30f6550e61 | ||
![]() |
5cfbc9102e | ||
![]() |
766bdde46b | ||
![]() |
f46f8752ca | ||
![]() |
bed9b1bb99 | ||
![]() |
053a20bd33 | ||
![]() |
be34e6145f | ||
![]() |
f60c7fff65 | ||
![]() |
80c68d847c | ||
![]() |
fed00be430 | ||
![]() |
ef527cb0fa | ||
![]() |
7da6c0e867 | ||
![]() |
0a0b6d51ba | ||
![]() |
982c1b4979 | ||
![]() |
a928120bec | ||
![]() |
ebdec77c88 | ||
![]() |
98ddc95648 | ||
![]() |
9566f51ca8 | ||
![]() |
493aac6885 | ||
![]() |
e0805b8272 | ||
![]() |
e72059ba87 | ||
![]() |
24d46fb936 | ||
![]() |
29c52ec4d4 | ||
![]() |
77831c424c | ||
![]() |
d633ec62df | ||
![]() |
69c13a6ecf | ||
![]() |
69d05c454d | ||
![]() |
97637da9e0 | ||
![]() |
535f555b13 | ||
![]() |
ddc35fa9ce | ||
![]() |
5daa130857 | ||
![]() |
c202b94a9a | ||
![]() |
ed0f22b037 | ||
![]() |
eb1c6894f5 | ||
![]() |
91091c614f | ||
![]() |
481b5cde0f | ||
![]() |
d328879329 | ||
![]() |
3c1bad1792 | ||
![]() |
9ec935f109 | ||
![]() |
4bedc49b4d | ||
![]() |
af2b1945a3 | ||
![]() |
c32e76a870 | ||
![]() |
8dcbe83b0b | ||
![]() |
9fac7866f5 | ||
![]() |
53bbf444e5 | ||
![]() |
913468a7b5 | ||
![]() |
ad49564ab5 | ||
![]() |
bf25be7cf0 | ||
![]() |
404b718677 | ||
![]() |
0e0a6c0f69 | ||
![]() |
cccbb6939c | ||
![]() |
db31f61368 | ||
![]() |
ffbae081ff | ||
![]() |
9b0d4a28ea | ||
![]() |
8dd82839cb |
24
.github/workflows/build.yml
vendored
24
.github/workflows/build.yml
vendored
@@ -20,26 +20,32 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: yarn
|
||||
cache: pnpm
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
pnpm install --frozen-lockfile
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
- name: Run Build
|
||||
run: yarn build
|
||||
run: pnpm run build
|
||||
|
||||
- name: Upload Build as Artifact
|
||||
- name: Upload Mermaid Build as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
name: mermaid-build
|
||||
path: packages/mermaid/dist
|
||||
|
||||
- name: Upload Mermaid Mindmap Build as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mermaid-mindmap-build
|
||||
path: packages/mermaid-mindmap/dist
|
||||
|
17
.github/workflows/e2e-applitools.yml
vendored
17
.github/workflows/e2e-applitools.yml
vendored
@@ -29,25 +29,24 @@ jobs:
|
||||
name: Warn if not using Applitools
|
||||
run: |
|
||||
echo "::error,title=Not using Applitols::APPLITOOLS_API_KEY is empty, disabling Applitools for this run."
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: yarn
|
||||
cache: pnpm
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
pnpm install --frozen-lockfile
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
- name: Run Build
|
||||
run: yarn build
|
||||
|
||||
- if: ${{ env.USE_APPLI }}
|
||||
name: Notify applitools of new batch
|
||||
# Copied from docs https://applitools.com/docs/topics/integrations/github-integration-ci-setup.html
|
||||
@@ -60,7 +59,7 @@ jobs:
|
||||
APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
|
||||
|
||||
- name: Run E2E Tests
|
||||
run: yarn e2e
|
||||
run: pnpm run e2e
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
# Mermaid applitools.config.js uses this to pick batch name.
|
||||
|
22
.github/workflows/e2e.yml
vendored
22
.github/workflows/e2e.yml
vendored
@@ -16,37 +16,31 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/cache@v3
|
||||
id: yarn-and-build-cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/Cypress
|
||||
build
|
||||
node_modules
|
||||
key: ${{ runner.os }}-node_modules-build-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node_modules-build-
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
# Need to skip setup if Cypress run is skipped, otherwise an error
|
||||
# is thrown since the pnpm cache step fails
|
||||
if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
|
||||
with:
|
||||
cache: yarn
|
||||
cache: pnpm
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
# Install NPM dependencies, cache them correctly
|
||||
# and run all Cypress tests
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v3
|
||||
uses: cypress-io/github-action@v4
|
||||
# If CYPRESS_RECORD_KEY is set, run in parallel on all containers
|
||||
# Otherwise (e.g. if running from fork), we run on a single container only
|
||||
if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
|
||||
with:
|
||||
start: yarn dev
|
||||
start: pnpm run dev
|
||||
wait-on: 'http://localhost:9000'
|
||||
# Disable recording if we don't have an API key
|
||||
# e.g. if this action was run from a fork
|
||||
record: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
|
||||
parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
|
||||
headless: true
|
||||
env:
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
|
14
.github/workflows/lint.yml
vendored
14
.github/workflows/lint.yml
vendored
@@ -20,23 +20,23 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: yarn
|
||||
cache: pnpm
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
pnpm install --frozen-lockfile
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
- name: Run Linting
|
||||
run: yarn lint
|
||||
run: pnpm run lint
|
||||
|
||||
- name: Verify Docs
|
||||
run: yarn docs:verify
|
||||
run: pnpm run docs:verify
|
||||
|
12
.github/workflows/test.yml
vendored
12
.github/workflows/test.yml
vendored
@@ -14,24 +14,24 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: yarn
|
||||
cache: pnpm
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
pnpm install --frozen-lockfile
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
- name: Run Unit Tests
|
||||
run: |
|
||||
yarn ci --coverage
|
||||
pnpm run ci --coverage
|
||||
|
||||
- name: Upload Coverage to Coveralls
|
||||
# it feels a bit weird to use @master, but that's what the docs use
|
||||
|
@@ -2,3 +2,5 @@ dist
|
||||
cypress/platform/xss3.html
|
||||
.cache
|
||||
coverage
|
||||
# Autogenerated by PNPM
|
||||
pnpm-lock.yaml
|
@@ -3,35 +3,67 @@ import { resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import jisonPlugin from './jisonPlugin.js';
|
||||
import pkg from '../package.json' assert { type: 'json' };
|
||||
type OutputOptions = Exclude<
|
||||
Exclude<InlineConfig['build'], undefined>['rollupOptions'],
|
||||
undefined
|
||||
>['output'];
|
||||
|
||||
const { dependencies } = pkg;
|
||||
const watch = process.argv.includes('--watch');
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
type OutputOptions = Exclude<
|
||||
Exclude<InlineConfig['build'], undefined>['rollupOptions'],
|
||||
undefined
|
||||
>['output'];
|
||||
|
||||
const packageOptions = {
|
||||
mermaid: {
|
||||
name: 'mermaid',
|
||||
packageName: 'mermaid',
|
||||
file: 'mermaid.ts',
|
||||
},
|
||||
'mermaid-mindmap': {
|
||||
name: 'mermaid-mindmap',
|
||||
packageName: 'mermaid-mindmap',
|
||||
file: 'add-diagram.ts',
|
||||
},
|
||||
'mermaid-mindmap-detector': {
|
||||
name: 'mermaid-mindmap-detector',
|
||||
packageName: 'mermaid-mindmap',
|
||||
file: 'registry.ts',
|
||||
},
|
||||
'mermaid-example-diagram': {
|
||||
name: 'mermaid-example-diagram',
|
||||
packageName: 'mermaid-example-diagram',
|
||||
file: 'add-diagram.ts',
|
||||
},
|
||||
'mermaid-example-diagram-detector': {
|
||||
name: 'mermaid-example-diagram-detector',
|
||||
packageName: 'mermaid-example-diagram',
|
||||
file: 'registry.ts',
|
||||
},
|
||||
};
|
||||
|
||||
interface BuildOptions {
|
||||
minify: boolean | 'esbuild';
|
||||
core?: boolean;
|
||||
watch?: boolean;
|
||||
entryName: keyof typeof packageOptions;
|
||||
}
|
||||
|
||||
export const getBuildConfig = ({ minify, core, watch }: BuildOptions): InlineConfig => {
|
||||
export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions): InlineConfig => {
|
||||
const external = ['require', 'fs', 'path'];
|
||||
console.log(entryName, packageOptions[entryName]);
|
||||
const { name, file, packageName } = packageOptions[entryName];
|
||||
let output: OutputOptions = [
|
||||
{
|
||||
name: 'mermaid',
|
||||
name,
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
entryFileNames: `[name].esm${minify ? '.min' : ''}.mjs`,
|
||||
entryFileNames: `${name}.esm${minify ? '.min' : ''}.mjs`,
|
||||
},
|
||||
{
|
||||
name: 'mermaid',
|
||||
name,
|
||||
format: 'umd',
|
||||
sourcemap: true,
|
||||
entryFileNames: `[name]${minify ? '.min' : ''}.js`,
|
||||
entryFileNames: `${name}${minify ? '.min' : ''}.js`,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -42,9 +74,10 @@ export const getBuildConfig = ({ minify, core, watch }: BuildOptions): InlineCon
|
||||
// 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: true,
|
||||
entryFileNames: `[name].core.mjs`,
|
||||
entryFileNames: `${name}.core.mjs`,
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -53,11 +86,12 @@ export const getBuildConfig = ({ minify, core, watch }: BuildOptions): InlineCon
|
||||
configFile: false,
|
||||
build: {
|
||||
emptyOutDir: false,
|
||||
outDir: resolve(__dirname, `../packages/${packageName}/dist`),
|
||||
lib: {
|
||||
entry: resolve(__dirname, '../src/mermaid.ts'),
|
||||
name: 'mermaid',
|
||||
entry: resolve(__dirname, `../packages/${packageName}/src/${file}`),
|
||||
name,
|
||||
// the proper extensions will be added
|
||||
fileName: 'mermaid',
|
||||
fileName: name,
|
||||
},
|
||||
minify,
|
||||
rollupOptions: {
|
||||
@@ -73,17 +107,36 @@ export const getBuildConfig = ({ minify, core, watch }: BuildOptions): InlineCon
|
||||
|
||||
if (watch && config.build) {
|
||||
config.build.watch = {
|
||||
include: 'src/**',
|
||||
include: [
|
||||
'packages/mermaid-mindmap/src/**',
|
||||
'packages/mermaid/src/**',
|
||||
'packages/mermaid-example-diagram/src/**',
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
||||
return Promise.allSettled([
|
||||
build(getBuildConfig({ minify: false, entryName })),
|
||||
build(getBuildConfig({ minify: 'esbuild', entryName })),
|
||||
build(getBuildConfig({ minify: false, core: true, entryName })),
|
||||
]);
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
||||
for (const pkg of packageNames) {
|
||||
await buildPackage(pkg);
|
||||
}
|
||||
};
|
||||
|
||||
if (watch) {
|
||||
build(getBuildConfig({ minify: false, watch }));
|
||||
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid' }));
|
||||
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
|
||||
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
|
||||
} else {
|
||||
build(getBuildConfig({ minify: false }));
|
||||
build(getBuildConfig({ minify: 'esbuild' }));
|
||||
build(getBuildConfig({ minify: false, core: true }));
|
||||
void main();
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ async function createServer() {
|
||||
});
|
||||
|
||||
app.use(vite.middlewares);
|
||||
app.use(express.static('dist'));
|
||||
app.use(express.static('./packages/mermaid/dist'));
|
||||
app.use(express.static('demos'));
|
||||
app.use(express.static('cypress/platform'));
|
||||
|
||||
|
17
README.md
17
README.md
@@ -1,5 +1,22 @@
|
||||
# mermaid [](https://travis-ci.org/mermaid-js/mermaid) [](https://www.npmjs.com/package/mermaid) [](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
|
||||
# Whoa, whats going on here?
|
||||
|
||||
We are transforming the Mermaid repository to a so called mono-repo. This is a part of the effort to decouple the diagrams from the core of mermaid. This will:
|
||||
|
||||
- Make it possible to select which diagrams to include on your site
|
||||
- Open up for lazy loading
|
||||
- Make it possible to add diagrams from outside of the Mermaid repository
|
||||
- Separate the release flow between different diagrams and the Mermaid core
|
||||
|
||||
As such be aware of sime changes..
|
||||
|
||||
# We use pnpm now
|
||||
|
||||
# The source code has moved
|
||||
|
||||
It is now localted in the src forunder for respoective package located as subfoders in packages.
|
||||
|
||||
English | [简体中文](./README.zh-CN.md)
|
||||
|
||||
<img src="./img/header.png" alt="" />
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import mermaid from '../../src/mermaid';
|
||||
import mermaid from '../../packages/mermaid/src/mermaid';
|
||||
|
||||
let code = `flowchart LR
|
||||
Power_Supply --> Transmitter_A
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- <meta charset="iso-8859-15"/> -->
|
||||
<script src="./viewer.js" type="module" />
|
||||
<script src="./viewer.js" type="module"></script>
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
||||
|
@@ -363,7 +363,9 @@ flowchart TD
|
||||
}
|
||||
</pre>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<!-- <script src="./mermaid.js"></script> -->
|
||||
<script src="./packages/mermaid-mindmap/dist/mermaid-mindmap.js"></script>
|
||||
<script src="./packages/mermaid/dist/mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
|
@@ -45,41 +45,37 @@
|
||||
</head>
|
||||
<body>
|
||||
<div>Security check</div>
|
||||
<div class="flex">
|
||||
<pre id="diagram" class="mermaid">
|
||||
flowchart TD
|
||||
A[myClass1] --> B[default] & C[default]
|
||||
B[default] & C[default] --> D[myClass2]
|
||||
classDef default stroke-width:2px,fill:none,stroke:silver
|
||||
classDef node color:red
|
||||
classDef myClass1 color:#0000ff
|
||||
classDef myClass2 stroke:#0000ff,fill:#ccccff
|
||||
class A myClass1
|
||||
class D myClass2
|
||||
</pre
|
||||
>
|
||||
<div id="res" class=""></div>
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<pre id="diagram" class="mermaid">
|
||||
info
|
||||
</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
mindmap
|
||||
root
|
||||
ch1
|
||||
ch2
|
||||
</pre
|
||||
>
|
||||
<script src="./packages/mermaid-mindmap/dist/mermaid-mindmap-detector.js"></script>
|
||||
<script src="./packages/mermaid-mindmap/dist/mermaid-example-diagram-detector.js"></script>
|
||||
<script src="./packages/mermaid/dist/mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
startOnLoad: true,
|
||||
logLevel: 0,
|
||||
basePath: './packages/',
|
||||
// themeVariables: {relationLabelColor: 'red'}
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
|
||||
// document.querySelector('#diagram').innerHTML = diagram;
|
||||
try {
|
||||
mermaid.initThrowsErrors(undefined, '#diagram');
|
||||
} catch (err) {
|
||||
console.log('Caught error:', err);
|
||||
}
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('In parse error:');
|
||||
console.error(err);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
82
cypress/platform/per.html
Normal file
82
cypress/platform/per.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<html>
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>
|
||||
body {
|
||||
/* background: rgb(221, 208, 208); */
|
||||
/* background:#333; */
|
||||
font-family: 'Arial';
|
||||
/* font-size: 18px !important; */
|
||||
}
|
||||
h1 {
|
||||
color: grey;
|
||||
}
|
||||
.mermaid2 {
|
||||
display: none;
|
||||
}
|
||||
.mermaid svg {
|
||||
/* font-size: 18px !important; */
|
||||
}
|
||||
.malware {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 150px;
|
||||
background: red;
|
||||
color: black;
|
||||
display: flex;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: monospace;
|
||||
font-size: 72px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>Security check</div>
|
||||
<pre id="diagram" class="mermaid">
|
||||
flowchart LR
|
||||
A-->B
|
||||
</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
mindmap
|
||||
root
|
||||
ch1
|
||||
ch2
|
||||
</pre
|
||||
>
|
||||
<script src="./packages/mermaid-mindmap/dist/mermaid-mindmap-detector.js"></script>
|
||||
<script src="./packages/mermaid-mindmap/dist/mermaid-example-diagram-detector.js"></script>
|
||||
<script src="./packages/mermaid/dist/mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
startOnLoad: true,
|
||||
logLevel: 0,
|
||||
basePath: './packages/',
|
||||
// themeVariables: {relationLabelColor: 'red'}
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('In parse error:');
|
||||
console.error(err);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,4 +1,4 @@
|
||||
import mermaid2 from '../../src/mermaid';
|
||||
import mermaid2 from '../../packages/mermaid/src/mermaid';
|
||||
|
||||
function b64ToUtf8(str) {
|
||||
return decodeURIComponent(escape(window.atob(str)));
|
||||
|
@@ -15,31 +15,47 @@
|
||||
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
erDiagram
|
||||
title: This is a title
|
||||
accDescription_ Test a description
|
||||
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
|
||||
erDiagram
|
||||
%% title This is a title
|
||||
%% accDescription Test a description
|
||||
|
||||
DELIVERY-ADDRESS {
|
||||
int customerId
|
||||
string addressLine1
|
||||
string addressLine2
|
||||
string city
|
||||
string county
|
||||
string state
|
||||
string region
|
||||
string country
|
||||
string postalCode
|
||||
}
|
||||
"Person . CUSTOMER"||--o{ ORDER : places
|
||||
|
||||
ORDER ||--|{ "€£LINE_ITEM ¥" : contains
|
||||
|
||||
"Person . CUSTOMER" }|..|{ "Address//StreetAddress::[DELIVERY ADDRESS]" : uses
|
||||
|
||||
"Address//StreetAddress::[DELIVERY ADDRESS]" {
|
||||
int customerID FK
|
||||
string line1 "this is the first address line comment"
|
||||
string line2
|
||||
string city
|
||||
string region
|
||||
string state
|
||||
string postal_code
|
||||
string country
|
||||
}
|
||||
|
||||
"a_~`!@#$^&*()-_=+[]{}|/;:'.?¡⁄™€£‹¢›∞fi§‡•°ª·º‚≠±œŒ∑„®†ˇ¥Á¨ˆˆØπ∏“«»åÅßÍ∂΃ϩ˙Ó∆Ô˚¬Ò…ÚæÆΩ¸≈π˛çÇ√◊∫ı˜µÂ≤¯≥˘÷¿" {
|
||||
string name "this is an entity with an absurd name just to show characters that are now acceptable as long as the name is in double quotes"
|
||||
}
|
||||
|
||||
"€£LINE_ITEM ¥" {
|
||||
int orderID FK
|
||||
int currencyId FK
|
||||
number price
|
||||
number quantity
|
||||
number adjustment
|
||||
number final_price
|
||||
}
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from '../src/mermaid';
|
||||
mermaid.initialize({
|
||||
theme: 'base',
|
||||
theme: 'default',
|
||||
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
|
38
package.json
38
package.json
@@ -1,11 +1,13 @@
|
||||
{
|
||||
"name": "mermaid",
|
||||
"name": "mermaid-monorepo",
|
||||
"private": true,
|
||||
"version": "9.2.0-rc2",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid.core.mjs",
|
||||
"module": "dist/mermaid.core.mjs",
|
||||
"types": "dist/mermaid.d.ts",
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@7.12.2",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/mermaid.min.js",
|
||||
@@ -26,25 +28,25 @@
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build:vite": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts",
|
||||
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
|
||||
"build:watch": "yarn build:code --watch",
|
||||
"build": "yarn clean; concurrently \"yarn build:vite\" \"yarn build:types\"",
|
||||
"dev": "concurrently \"yarn build:vite --watch\" \"ts-node-esm .vite/server\"",
|
||||
"docs:build": "ts-node-esm --transpileOnly src/docs.mts",
|
||||
"docs:verify": "yarn docs:build --verify",
|
||||
"postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md",
|
||||
"release": "yarn build",
|
||||
"lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .",
|
||||
"build:types": "concurrently \"tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly\" \"tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly\"",
|
||||
"build:watch": "pnpm build:vite --watch",
|
||||
"build": "pnpm clean; concurrently \"pnpm build:vite\" \"pnpm build:types\"",
|
||||
"dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server\"",
|
||||
"docs:build": "ts-node-esm --transpileOnly packages/mermaid/src/docs.mts",
|
||||
"docs:verify": "pnpm docs:build --verify",
|
||||
"todo-postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md",
|
||||
"release": "pnpm build",
|
||||
"lint": "eslint --cache --ignore-path .gitignore . && pnpm lint:jison && prettier --check .",
|
||||
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
|
||||
"lint:jison": "ts-node-esm --transpileOnly src/jison/lint.mts",
|
||||
"lint:jison": "ts-node-esm --transpileOnly packages/mermaid/src/jison/lint.mts",
|
||||
"cypress": "cypress run",
|
||||
"cypress:open": "cypress open",
|
||||
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
|
||||
"ci": "vitest run",
|
||||
"test": "yarn lint && vitest run",
|
||||
"test": "pnpm lint && vitest run",
|
||||
"test:watch": "vitest --coverage --watch",
|
||||
"prepublishOnly": "yarn build && yarn test",
|
||||
"prepare": "concurrently \"husky install\" \"yarn build\"",
|
||||
"prepublishOnly": "pnpm build && pnpm test",
|
||||
"todo-prepare": "concurrently \"husky install\" \"pnpm build\"",
|
||||
"pre-commit": "lint-staged"
|
||||
},
|
||||
"repository": {
|
||||
@@ -65,6 +67,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.0",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/node": "^18.7.21",
|
||||
"d3": "^7.0.0",
|
||||
"dagre": "^0.8.5",
|
||||
"dagre-d3": "^0.6.4",
|
||||
@@ -75,7 +79,9 @@
|
||||
"lodash": "^4.17.21",
|
||||
"moment-mini": "^2.24.0",
|
||||
"non-layered-tidy-tree-layout": "^2.0.2",
|
||||
"stylis": "^4.1.2"
|
||||
"rollup": "^2.79.1",
|
||||
"stylis": "^4.1.2",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-cypress": "^3.25.7",
|
||||
@@ -110,6 +116,7 @@
|
||||
"globby": "^13.1.2",
|
||||
"husky": "^8.0.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "29.x",
|
||||
"jison": "^0.4.18",
|
||||
"jsdom": "^20.0.0",
|
||||
"lint-staged": "^13.0.0",
|
||||
@@ -119,7 +126,6 @@
|
||||
"prettier-plugin-jsdoc": "^0.4.2",
|
||||
"remark": "^14.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.79.1",
|
||||
"start-server-and-test": "^1.12.6",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.3",
|
||||
|
70
packages/mermaid-example-diagram/package.json
Normal file
70
packages/mermaid-example-diagram/package.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"name": "@mermaid-js/mermaid-example-diagram",
|
||||
"version": "9.2.0-rc2",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid-mindmap.core.mjs",
|
||||
"module": "dist/mermaid-mindmap.core.mjs",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/mermaid-example-diagram.min.js",
|
||||
"import": "./dist/mermaid-example-diagram.core.mjs"
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
"keywords": [
|
||||
"diagram",
|
||||
"markdown",
|
||||
"mindmap",
|
||||
"mermaid"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
|
||||
"build:watch": "yarn build:code --watch",
|
||||
"build:esbuild": "concurrently \"yarn build:code\" \"yarn build:types\"",
|
||||
"build": "yarn clean; yarn build:esbuild",
|
||||
"dev": "node .esbuild/serve.cjs",
|
||||
"release": "yarn build",
|
||||
"lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .",
|
||||
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
|
||||
"lint:jison": "ts-node-esm src/jison/lint.mts",
|
||||
"ci": "vitest run",
|
||||
"test": "yarn lint && vitest run",
|
||||
"test:watch": "vitest --coverage --watch",
|
||||
"todo-prepublishOnly": "yarn build && yarn test",
|
||||
"todo-prepare": "concurrently \"husky install ../../.husky\" \"yarn build\"",
|
||||
"todo-pre-commit": "lint-staged"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mermaid-js/mermaid"
|
||||
},
|
||||
"author": "Knut Sveidqvist",
|
||||
"license": "MIT",
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"**/parser/*.js",
|
||||
"dist/**/*.js",
|
||||
"cypress/**/*.js"
|
||||
],
|
||||
"globals": [
|
||||
"page"
|
||||
]
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"concurrently": "^7.4.0",
|
||||
"rimraf": "^3.0.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"d3": "^7.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"sideEffects": [
|
||||
"**/*.css",
|
||||
"**/*.scss"
|
||||
]
|
||||
}
|
17
packages/mermaid-example-diagram/src/add-diagram.ts
Normal file
17
packages/mermaid-example-diagram/src/add-diagram.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/exampleDiagram';
|
||||
import * as db from './exampleDiagramDb';
|
||||
import renderer from './exampleDiagramRenderer';
|
||||
import styles from './styles';
|
||||
import { injectUtils } from './mermaidUtils';
|
||||
|
||||
window.mermaid.connectDiagram(
|
||||
'example-diagram',
|
||||
{
|
||||
db,
|
||||
renderer,
|
||||
parser,
|
||||
styles,
|
||||
},
|
||||
injectUtils
|
||||
);
|
3
packages/mermaid-example-diagram/src/exampleDetector.ts
Normal file
3
packages/mermaid-example-diagram/src/exampleDetector.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const detector = (txt: string) => {
|
||||
return txt.match(/^\s*example-diagram/) !== null;
|
||||
};
|
16
packages/mermaid-example-diagram/src/exampleDiagram.spec.js
Normal file
16
packages/mermaid-example-diagram/src/exampleDiagram.spec.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { parser } from './parser/exampleDiagram';
|
||||
import db from './exampleDiagramDb';
|
||||
describe('when parsing an info graph it', function () {
|
||||
let ex;
|
||||
beforeEach(function () {
|
||||
ex = parser;
|
||||
ex.yy = db;
|
||||
});
|
||||
|
||||
it('should handle an info definition', function () {
|
||||
let str = `info
|
||||
showInfo`;
|
||||
|
||||
ex.parse(str);
|
||||
});
|
||||
});
|
33
packages/mermaid-example-diagram/src/exampleDiagramDb.js
Normal file
33
packages/mermaid-example-diagram/src/exampleDiagramDb.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/** Created by knut on 15-01-14. */
|
||||
import { log } from './mermaidUtils';
|
||||
|
||||
var message = '';
|
||||
var info = false;
|
||||
|
||||
export const setMessage = (txt) => {
|
||||
log.debug('Setting message to: ' + txt);
|
||||
message = txt;
|
||||
};
|
||||
|
||||
export const getMessage = () => {
|
||||
return message;
|
||||
};
|
||||
|
||||
export const setInfo = (inf) => {
|
||||
info = inf;
|
||||
};
|
||||
|
||||
export const getInfo = () => {
|
||||
return info;
|
||||
};
|
||||
|
||||
export default {
|
||||
setMessage,
|
||||
getMessage,
|
||||
setInfo,
|
||||
getInfo,
|
||||
clear: () => {
|
||||
message = '';
|
||||
info = false;
|
||||
},
|
||||
};
|
@@ -0,0 +1,55 @@
|
||||
/** Created by knut on 14-12-11. */
|
||||
import { select } from 'd3';
|
||||
import { log, getConfig } from './mermaidUtils';
|
||||
|
||||
/**
|
||||
* Draws a an info picture in the tag with id: id based on the graph definition in text.
|
||||
*
|
||||
* @param {any} text
|
||||
* @param {any} id
|
||||
* @param {any} version
|
||||
* @param diagObj
|
||||
*/
|
||||
export const draw = (text, id, version, diagObj) => {
|
||||
try {
|
||||
log.debug('Rendering info diagram\n' + text);
|
||||
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and Document for when rendering in sanbox mode
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
|
||||
// Parse the graph definition
|
||||
// parser.parse(text);
|
||||
// log.debug('Parsed info diagram');
|
||||
// Fetch the default direction, use TD if none was found
|
||||
const svg = root.select('#' + id);
|
||||
|
||||
const g = svg.append('g');
|
||||
|
||||
g.append('text') // text label for the x axis
|
||||
.attr('x', 100)
|
||||
.attr('y', 40)
|
||||
.attr('class', 'version')
|
||||
.attr('font-size', '32px')
|
||||
.style('text-anchor', 'middle')
|
||||
.text('v ' + version);
|
||||
|
||||
svg.attr('height', 100);
|
||||
svg.attr('width', 400);
|
||||
// svg.attr('viewBox', '0 0 300 150');
|
||||
} catch (e) {
|
||||
log.error('Error while rendering info diagram');
|
||||
log.error(e.message);
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
draw,
|
||||
};
|
63
packages/mermaid-example-diagram/src/mermaidUtils.ts
Normal file
63
packages/mermaid-example-diagram/src/mermaidUtils.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
const warning = () => null;
|
||||
|
||||
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
||||
|
||||
export const LEVELS: Record<LogLevel, number> = {
|
||||
trace: 0,
|
||||
debug: 1,
|
||||
info: 2,
|
||||
warn: 3,
|
||||
error: 4,
|
||||
fatal: 5,
|
||||
};
|
||||
|
||||
export const log: Record<keyof typeof LEVELS, typeof console.log> = {
|
||||
trace: warning,
|
||||
debug: warning,
|
||||
info: warning,
|
||||
warn: warning,
|
||||
error: warning,
|
||||
fatal: warning,
|
||||
};
|
||||
|
||||
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
|
||||
export let getConfig: () => object;
|
||||
export let sanitizeText: (str: string) => string;
|
||||
/**
|
||||
* Placeholder for the real function that will be injected by mermaid.
|
||||
*/
|
||||
// eslint-disable @typescript-eslint/no-explicit-any
|
||||
export let setupGraphViewbox: (
|
||||
graph: any,
|
||||
svgElem: any,
|
||||
padding: any,
|
||||
useMaxWidth: boolean
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Function called by mermaid that injects utility functions that help the diagram to be a good citizen.
|
||||
* @param _log
|
||||
* @param _setLogLevel
|
||||
* @param _getConfig
|
||||
* @param _sanitizeText
|
||||
* @param _setupGraphViewbox
|
||||
*/
|
||||
export const injectUtils = (
|
||||
_log: Record<keyof typeof LEVELS, typeof console.log>,
|
||||
_setLogLevel: any,
|
||||
_getConfig: any,
|
||||
_sanitizeText: any,
|
||||
_setupGraphViewbox: any
|
||||
) => {
|
||||
_log.debug('Mermaid utils injected into example-diagram');
|
||||
log.trace = _log.trace;
|
||||
log.debug = _log.debug;
|
||||
log.info = _log.info;
|
||||
log.warn = _log.warn;
|
||||
log.error = _log.error;
|
||||
log.fatal = _log.fatal;
|
||||
setLogLevel = _setLogLevel;
|
||||
getConfig = _getConfig;
|
||||
sanitizeText = _sanitizeText;
|
||||
setupGraphViewbox = _setupGraphViewbox;
|
||||
};
|
@@ -0,0 +1,43 @@
|
||||
%lex
|
||||
|
||||
%options case-insensitive
|
||||
|
||||
%{
|
||||
// Pre-lexer code can go here
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
"info" return 'info' ;
|
||||
[\s\n\r]+ return 'NL' ;
|
||||
[\s]+ return 'space';
|
||||
"showInfo" return 'showInfo';
|
||||
<<EOF>> return 'EOF' ;
|
||||
. return 'TXT' ;
|
||||
|
||||
/lex
|
||||
|
||||
%start start
|
||||
|
||||
%% /* language grammar */
|
||||
|
||||
start
|
||||
// %{ : info document 'EOF' { return yy; } }
|
||||
: info document 'EOF' { return yy; }
|
||||
;
|
||||
|
||||
document
|
||||
: /* empty */
|
||||
| document line
|
||||
;
|
||||
|
||||
line
|
||||
: statement { }
|
||||
| 'NL'
|
||||
;
|
||||
|
||||
statement
|
||||
: showInfo { yy.setInfo(true); }
|
||||
;
|
||||
|
||||
%%
|
33
packages/mermaid-example-diagram/src/registry.ts
Normal file
33
packages/mermaid-example-diagram/src/registry.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import { detector } from './exampleDetector';
|
||||
|
||||
const scriptElement = document.currentScript as HTMLScriptElement;
|
||||
const path = scriptElement.src;
|
||||
const lastSlash = path.lastIndexOf('/');
|
||||
const baseFolder = lastSlash < 0 ? path : path.substring(0, lastSlash + 1);
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
if (window.mermaid && typeof window.mermaid.detectors === 'object') {
|
||||
window.mermaid.detectors.push({ id: 'example-diagram', detector });
|
||||
} else {
|
||||
window.mermaid = {};
|
||||
window.mermaid.detectors = [{ id: 'example-diagram', detector }];
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for document loaded before starting the execution.
|
||||
*/
|
||||
window.addEventListener(
|
||||
'load',
|
||||
() => {
|
||||
if (window.mermaid && typeof window.mermaid.detectors === 'object') {
|
||||
window.mermaid.detectors.push({
|
||||
id: 'example-diagram',
|
||||
detector,
|
||||
path: baseFolder,
|
||||
});
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
7
packages/mermaid-example-diagram/src/types/index.d.ts
vendored
Normal file
7
packages/mermaid-example-diagram/src/types/index.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
mermaid: any; // 👈️ turn off type checking
|
||||
}
|
||||
}
|
9
packages/mermaid-example-diagram/tsconfig.json
Normal file
9
packages/mermaid-example-diagram/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["./src/**/*.ts"],
|
||||
"typeRoots": ["./src/types"]
|
||||
}
|
75
packages/mermaid-mindmap/package.json
Normal file
75
packages/mermaid-mindmap/package.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "@mermaid-js/mermaid-mindmap",
|
||||
"version": "9.2.0-rc2",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid-mindmap.core.mjs",
|
||||
"module": "dist/mermaid-mindmap.core.mjs",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/mermaid-mindmap.min.js",
|
||||
"import": "./dist/mermaid-mindmap.core.mjs"
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
"keywords": [
|
||||
"diagram",
|
||||
"markdown",
|
||||
"mindmap",
|
||||
"mermaid"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
|
||||
"build:watch": "yarn build:code --watch",
|
||||
"build:esbuild": "concurrently \"yarn build:code\" \"yarn build:types\"",
|
||||
"build": "yarn clean; yarn build:esbuild",
|
||||
"dev": "node .esbuild/serve.cjs",
|
||||
"release": "yarn build",
|
||||
"lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .",
|
||||
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
|
||||
"lint:jison": "ts-node-esm src/jison/lint.mts",
|
||||
"ci": "vitest run",
|
||||
"test": "yarn lint && vitest run",
|
||||
"test:watch": "vitest --coverage --watch",
|
||||
"todo-prepublishOnly": "yarn build && yarn test",
|
||||
"todo-prepare": "concurrently \"husky install ../../.husky\" \"yarn build\"",
|
||||
"todo-pre-commit": "lint-staged"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mermaid-js/mermaid"
|
||||
},
|
||||
"author": "Knut Sveidqvist",
|
||||
"license": "MIT",
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"**/parser/*.js",
|
||||
"dist/**/*.js",
|
||||
"cypress/**/*.js"
|
||||
],
|
||||
"globals": [
|
||||
"page"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.0",
|
||||
"d3": "^7.0.0",
|
||||
"mermaid": "workspace:*",
|
||||
"non-layered-tidy-tree-layout": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^7.4.0",
|
||||
"rimraf": "^3.0.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"d3": "^7.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"sideEffects": [
|
||||
"**/*.css",
|
||||
"**/*.scss"
|
||||
]
|
||||
}
|
23
packages/mermaid-mindmap/src/add-diagram.ts
Normal file
23
packages/mermaid-mindmap/src/add-diagram.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import mindmapParser from './parser/mindmap';
|
||||
import * as mindmapDb from './mindmapDb';
|
||||
import mindmapRenderer from './mindmapRenderer';
|
||||
import mindmapStyles from './styles';
|
||||
import { injectUtils } from './mermaidUtils';
|
||||
|
||||
// const getBaseFolder = (path: string) => {
|
||||
// const parts = path.split('/');
|
||||
// parts.pop();
|
||||
// return parts.join('/');
|
||||
// };
|
||||
|
||||
window.mermaid.connectDiagram(
|
||||
'mindmap',
|
||||
{
|
||||
db: mindmapDb,
|
||||
renderer: mindmapRenderer,
|
||||
parser: mindmapParser,
|
||||
styles: mindmapStyles,
|
||||
},
|
||||
injectUtils
|
||||
);
|
81
packages/mermaid-mindmap/src/mermaidUtils.ts
Normal file
81
packages/mermaid-mindmap/src/mermaidUtils.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
const warning = (s: string) => {
|
||||
// Todo remove debug code
|
||||
console.error('Log function was called before initialization', s); // eslint-disable-line
|
||||
};
|
||||
|
||||
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
||||
|
||||
export const LEVELS: Record<LogLevel, number> = {
|
||||
trace: 0,
|
||||
debug: 1,
|
||||
info: 2,
|
||||
warn: 3,
|
||||
error: 4,
|
||||
fatal: 5,
|
||||
};
|
||||
|
||||
export const log: Record<keyof typeof LEVELS, typeof console.log> = {
|
||||
trace: warning,
|
||||
debug: warning,
|
||||
info: warning,
|
||||
warn: warning,
|
||||
error: warning,
|
||||
fatal: warning,
|
||||
};
|
||||
|
||||
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
|
||||
export let getConfig: () => object;
|
||||
export let sanitizeText: (str: string) => string;
|
||||
// eslint-disable @typescript-eslint/no-explicit-any
|
||||
export let setupGraphViewbox: (
|
||||
graph: any,
|
||||
svgElem: any,
|
||||
padding: any,
|
||||
useMaxWidth: boolean
|
||||
) => void;
|
||||
|
||||
export const injectUtils = (
|
||||
_log: Record<keyof typeof LEVELS, typeof console.log>,
|
||||
_setLogLevel: any,
|
||||
_getConfig: any,
|
||||
_sanitizeText: any,
|
||||
_setupGraphViewbox: any
|
||||
) => {
|
||||
_log.info('Mermaid utils injected');
|
||||
log.trace = _log.trace;
|
||||
log.debug = _log.debug;
|
||||
log.info = _log.info;
|
||||
log.warn = _log.warn;
|
||||
log.error = _log.error;
|
||||
log.fatal = _log.fatal;
|
||||
setLogLevel = _setLogLevel;
|
||||
getConfig = _getConfig;
|
||||
sanitizeText = _sanitizeText;
|
||||
setupGraphViewbox = _setupGraphViewbox;
|
||||
};
|
||||
|
||||
/*
|
||||
const warning = (..._args: any[]) => {
|
||||
console.error('Log function was called before initialization');
|
||||
};
|
||||
|
||||
export let log = {
|
||||
trace: warning,
|
||||
debug: warning,
|
||||
info: warning,
|
||||
warn: warning,
|
||||
error: warning,
|
||||
fatal: warning,
|
||||
};
|
||||
export let setLogLevel;
|
||||
export let getConfig;
|
||||
export let sanitizeText;
|
||||
export let setupGraphViewbox;
|
||||
export const injectUtils = (_log, _setLogLevel, _getConfig, _sanitizeText, _setupGraphViewbox) => {
|
||||
log = _log;
|
||||
setLogLevel = _setLogLevel;
|
||||
getConfig = _getConfig;
|
||||
sanitizeText = _sanitizeText;
|
||||
setupGraphViewbox = _setupGraphViewbox;
|
||||
};
|
||||
*/
|
@@ -1,6 +1,16 @@
|
||||
import { parser as mindmap } from './parser/mindmap';
|
||||
import * as mindmapDB from './mindmapDb';
|
||||
import { setLogLevel } from '../../diagram-api/diagramAPI';
|
||||
import { injectUtils } from './mermaidUtils';
|
||||
// Todo fix utils functions for tests
|
||||
import {
|
||||
log,
|
||||
setLogLevel,
|
||||
getConfig,
|
||||
sanitizeText,
|
||||
setupGraphViewBox,
|
||||
} from '../../mermaid/src/diagram-api/diagramAPI';
|
||||
|
||||
injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewBox);
|
||||
|
||||
describe('when parsing a mindmap ', function () {
|
||||
beforeEach(function () {
|
@@ -1,5 +1,5 @@
|
||||
/** Created by knut on 15-01-14. */
|
||||
import { sanitizeText, getConfig, log as _log } from '../../diagram-api/diagramAPI';
|
||||
import { sanitizeText, getConfig, log } from './mermaidUtils';
|
||||
|
||||
let nodes = [];
|
||||
let cnt = 0;
|
||||
@@ -131,8 +131,19 @@ export const type2Str = (type) => {
|
||||
return 'no-border';
|
||||
}
|
||||
};
|
||||
|
||||
export let parseError; // = (str, hash)
|
||||
// => {
|
||||
// const error = { str, hash };
|
||||
// throw error;
|
||||
// };
|
||||
export const setErrorHandler = (handler) => {
|
||||
parseError = handler;
|
||||
};
|
||||
|
||||
// Expose logger to grammar
|
||||
export const log = _log;
|
||||
export const getLogger = () => log;
|
||||
|
||||
export const getNodeById = (id) => nodes[id];
|
||||
export const getElementById = (id) => elements[id];
|
||||
// export default {
|
3
packages/mermaid-mindmap/src/mindmapDetector.ts
Normal file
3
packages/mermaid-mindmap/src/mindmapDetector.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const mindmapDetector = (txt: string) => {
|
||||
return txt.match(/^\s*mindmap/) !== null;
|
||||
};
|
@@ -1,6 +1,6 @@
|
||||
/** Created by knut on 14-12-11. */
|
||||
import { select } from 'd3';
|
||||
import { log, getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI';
|
||||
import { log, getConfig, setupGraphViewbox } from './mermaidUtils';
|
||||
import svgDraw from './svgDraw';
|
||||
import { BoundingBox, Layout } from 'non-layered-tidy-tree-layout';
|
||||
import clone from 'fast-clone';
|
||||
@@ -215,51 +215,53 @@ function positionNodes(node, conf) {
|
||||
* @param {any} version
|
||||
* @param diagObj
|
||||
*/
|
||||
|
||||
export const draw = (text, id, version, diagObj) => {
|
||||
const conf = getConfig();
|
||||
try {
|
||||
log.debug('Renering info diagram\n' + text);
|
||||
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and Document for when rendering in sanbox mode
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
// Parse the graph definition
|
||||
// This is done only for throwing the error if the text is not valid.
|
||||
diagObj.db.clear();
|
||||
// Parse the graph definition
|
||||
diagObj.parser.parse(text);
|
||||
|
||||
const svg = root.select('#' + id);
|
||||
log.debug('Renering info diagram\n' + text);
|
||||
|
||||
svg.append('g');
|
||||
const mm = diagObj.db.getMindmap();
|
||||
|
||||
// Draw the graph and start with drawing the nodes without proper position
|
||||
// this gives us the size of the nodes and we can set the positions later
|
||||
|
||||
const edgesElem = svg.append('g');
|
||||
edgesElem.attr('class', 'mindmap-edges');
|
||||
const nodesElem = svg.append('g');
|
||||
nodesElem.attr('class', 'mindmap-nodes');
|
||||
drawNodes(nodesElem, mm, -1, conf);
|
||||
|
||||
// Next step is to layout the mindmap, giving each node a position
|
||||
|
||||
const positionedMindmap = layoutMindmap(mm, conf);
|
||||
|
||||
// After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf);
|
||||
positionNodes(positionedMindmap, conf);
|
||||
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
|
||||
} catch (e) {
|
||||
log.error('Error while rendering info diagram');
|
||||
log.error(e.message);
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and Document for when rendering in sanbox mode
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
// Parse the graph definition
|
||||
|
||||
const svg = root.select('#' + id);
|
||||
|
||||
svg.append('g');
|
||||
const mm = diagObj.db.getMindmap();
|
||||
|
||||
// Draw the graph and start with drawing the nodes without proper position
|
||||
// this gives us the size of the nodes and we can set the positions later
|
||||
|
||||
const edgesElem = svg.append('g');
|
||||
edgesElem.attr('class', 'mindmap-edges');
|
||||
const nodesElem = svg.append('g');
|
||||
nodesElem.attr('class', 'mindmap-nodes');
|
||||
drawNodes(nodesElem, mm, -1, conf);
|
||||
|
||||
// Next step is to layout the mindmap, giving each node a position
|
||||
|
||||
const positionedMindmap = layoutMindmap(mm, conf);
|
||||
|
||||
// After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf);
|
||||
positionNodes(positionedMindmap, conf);
|
||||
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
|
||||
};
|
||||
|
||||
export default {
|
108
packages/mermaid-mindmap/src/parser/mindmap.jison
Normal file
108
packages/mermaid-mindmap/src/parser/mindmap.jison
Normal file
@@ -0,0 +1,108 @@
|
||||
/** mermaid
|
||||
* https://knsv.github.io/mermaid
|
||||
* (c) 2015 Knut Sveidqvist
|
||||
* MIT license.
|
||||
*/
|
||||
%lex
|
||||
|
||||
%options case-insensitive
|
||||
|
||||
%{
|
||||
// Pre-lexer code can go here
|
||||
%}
|
||||
%x NODE
|
||||
%x NSTR
|
||||
%x ICON
|
||||
%x CLASS
|
||||
|
||||
%%
|
||||
|
||||
\s*\%\%.* {yy.getLogger().trace('Found comment',yytext);}
|
||||
// \%\%[^\n]*\n /* skip comments */
|
||||
"mindmap" return 'MINDMAP';
|
||||
":::" { this.begin('CLASS'); }
|
||||
<CLASS>.+ { this.popState();return 'CLASS'; }
|
||||
<CLASS>\n { this.popState();}
|
||||
// [\s]*"::icon(" { this.begin('ICON'); }
|
||||
"::icon(" { yy.getLogger().trace('Begin icon');this.begin('ICON'); }
|
||||
[\n]+ return 'NL';
|
||||
<ICON>[^\)]+ { return 'ICON'; }
|
||||
<ICON>\) {yy.getLogger().trace('end icon');this.popState();}
|
||||
"-)" { yy.getLogger().trace('Exploding node'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"(-" { yy.getLogger().trace('Cloud'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"))" { yy.getLogger().trace('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
")" { yy.getLogger().trace('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"((" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"(" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"[" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
[\s]+ return 'SPACELIST' /* skip all whitespace */ ;
|
||||
// !(-\() return 'NODE_ID';
|
||||
[^\(\[\n\-\)]+ return 'NODE_ID';
|
||||
<<EOF>> return 'EOF';
|
||||
<NODE>["] { yy.getLogger().trace('Starting NSTR');this.begin("NSTR");}
|
||||
<NSTR>[^"]+ { yy.getLogger().trace('description:', yytext); return "NODE_DESCR";}
|
||||
<NSTR>["] {this.popState();}
|
||||
<NODE>[\)]\) {this.popState();yy.getLogger().trace('node end ))');return "NODE_DEND";}
|
||||
<NODE>[\)] {this.popState();yy.getLogger().trace('node end )');return "NODE_DEND";}
|
||||
<NODE>[\]] {this.popState();yy.getLogger().trace('node end ...',yytext);return "NODE_DEND";}
|
||||
<NODE>"(-" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";}
|
||||
<NODE>"-)" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";}
|
||||
<NODE>"((" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
|
||||
<NODE>"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
|
||||
<NODE>[^\)\]\(]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';}
|
||||
<NODE>.+(?!\(\() { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';}
|
||||
// [\[] return 'NODE_START';
|
||||
// .+ return 'TXT' ;
|
||||
|
||||
/lex
|
||||
|
||||
%start start
|
||||
|
||||
%% /* language grammar */
|
||||
|
||||
start
|
||||
// %{ : info document 'EOF' { return yy; } }
|
||||
: MINDMAP document { return yy; }
|
||||
| MINDMAP NL document { return yy; }
|
||||
| SPACELIST MINDMAP document { return yy; }
|
||||
;
|
||||
|
||||
stop
|
||||
: NL {yy.getLogger().trace('Stop NL ');}
|
||||
| EOF {yy.getLogger().trace('Stop EOF ');}
|
||||
| stop NL {yy.getLogger().trace('Stop NL2 ');}
|
||||
| stop EOF {yy.getLogger().trace('Stop EOF2 ');}
|
||||
;
|
||||
document
|
||||
: document statement stop
|
||||
| statement stop
|
||||
;
|
||||
|
||||
statement
|
||||
: SPACELIST node { yy.getLogger().trace('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); }
|
||||
| SPACELIST ICON { yy.getLogger().trace('Icon: ',$2);yy.decorateNode({icon: $2}); }
|
||||
| SPACELIST CLASS { yy.decorateNode({class: $2}); }
|
||||
| node { yy.getLogger().trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); }
|
||||
| ICON { yy.decorateNode({icon: $1}); }
|
||||
| CLASS { yy.decorateNode({class: $1}); }
|
||||
| SPACELIST
|
||||
;
|
||||
|
||||
|
||||
|
||||
node
|
||||
:nodeWithId
|
||||
|nodeWithoutId
|
||||
;
|
||||
|
||||
nodeWithoutId
|
||||
: NODE_DSTART NODE_DESCR NODE_DEND
|
||||
{ yy.getLogger().trace("node found ..", $1); $$ = { id: $2, descr: $2, type: yy.getType($1, $3) }; }
|
||||
;
|
||||
|
||||
nodeWithId
|
||||
: NODE_ID { $$ = { id: $1, descr: $1, type: yy.nodeType.DEFAULT }; }
|
||||
| NODE_ID NODE_DSTART NODE_DESCR NODE_DEND
|
||||
{ yy.getLogger().trace("node found ..", $1); $$ = { id: $1, descr: $3, type: yy.getType($2, $4) }; }
|
||||
;
|
||||
%%
|
41
packages/mermaid-mindmap/src/registry.ts
Normal file
41
packages/mermaid-mindmap/src/registry.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import { mindmapDetector } from './mindmapDetector';
|
||||
|
||||
// const getBaseFolder = () => {
|
||||
const scriptElement = document.currentScript as HTMLScriptElement;
|
||||
const path = scriptElement.src;
|
||||
const lastSlash = path.lastIndexOf('/');
|
||||
const baseFolder = lastSlash < 0 ? path : path.substring(0, lastSlash + 1);
|
||||
|
||||
// };
|
||||
|
||||
// console.log('Current script', getBaseFolder(scriptElement !== null ? scriptElement.src : '')); // eslint-disable-line no-console
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
if (window.mermaid && typeof window.mermaid.detectors === 'object') {
|
||||
window.mermaid.detectors.push({ id: 'mindmap', detector: mindmapDetector });
|
||||
} else {
|
||||
// console.error('window.mermaid.detectors was not found!'); // eslint-disable-line no-console
|
||||
window.mermaid = {};
|
||||
window.mermaid.detectors = [{ id: 'mindmap', detector: mindmapDetector }];
|
||||
// console.error('Detectors now:', window.mermaid.detectors); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
/*!
|
||||
* Wait for document loaded before starting the execution.
|
||||
*/
|
||||
window.addEventListener(
|
||||
'load',
|
||||
() => {
|
||||
if (window.mermaid && typeof window.mermaid.detectors === 'object') {
|
||||
window.mermaid.detectors.push({
|
||||
id: 'mindmap',
|
||||
detector: mindmapDetector,
|
||||
path: baseFolder,
|
||||
});
|
||||
// console.error(window.mermaid.detectors); // eslint-disable-line no-console
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
7
packages/mermaid-mindmap/src/types/index.d.ts
vendored
Normal file
7
packages/mermaid-mindmap/src/types/index.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
mermaid: any; // 👈️ turn off type checking
|
||||
}
|
||||
}
|
9
packages/mermaid-mindmap/tsconfig.json
Normal file
9
packages/mermaid-mindmap/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["./src/**/*.ts"],
|
||||
"typeRoots": ["./src/types"]
|
||||
}
|
141
packages/mermaid/package.json
Normal file
141
packages/mermaid/package.json
Normal file
@@ -0,0 +1,141 @@
|
||||
{
|
||||
"name": "mermaid",
|
||||
"version": "9.2.0-rc2",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "./dist/mermaid.core.mjs",
|
||||
"module": "./dist/mermaid.core.mjs",
|
||||
"types": "./dist/mermaid.d.ts",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/mermaid.min.js",
|
||||
"import": "./dist/mermaid.core.mjs",
|
||||
"types": "./dist/mermaid.d.ts"
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
"keywords": [
|
||||
"diagram",
|
||||
"markdown",
|
||||
"flowchart",
|
||||
"sequence diagram",
|
||||
"gantt",
|
||||
"class diagram",
|
||||
"git graph"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build:code": "node .esbuild/esbuild.cjs",
|
||||
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
|
||||
"build:watch": "yarn build:code --watch",
|
||||
"build:esbuild": "concurrently \"yarn build:code\" \"yarn build:types\"",
|
||||
"build": "yarn clean; yarn build:esbuild",
|
||||
"dev": "node .esbuild/serve.cjs",
|
||||
"docs:build": "ts-node-esm src/docs.mts",
|
||||
"docs:verify": "yarn docs:build --verify",
|
||||
"todo-postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md",
|
||||
"release": "yarn build",
|
||||
"lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .",
|
||||
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
|
||||
"lint:jison": "ts-node-esm src/jison/lint.mts",
|
||||
"cypress": "cypress run",
|
||||
"cypress:open": "cypress open",
|
||||
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
|
||||
"ci": "vitest run",
|
||||
"test": "yarn lint && vitest run",
|
||||
"test:watch": "vitest --coverage --watch",
|
||||
"prepublishOnly": "yarn build && yarn test",
|
||||
"todo-prepare": "concurrently \"husky install\" \"yarn build\"",
|
||||
"pre-commit": "lint-staged"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mermaid-js/mermaid"
|
||||
},
|
||||
"author": "Knut Sveidqvist",
|
||||
"license": "MIT",
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"**/parser/*.js",
|
||||
"dist/**/*.js",
|
||||
"cypress/**/*.js"
|
||||
],
|
||||
"globals": [
|
||||
"page"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.0",
|
||||
"d3": "^7.0.0",
|
||||
"dagre": "^0.8.5",
|
||||
"dagre-d3": "^0.6.4",
|
||||
"dompurify": "2.4.0",
|
||||
"fast-clone": "^1.5.13",
|
||||
"graphlib": "^2.1.8",
|
||||
"khroma": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"moment-mini": "^2.24.0",
|
||||
"non-layered-tidy-tree-layout": "^2.0.2",
|
||||
"stylis": "^4.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-cypress": "^3.25.7",
|
||||
"@commitlint/cli": "^17.1.2",
|
||||
"@commitlint/config-conventional": "^17.0.0",
|
||||
"@types/d3": "^7.4.0",
|
||||
"@types/dompurify": "^2.3.4",
|
||||
"@types/eslint": "^8.4.6",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/jsdom": "^20.0.0",
|
||||
"@types/lodash": "^4.14.185",
|
||||
"@types/prettier": "^2.7.0",
|
||||
"@types/stylis": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.37.0",
|
||||
"@typescript-eslint/parser": "^5.37.0",
|
||||
"@vitest/coverage-c8": "^0.23.2",
|
||||
"@vitest/ui": "^0.23.2",
|
||||
"concurrently": "^7.4.0",
|
||||
"coveralls": "^3.1.1",
|
||||
"cypress": "^10.0.0",
|
||||
"cypress-image-snapshot": "^4.0.1",
|
||||
"documentation": "13.2.0",
|
||||
"esbuild": "^0.15.8",
|
||||
"eslint": "^8.23.1",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-html": "^7.1.0",
|
||||
"eslint-plugin-jest": "^27.0.4",
|
||||
"eslint-plugin-jsdoc": "^39.3.6",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-markdown": "^3.0.0",
|
||||
"express": "^4.18.1",
|
||||
"globby": "^13.1.2",
|
||||
"husky": "^8.0.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jison": "^0.4.18",
|
||||
"js-base64": "3.7.2",
|
||||
"jsdom": "^20.0.0",
|
||||
"lint-staged": "^13.0.0",
|
||||
"moment": "^2.23.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-jsdoc": "^0.4.2",
|
||||
"remark": "^14.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"start-server-and-test": "^1.12.6",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.3",
|
||||
"unist-util-flatmap": "^1.0.0",
|
||||
"vitest": "^0.23.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"d3": "^7.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"sideEffects": [
|
||||
"**/*.css",
|
||||
"**/*.scss"
|
||||
]
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
import * as configApi from './config';
|
||||
import { log } from './logger';
|
||||
import { getDiagram } from './diagram-api/diagramAPI';
|
||||
import { detectType } from './diagram-api/detectType';
|
||||
import { getDiagram, loadDiagram } from './diagram-api/diagramAPI';
|
||||
import { detectType, getPathForDiagram } from './diagram-api/detectType';
|
||||
import { isDetailedError } from './utils';
|
||||
export class Diagram {
|
||||
type = 'graph';
|
||||
@@ -26,11 +26,7 @@ export class Diagram {
|
||||
log.debug('Initialized diagram ' + this.type, cnf);
|
||||
}
|
||||
this.txt += '\n';
|
||||
this.parser.parser.yy.graphType = this.type;
|
||||
this.parser.parser.yy.parseError = (str: string, hash: string) => {
|
||||
const error = { str, hash };
|
||||
throw error;
|
||||
};
|
||||
|
||||
this.parse(this.txt, parseError);
|
||||
}
|
||||
|
||||
@@ -71,3 +67,21 @@ export class Diagram {
|
||||
}
|
||||
|
||||
export default Diagram;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export const getDiagramFromText = async (txt: string, parseError?: Function) => {
|
||||
const type = detectType(txt, configApi.getConfig());
|
||||
try {
|
||||
// Trying to find the diagram
|
||||
getDiagram(type);
|
||||
} catch (error) {
|
||||
// Diagram not avaiable, loading it
|
||||
const path = getPathForDiagram(type);
|
||||
// await loadDiagram('./packages/mermaid-mindmap/dist/mermaid-mindmap.js');
|
||||
await loadDiagram(path + 'mermaid-' + type + '.js');
|
||||
// new diagram will try getDiagram again and if fails then it is a valid throw
|
||||
}
|
||||
// If either of the above worked, we have the diagram
|
||||
// logic and can continue
|
||||
return new Diagram(txt, parseError);
|
||||
};
|
@@ -143,7 +143,7 @@ const point = (elem, type) => {
|
||||
.attr('id', type + '-pointEnd')
|
||||
.attr('class', 'marker ' + type)
|
||||
.attr('viewBox', '0 0 10 10')
|
||||
.attr('refX', 9)
|
||||
.attr('refX', 10)
|
||||
.attr('refY', 5)
|
||||
.attr('markerUnits', 'userSpaceOnUse')
|
||||
.attr('markerWidth', 12)
|
@@ -39,8 +39,6 @@ const edgeInCluster = (edge, clusterId) => {
|
||||
log.debug('Tilt, ', clusterId, ',not in decendants');
|
||||
return false;
|
||||
}
|
||||
log.info('Here ');
|
||||
|
||||
if (decendants[clusterId].indexOf(edge.v) >= 0) return true;
|
||||
if (isDecendant(edge.v, clusterId)) return true;
|
||||
if (isDecendant(edge.w, clusterId)) return true;
|
@@ -1,12 +1,13 @@
|
||||
import { MermaidConfig } from '../config.type';
|
||||
|
||||
export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
|
||||
export type DetectorRecord = { detector: DiagramDetector; path: string };
|
||||
|
||||
const directive =
|
||||
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
||||
const anyComment = /\s*%%.*\n/gm;
|
||||
|
||||
const detectors: Record<string, DiagramDetector> = {};
|
||||
const detectors: Record<string, DetectorRecord> = {};
|
||||
|
||||
/**
|
||||
* @function detectType Detects the type of the graph text. Takes into consideration the possible
|
||||
@@ -34,8 +35,10 @@ const detectors: Record<string, DiagramDetector> = {};
|
||||
export const detectType = function (text: string, config?: MermaidConfig): string {
|
||||
text = text.replace(directive, '').replace(anyComment, '\n');
|
||||
|
||||
for (const [key, detector] of Object.entries(detectors)) {
|
||||
if (detector(text, config)) {
|
||||
// console.log(detectors);
|
||||
|
||||
for (const [key, detectorRecord] of Object.entries(detectors)) {
|
||||
if (detectorRecord.detector(text, config)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -44,6 +47,13 @@ export const detectType = function (text: string, config?: MermaidConfig): strin
|
||||
return 'flowchart';
|
||||
};
|
||||
|
||||
export const addDetector = (key: string, detector: DiagramDetector) => {
|
||||
detectors[key] = detector;
|
||||
export const addDetector = (key: string, detector: DiagramDetector, path: string) => {
|
||||
detectors[key] = { detector, path };
|
||||
};
|
||||
|
||||
export const getPathForDiagram = (id: string) => {
|
||||
const detectorRecord = detectors[id];
|
||||
if (detectorRecord) {
|
||||
return detectorRecord.path;
|
||||
}
|
||||
};
|
@@ -1,11 +1,16 @@
|
||||
import { registerDiagram } from './diagramAPI';
|
||||
import {
|
||||
registerDiagram,
|
||||
registerDetector,
|
||||
DiagramDefinition,
|
||||
DiagramDetector,
|
||||
} from './diagramAPI';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
||||
import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||
import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
||||
import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||
import mindmapStyles from '../diagrams/mindmap/styles';
|
||||
// // @ts-ignore: TODO Fix ts errors
|
||||
// import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
||||
// import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||
// import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
||||
// import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||
// import mindmapStyles from '../diagrams/mindmap/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||
@@ -96,13 +101,22 @@ import { journeyDetector } from '../diagrams/user-journey/journeyDetector';
|
||||
import journeyDb from '../diagrams/user-journey/journeyDb';
|
||||
import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
|
||||
import journeyStyles from '../diagrams/user-journey/styles';
|
||||
import { getConfig, setConfig } from '../config';
|
||||
import { setConfig } from '../config';
|
||||
|
||||
import errorRenderer from '../diagrams/error/errorRenderer';
|
||||
import errorStyles from '../diagrams/error/styles';
|
||||
|
||||
const registerDiagramAndDetector = (
|
||||
id: string,
|
||||
diagram: DiagramDefinition,
|
||||
detector: DiagramDetector
|
||||
) => {
|
||||
registerDiagram(id, diagram);
|
||||
registerDetector(id, detector, '');
|
||||
};
|
||||
|
||||
export const addDiagrams = () => {
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'error',
|
||||
// Special diagram with error messages but setup as a regular diagram
|
||||
{
|
||||
@@ -125,7 +139,8 @@ export const addDiagrams = () => {
|
||||
},
|
||||
(text) => text.toLowerCase().trim() === 'error'
|
||||
);
|
||||
registerDiagram(
|
||||
|
||||
registerDiagramAndDetector(
|
||||
'c4',
|
||||
{
|
||||
parser: c4Parser,
|
||||
@@ -138,7 +153,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
c4Detector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'class',
|
||||
{
|
||||
parser: classParser,
|
||||
@@ -155,7 +170,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
classDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'classDiagram',
|
||||
{
|
||||
parser: classParser,
|
||||
@@ -172,7 +187,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
classDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'er',
|
||||
{
|
||||
parser: erParser,
|
||||
@@ -182,7 +197,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
erDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'gantt',
|
||||
{
|
||||
parser: ganttParser,
|
||||
@@ -192,7 +207,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
ganttDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'info',
|
||||
{
|
||||
parser: infoParser,
|
||||
@@ -202,7 +217,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
infoDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'pie',
|
||||
{
|
||||
parser: pieParser,
|
||||
@@ -212,7 +227,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
pieDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'requirement',
|
||||
{
|
||||
parser: requirementParser,
|
||||
@@ -222,7 +237,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
requirementDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'sequence',
|
||||
{
|
||||
parser: sequenceParser,
|
||||
@@ -245,7 +260,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
sequenceDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'state',
|
||||
{
|
||||
parser: stateParser,
|
||||
@@ -262,7 +277,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
stateDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'stateDiagram',
|
||||
{
|
||||
parser: stateParser,
|
||||
@@ -279,7 +294,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
stateDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'journey',
|
||||
{
|
||||
parser: journeyParser,
|
||||
@@ -294,7 +309,7 @@ export const addDiagrams = () => {
|
||||
journeyDetector
|
||||
);
|
||||
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'flowchart',
|
||||
{
|
||||
parser: flowParser,
|
||||
@@ -314,7 +329,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
flowDetector
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'flowchart-v2',
|
||||
{
|
||||
parser: flowParser,
|
||||
@@ -335,14 +350,14 @@ export const addDiagrams = () => {
|
||||
},
|
||||
flowDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
registerDiagramAndDetector(
|
||||
'gitGraph',
|
||||
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
|
||||
gitGraphDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'mindmap',
|
||||
{ parser: mindmapParser, db: mindmapDb, renderer: mindmapRenderer, styles: mindmapStyles },
|
||||
mindmapDetector
|
||||
);
|
||||
// registerDiagram(
|
||||
// 'mindmap',
|
||||
// { parser: mindmapParser, db: mindmapDb, renderer: mindmapRenderer, styles: mindmapStyles },
|
||||
// mindmapDetector
|
||||
// );
|
||||
};
|
@@ -1,5 +1,5 @@
|
||||
import { detectType } from './detectType';
|
||||
import { getDiagram, registerDiagram } from './diagramAPI';
|
||||
import { detectType, DiagramDetector } from './detectType';
|
||||
import { getDiagram, registerDiagram, registerDetector } from './diagramAPI';
|
||||
import { addDiagrams } from './diagram-orchestration';
|
||||
|
||||
addDiagrams();
|
||||
@@ -16,6 +16,10 @@ describe('DiagramAPI', () => {
|
||||
it('should handle diagram registrations', () => {
|
||||
expect(() => getDiagram('loki')).toThrow();
|
||||
expect(() => detectType('loki diagram')).not.toThrow(); // TODO: #3391
|
||||
const detector: DiagramDetector = (str: string) => {
|
||||
return str.match('loki') !== null;
|
||||
};
|
||||
registerDetector('loki', detector, '');
|
||||
registerDiagram(
|
||||
'loki',
|
||||
{
|
@@ -27,18 +27,32 @@ export interface DiagramDefinition {
|
||||
}
|
||||
|
||||
const diagrams: Record<string, DiagramDefinition> = {};
|
||||
const connectCallbacks: Record<string, any> = {}; // TODO fix, eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
export interface Detectors {
|
||||
[key: string]: DiagramDetector;
|
||||
}
|
||||
|
||||
export const registerDetector = (id: string, detector: DiagramDetector, path: string) => {
|
||||
addDetector(id, detector, path);
|
||||
};
|
||||
|
||||
export const registerDiagram = (
|
||||
id: string,
|
||||
diagram: DiagramDefinition,
|
||||
detector: DiagramDetector
|
||||
callback?: (
|
||||
_log: any,
|
||||
_setLogLevel: any,
|
||||
_getConfig: any,
|
||||
_sanitizeText: any,
|
||||
_setupGraphViewbox: any
|
||||
) => void
|
||||
) => {
|
||||
if (diagrams[id]) {
|
||||
log.warn(`Diagram ${id} already registered.`);
|
||||
}
|
||||
diagrams[id] = diagram;
|
||||
addDetector(id, detector);
|
||||
addStylesForDiagram(id, diagram.styles);
|
||||
connectCallbacks[id] = callback;
|
||||
};
|
||||
|
||||
export const getDiagram = (name: string): DiagramDefinition => {
|
||||
@@ -47,3 +61,19 @@ export const getDiagram = (name: string): DiagramDefinition => {
|
||||
}
|
||||
throw new Error(`Diagram ${name} not found.`);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sScriptSrc
|
||||
*/
|
||||
export const loadDiagram = (sScriptSrc: string) =>
|
||||
new Promise((resolve) => {
|
||||
const oHead = document.getElementsByTagName('HEAD')[0];
|
||||
const oScript = document.createElement('script');
|
||||
oScript.type = 'text/javascript';
|
||||
oScript.src = sScriptSrc;
|
||||
oHead.appendChild(oScript);
|
||||
oScript.onload = () => {
|
||||
resolve(true);
|
||||
};
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user