diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml new file mode 100644 index 000000000..fbf03cb39 --- /dev/null +++ b/.github/workflows/link-checker.yml @@ -0,0 +1,45 @@ +# This Link Checker is run on all documentation files once per week. + +# references: +# - https://github.com/lycheeverse/lychee-action +# - https://github.com/lycheeverse/lychee + +name: Link Checker + +on: + push: + branches: + - develop + - master + pull_request: + branches: + - develop + - master + schedule: + # * is a special character in YAML so you have to quote this string + - cron: '30 8 * * 5' + +jobs: + linkChecker: + runs-on: ubuntu-latest + permissions: + # lychee only uses the GITHUB_TOKEN to avoid rate-limiting + contents: read + steps: + - uses: actions/checkout@v3 + + - name: Restore lychee cache + uses: actions/cache@v3 + with: + path: .lycheecache + key: cache-lychee-${{ github.sha }} + restore-keys: cache-lychee- + + - name: Link Checker + uses: lycheeverse/lychee-action@v1.5.4 + with: + args: --verbose --no-progress --cache --max-cache-age 1d packages/mermaid/src/docs/**/*.md README.md README.zh-CN.md + fail: true + jobSummary: true + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.gitignore b/.gitignore index 8cc09354b..f29286825 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ tsconfig.tsbuildinfo knsv*.html local*.html +stats/ diff --git a/.lycheeignore b/.lycheeignore new file mode 100644 index 000000000..767906b16 --- /dev/null +++ b/.lycheeignore @@ -0,0 +1,13 @@ +# These links are ignored by our link checker https://github.com/lycheeverse/lychee +# The file allows you to list multiple regular expressions for exclusion (one pattern per line). + +# Network error: Forbidden +https://codepen.io + +# Network error: The certificate was not trusted +https://mkdocs.org/ +https://osawards.com/javascript/#nominees +https://osawards.com/javascript/2019 + +# Don't check files that are generated during the build via `pnpm docs:code` +packages/mermaid/src/docs/config/setup/* diff --git a/.vite/build.ts b/.vite/build.ts index 50b7fb1ad..f2dd7db05 100644 --- a/.vite/build.ts +++ b/.vite/build.ts @@ -1,9 +1,12 @@ -import { build, InlineConfig } from 'vite'; +import { build, InlineConfig, type PluginOption } from 'vite'; import { resolve } from 'path'; import { fileURLToPath } from 'url'; import jisonPlugin from './jisonPlugin.js'; import { readFileSync } from 'fs'; +import { visualizer } from 'rollup-plugin-visualizer'; +import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js'; +const visualize = process.argv.includes('--visualize'); const watch = process.argv.includes('--watch'); const mermaidOnly = process.argv.includes('--mermaid'); const __dirname = fileURLToPath(new URL('.', import.meta.url)); @@ -13,6 +16,20 @@ type OutputOptions = Exclude< undefined >['output']; +const visualizerOptions = (packageName: string, core = false): PluginOption[] => { + if (packageName !== 'mermaid' || !visualize) { + return []; + } + return ['network', 'treemap', 'sunburst'].map((chartType) => + visualizer({ + filename: `./stats/${chartType}${core ? '.core' : ''}.html`, + template: chartType as TemplateType, + gzipSize: true, + brotliSize: true, + }) + ); +}; + const packageOptions = { mermaid: { name: 'mermaid', @@ -95,7 +112,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) resolve: { extensions: ['.jison', '.js', '.ts', '.json'], }, - plugins: [jisonPlugin()], + plugins: [jisonPlugin(), ...visualizerOptions(packageName, core)], }; if (watch && config.build) { @@ -121,7 +138,7 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => { const main = async () => { const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[]; - for (const pkg of packageNames) { + for (const pkg of packageNames.filter((pkg) => !mermaidOnly || pkg === 'mermaid')) { await buildPackage(pkg); } }; @@ -132,6 +149,9 @@ if (watch) { build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' })); // build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); } +} else if (visualize) { + await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' })); + await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' })); } else { void main(); } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9ec68a917..cf199c39b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,7 +72,7 @@ flowchart LR If you want to preview the whole documentation site on your machine: ```sh -cd mermaid +cd packages/mermaid pnpm i pnpm docs:dev ``` diff --git a/README.md b/README.md index 4d66d3e6b..059940a02 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,6 @@ # mermaid -[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) - -# Whoa, what's 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 some changes.. - -# We use pnpm now - -# The source code has moved - -It is now located in the src folder for each respective package located as subfolders in packages. +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) English | [简体中文](./README.zh-CN.md) diff --git a/README.zh-CN.md b/README.zh-CN.md index e88c54e7f..4bdbc4ae7 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,6 +1,6 @@ # mermaid -[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) [English](./README.md) | 简体中文 @@ -24,9 +24,9 @@ Mermaid 是一个基于 Javascript 的图表绘制工具,通过解析类 Markd Mermaid 通过允许用户创建便于修改的图表来解决这一难题,它也可以作为生产脚本(或其他代码)的一部分。

Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://mermaid.live/) 轻松创建详细的图表。
-你可以访问 [教程](./docs/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。 +你可以访问 [教程](./docs/config/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/misc/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。 -如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/n00b-overview.md), [用法](./docs/usage.md) 和 [教程](./docs/Tutorials.md). +如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/community/n00b-overview.md), [用法](./docs/config/usage.md) 和 [教程](./docs/config/Tutorials.md). 🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [文档](https://mermaidjs.github.io) | 🙌 [贡献](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [更新日志](./docs/CHANGELOG.md) diff --git a/__mocks__/d3.ts b/__mocks__/d3.ts index 67f09b6f4..f90d93557 100644 --- a/__mocks__/d3.ts +++ b/__mocks__/d3.ts @@ -53,6 +53,18 @@ export const MockD3 = (name, parent) => { get __parent() { return parent; }, + node() { + return { + getBBox() { + return { + x: 5, + y: 10, + height: 15, + width: 20, + }; + }, + }; + }, }; elem.append = (name) => { const mockElem = MockD3(name, elem); diff --git a/cSpell.json b/cSpell.json index 08fce1d1c..03891165f 100644 --- a/cSpell.json +++ b/cSpell.json @@ -14,6 +14,7 @@ "bilkent", "bisheng", "brolin", + "brotli", "codedoc", "colour", "cpettitt", @@ -70,6 +71,7 @@ "substate", "sveidqvist", "techn", + "treemap", "ts-nocheck", "tuleap", "verdana", @@ -116,5 +118,8 @@ "Multi-line code blocks", "HTML Tags" ], - "ignorePaths": ["packages/mermaid/src/docs/CHANGELOG.md"] + "ignorePaths": [ + "packages/mermaid/src/docs/CHANGELOG.md", + "packages/mermaid/src/docs/.vitepress/redirect.ts" + ] } diff --git a/cypress/integration/rendering/classDiagram-v2.spec.js b/cypress/integration/rendering/classDiagram-v2.spec.js index e36693a65..f97458857 100644 --- a/cypress/integration/rendering/classDiagram-v2.spec.js +++ b/cypress/integration/rendering/classDiagram-v2.spec.js @@ -496,4 +496,16 @@ describe('Class diagram V2', () => { ); cy.get('svg'); }); + + it('1433: should render a simple class with a title', () => { + imgSnapshotTest( + `--- +title: simple class diagram +--- +classDiagram-v2 +class Class10 +`, + {} + ); + }); }); diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js index 057b36dc1..8e8946170 100644 --- a/cypress/integration/rendering/erDiagram.spec.js +++ b/cypress/integration/rendering/erDiagram.spec.js @@ -273,4 +273,17 @@ describe('Entity Relationship Diagram', () => { ); cy.get('svg'); }); + + it('1433: should render a simple ER diagram with a title', () => { + imgSnapshotTest( + `--- +title: simple ER diagram +--- +erDiagram +CUSTOMER ||--o{ ORDER : places +ORDER ||--|{ LINE-ITEM : contains +`, + {} + ); + }); }); diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index 61dccfb84..30ae4f0d2 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -663,4 +663,15 @@ flowchart RL { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } ); }); + it('1433: should render a titled flowchart with titleTopMargin set to 0', () => { + imgSnapshotTest( + `--- +title: Simple flowchart +--- +flowchart TD +A --> B +`, + { titleTopMargin: 0 } + ); + }); }); diff --git a/cypress/integration/rendering/gitGraph.spec.js b/cypress/integration/rendering/gitGraph.spec.js index afb39b62e..0b5048b44 100644 --- a/cypress/integration/rendering/gitGraph.spec.js +++ b/cypress/integration/rendering/gitGraph.spec.js @@ -322,4 +322,15 @@ describe('Git Graph diagram', () => { {} ); }); + it('1433: should render a simple gitgraph with a title', () => { + imgSnapshotTest( + `--- +title: simple gitGraph +--- +gitGraph + commit +`, + {} + ); + }); }); diff --git a/cypress/integration/rendering/mermaid.spec.js b/cypress/integration/rendering/mermaid.spec.js deleted file mode 100644 index 4b7de3027..000000000 --- a/cypress/integration/rendering/mermaid.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; - -describe('Mindmap', () => { - it('square shape', () => { - imgSnapshotTest( - ` -mindmap - root[ - The root - ] - `, - {} - ); - cy.get('svg'); - }); - it('rounded rect shape', () => { - imgSnapshotTest( - ` -mindmap - root(( - The root - )) - `, - {} - ); - cy.get('svg'); - }); - it('circle shape', () => { - imgSnapshotTest( - ` -mindmap - root( - The root - ) - `, - {} - ); - cy.get('svg'); - }); - it('default shape', () => { - imgSnapshotTest( - ` -mindmap - The root - `, - {} - ); - cy.get('svg'); - }); - it('adding children', () => { - imgSnapshotTest( - ` -mindmap - The root - child1 - child2 - `, - {} - ); - cy.get('svg'); - }); - it('adding grand children', () => { - imgSnapshotTest( - ` -mindmap - The root - child1 - child2 - child3 - `, - {} - ); - cy.get('svg'); - }); -}); diff --git a/cypress/integration/rendering/mindmap.spec.js b/cypress/integration/rendering/mindmap.spec.js deleted file mode 100644 index f0cc2bc3f..000000000 --- a/cypress/integration/rendering/mindmap.spec.js +++ /dev/null @@ -1,115 +0,0 @@ -import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; - -describe('Mindmaps', () => { - it('Only a root', () => { - imgSnapshotTest( - `mindmap -root - `, - {} - ); - }); - - it('a root with a shape', () => { - imgSnapshotTest( - `mindmap -root[root] - `, - {} - ); - }); - - it('a root with wrapping text and a shape', () => { - imgSnapshotTest( - `mindmap -root[A root with a long text that wraps to keep the node size in check] - `, - {} - ); - }); - - it('a root with an icon', () => { - imgSnapshotTest( - `mindmap -root[root] -::icon(mdi mdi-fire) - `, - {} - ); - }); - - it('Blang and cloud shape', () => { - imgSnapshotTest( - `mindmap -root))bang(( - ::icon(mdi mdi-fire) - a))Another bang(( - ::icon(mdi mdi-fire) - a)A cloud( - ::icon(mdi mdi-fire) - `, - {} - ); - }); - - it('Blang and cloud shape with icons', () => { - imgSnapshotTest( - `mindmap -root))bang(( - - a))Another bang(( - a)A cloud( - `, - {} - ); - }); - - it('braches', () => { - imgSnapshotTest( - `mindmap -root - child1 - grandchild 1 - grandchild 2 - child2 - grandchild 3 - grandchild 4 - child3 - grandchild 5 - grandchild 6 - `, - {} - ); - }); - - it('braches with shapes and labels', () => { - imgSnapshotTest( - `mindmap -root - child1((Circle)) - grandchild 1 - grandchild 2 - child2(Round rectangle) - grandchild 3 - grandchild 4 - child3[Square] - grandchild 5 - ::icon(mdi mdi-fire) - gc6((grand
child 6)) - ::icon(mdi mdi-fire) - `, - {} - ); - }); - it('text shouhld wrap with icon', () => { - imgSnapshotTest( - `mindmap -root - Child3(A node with an icon and with a long text that wraps to keep the node size in check) - `, - {} - ); - }); - - /* The end */ -}); diff --git a/cypress/integration/rendering/mindmap.spec.ts b/cypress/integration/rendering/mindmap.spec.ts new file mode 100644 index 000000000..62c7e785b --- /dev/null +++ b/cypress/integration/rendering/mindmap.spec.ts @@ -0,0 +1,233 @@ +import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; + +/** + * Check whether the SVG Element has a Mindmap root + * + * Sometimes, Cypress takes a snapshot before the mermaid mindmap has finished + * generating the SVG. + * + * @param $p - The element to check. + */ +function shouldHaveRoot($p: JQuery) { + // get HTML Element from jquery element + const svgElement = $p[0]; + expect(svgElement.nodeName).equal('svg'); + + const sectionRoots = svgElement.getElementsByClassName('mindmap-node section-root'); + // mindmap should have at least one root section + expect(sectionRoots).to.have.lengthOf.at.least(1); +} + +describe('Mindmaps', () => { + it('Only a root', () => { + imgSnapshotTest( + `mindmap +root + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('a root with a shape', () => { + imgSnapshotTest( + `mindmap +root[root] + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('a root with wrapping text and a shape', () => { + imgSnapshotTest( + `mindmap +root[A root with a long text that wraps to keep the node size in check] + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('a root with an icon', () => { + imgSnapshotTest( + `mindmap +root[root] +::icon(mdi mdi-fire) + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('Blang and cloud shape', () => { + imgSnapshotTest( + `mindmap +root))bang(( + ::icon(mdi mdi-fire) + a))Another bang(( + ::icon(mdi mdi-fire) + a)A cloud( + ::icon(mdi mdi-fire) + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('Blang and cloud shape with icons', () => { + imgSnapshotTest( + `mindmap +root))bang(( + + a))Another bang(( + a)A cloud( + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('braches', () => { + imgSnapshotTest( + `mindmap +root + child1 + grandchild 1 + grandchild 2 + child2 + grandchild 3 + grandchild 4 + child3 + grandchild 5 + grandchild 6 + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('braches with shapes and labels', () => { + imgSnapshotTest( + `mindmap +root + child1((Circle)) + grandchild 1 + grandchild 2 + child2(Round rectangle) + grandchild 3 + grandchild 4 + child3[Square] + grandchild 5 + ::icon(mdi mdi-fire) + gc6((grand
child 6)) + ::icon(mdi mdi-fire) + `, + {}, + undefined, + shouldHaveRoot + ); + }); + it('text shouhld wrap with icon', () => { + imgSnapshotTest( + `mindmap +root + Child3(A node with an icon and with a long text that wraps to keep the node size in check) + `, + {}, + undefined, + shouldHaveRoot + ); + }); + it('square shape', () => { + imgSnapshotTest( + ` +mindmap + root[ + The root + ] + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('rounded rect shape', () => { + imgSnapshotTest( + ` +mindmap + root(( + The root + )) + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('circle shape', () => { + imgSnapshotTest( + ` +mindmap + root( + The root + ) + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('default shape', () => { + imgSnapshotTest( + ` +mindmap + The root + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('adding children', () => { + imgSnapshotTest( + ` +mindmap + The root + child1 + child2 + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('adding grand children', () => { + imgSnapshotTest( + ` +mindmap + The root + child1 + child2 + child3 + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + /* The end */ +}); diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index 5b43c890c..0eca01873 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -559,4 +559,16 @@ stateDiagram-v2 ); }); }); + it('1433: should render a simple state diagram with a title', () => { + imgSnapshotTest( + `--- +title: simple state diagram +--- +stateDiagram-v2 +[*] --> State1 +State1 --> [*] +`, + {} + ); + }); }); diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json new file mode 100644 index 000000000..e3351cebe --- /dev/null +++ b/cypress/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "es2020", + "lib": ["es2020", "dom"], + "types": ["cypress", "node"] + }, + "include": ["**/*.ts"] +} diff --git a/demos/classchart.html b/demos/classchart.html index 5979152d6..031f3b608 100644 --- a/demos/classchart.html +++ b/demos/classchart.html @@ -17,6 +17,9 @@

Class diagram demos

+---
+title: Demo Class Diagram
+---
 		classDiagram
       accTitle: Demo Class Diagram
       accDescr: This class diagram show the abstract Animal class, and 3 classes that inherit from it: Duck, Fish, and Zebra.
diff --git a/demos/er.html b/demos/er.html
index 4c1a72c20..06fbf020e 100644
--- a/demos/er.html
+++ b/demos/er.html
@@ -20,6 +20,9 @@
   
     
 
+---
+title: This is a title
+---
 erDiagram
   %% title This is a title
   %% accDescription Test a description
diff --git a/demos/flowchart.html b/demos/flowchart.html
index e11bfcb26..7251e586e 100644
--- a/demos/flowchart.html
+++ b/demos/flowchart.html
@@ -17,6 +17,9 @@
     

Sample 1

graph

+---
+title: This is a complicated flow
+---
     graph LR
       accTitle: This is a complicated flow
       accDescr: This is the descriptoin for the complicated flow.
@@ -221,6 +224,9 @@
     

Sample 2

graph

+---
+title: What to buy
+---
     graph TD
       accTitle: What to buy
       accDescr: Options of what to buy with Christmas money
diff --git a/demos/git.html b/demos/git.html
index 15b4401db..99c53d7d0 100644
--- a/demos/git.html
+++ b/demos/git.html
@@ -16,6 +16,9 @@
   
     

Git diagram demo

+---
+title: Simple Git diagram
+---
     gitGraph:
     options
     {
diff --git a/demos/index.html b/demos/index.html
index a65681ddf..da27cdcff 100644
--- a/demos/index.html
+++ b/demos/index.html
@@ -48,6 +48,9 @@
       
  • Journey

  • +
  • +

    Mindmap

    +
  • Pie

  • diff --git a/demos/journey.html b/demos/journey.html index c5c6c25e8..9ccc8dd3d 100644 --- a/demos/journey.html +++ b/demos/journey.html @@ -16,8 +16,10 @@

    Journey diagram demo

    -         journey
    -    title My working day
    +---
    +title: My working day
    +---
    +     journey
           accTitle: Very simple journey demo
           accDescr: 2 main sections: work and home, each with just a few tasks
     
    diff --git a/demos/mindmap.html b/demos/mindmap.html
    new file mode 100644
    index 000000000..a5b554a1a
    --- /dev/null
    +++ b/demos/mindmap.html
    @@ -0,0 +1,108 @@
    +
    +
    +  
    +    
    +    
    +    Mindmap Mermaid Quick Test Page
    +    
    +    
    +  
    +
    +  
    +    

    Mindmap diagram demo

    +
    +        mindmap
    +        root
    +            child1((Circle))
    +                grandchild 1
    +                grandchild 2
    +            child2(Round rectangle)
    +                grandchild 3
    +                grandchild 4
    +            child3[Square]
    +                grandchild 5
    +                ::icon(mdi mdi-fire)
    +                gc6((grand
    child 6)) + ::icon(mdi mdi-fire) + gc7((grand
    grand
    child 8)) +
    + +

    Mindmap with root wrapping text and a shape

    +
    +        mindmap
    +            root[A root with a long text that wraps to keep the node size in check]
    +    
    + + + + diff --git a/demos/state.html b/demos/state.html index dbe2286a3..3d070f379 100644 --- a/demos/state.html +++ b/demos/state.html @@ -1,5 +1,5 @@ - + @@ -17,6 +17,9 @@

    State diagram demos

    Very simple showing change from State1 to State2

    +---
    +title: Very simple diagram
    +---
     		stateDiagram
     		  accTitle: This is the accessible title
           accDescr:This is an accessible description
    @@ -30,8 +33,9 @@
         

    classDef notMoving fill:white
    - classDef movement font-style:italic;
    - classDef badBadEvent fill:#f00,color:white,font-weight:bold
    + classDef movement font-style:italic
    + classDef badBadEvent + fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow

    And these are how they are applied:

    @@ -43,15 +47,20 @@

    -		stateDiagram-v2
    +---
    +title: Very simple diagram
    +---
    +		stateDiagram
    +      direction TB
    +
     		  accTitle: This is the accessible title
           accDescr: This is an accessible description
     
           classDef notMoving fill:white
    -      classDef movement font-style:italic;
    -      classDef badBadEvent fill:#f00,color:white,font-weight:bold
    +      classDef movement font-style:italic
    +      classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
     
    -      [*] --> Still
    +      [*]--> Still
           Still --> [*]
           Still --> Moving
           Moving --> Still
    @@ -61,10 +70,57 @@
           class Still notMoving
           class Moving, Crash movement
           class Crash badBadEvent
    +      class end badBadEvent
         

    +

    Here is a diagram that uses the ::: operator to apply styles to states

    +

    Here are the classDef statements:

    +

    + + classDef notMoving fill:white
    + classDef movement font-style:italic
    + classDef badBadEvent + fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
    +
    +

    +

    And these are how they are applied:

    +

    + + [*] --> Still:::notMoving
    + ...
    + Still --> Moving:::movement
    + ...
    + Moving --> Crash:::movement
    + Crash:::badBadEvent --> [*]
    +
    +

    +

    + Note that both the starting state and the end state have styles applied:
    + The start state has the start classDef style
    and the end state has the + stop classDef style applied. +

    +
    +    stateDiagram
    +      direction TB
    +
    +		  accTitle: This is the accessible title
    +      accDescr: This is an accessible description
    +
    +      classDef notMoving fill:white
    +      classDef movement font-style:italic
    +      classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
    +
    +      [*] --> Still:::notMoving
    +      Still --> [*]
    +      Still --> Moving:::movement
    +      Moving --> Still
    +      Moving --> Crash:::movement
    +      Crash:::badBadEvent --> [*]
    +    
    +
    +
         stateDiagram-v2
           accTitle: very very simple state
    @@ -73,6 +129,20 @@
         

    +

    States with spaces in them

    +
    +      stateDiagram
    +        classDef yourState font-style:italic,font-weight:bold,fill:white
    +
    +        yswsii: Your state with spaces in it
    +        [*] --> yswsii:::yourState
    +        [*] --> SomeOtherState
    +        SomeOtherState --> YetAnotherState
    +        yswsii --> YetAnotherState
    +        YetAnotherState --> [*]
    +    
    +
    +

    You can label the relationships

         stateDiagram-v2
    @@ -121,7 +191,7 @@
         
           stateDiagram-v2
           [*] --> S1
    -      S1 --> S2: This long line uses a br tag
    to create multiple
    lines. + S1 --> S2: This long line uses a br tag
    to create multiple
    lines. S1 --> S3: This transition descripton uses \na newline character\nto create multiple\nlines.
    @@ -133,7 +203,7 @@ direction LR State1: A state with a note note right of State1 - Important information!
    You can write notes.
    And\nthey\ncan\nbe\nmulti-\nline. + Important information!
    You can write notes.
    And\nthey\ncan\nbe\nmulti-\nline. end note State1 --> State2 note left of State2 : Notes can be to the left of a state\n(like this one). diff --git a/docs/community/development.md b/docs/community/development.md index d7e9b7315..58ca4670b 100644 --- a/docs/community/development.md +++ b/docs/community/development.md @@ -12,7 +12,7 @@ So you want to help? That's great! Here are a few things to get you started on the right path. -**The Docs Structure is dictated by [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)** +**The Docs Structure is dictated by [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. **Note: Commits and Pull Requests should be directed to the develop branch.** @@ -32,7 +32,7 @@ We make all changes via Pull Requests. As we have many Pull Requests from develo - Large changes reviewed by knsv or other developer asked to review by knsv - Smaller, low-risk changes like dependencies, documentation, etc. can be merged by active collaborators -- Documentation (we encourage updates to the `src/docs` folder; you can submit them via direct commits) +- Documentation (we encourage updates to the `/packages/mermaid/src/docs` folder; you can submit them via direct commits) When you commit code, create a branch with the following naming convention: @@ -50,9 +50,9 @@ Start with the type, such as **feature** or **bug**, followed by the issue numbe If it is not in the documentation, it's like it never happened. Wouldn't that be sad? With all the effort that was put into the feature? -The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via the **[sidebar](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**. +The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via **[.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. -> **All the documents displayed in the GitHub.io page are listed in [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**. +> **All the documents displayed in the GitHub.io page are listed in [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. The contents of are based on the docs from the `master` branch. Updates committed to the `master` branch are reflected in the [Mermaid Docs](https://mermaid-js.github.io/mermaid/) once released. @@ -64,7 +64,7 @@ The documentation is located in the `src/docs` directory and organized according The `docs` folder will be automatically generated when committing to `src/docs` and should not be edited manually. -We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s) +We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s) ### Add Unit Tests for Parsing @@ -117,7 +117,7 @@ Markdown is used to format the text, for more information about Markdown [see th To edit Docs on your computer: -1. Find the Markdown file (.md) to edit in the [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs) directory in the `develop` branch. +1. Find the Markdown file (.md) to edit in the [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs) directory in the `develop` branch. 2. Create a fork of the develop branch. 3. Make changes or add new documentation. 4. Commit changes to your fork and push it to GitHub. @@ -126,7 +126,7 @@ To edit Docs on your computer: To edit Docs on GitHub: 1. Login to [GitHub.com](https://www.github.com). -2. Navigate to [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). +2. Navigate to [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). 3. To edit a file, click the pencil icon at the top-right of the file contents panel. 4. Describe what you changed in the **Propose file change** section, located at the bottom of the page. 5. Submit your changes by clicking the button **Propose file change** at the bottom (by automatic creation of a fork and a new branch). diff --git a/docs/community/n00b-overview.md b/docs/community/n00b-overview.md index 0747edc32..e0056d912 100644 --- a/docs/community/n00b-overview.md +++ b/docs/community/n00b-overview.md @@ -45,7 +45,7 @@ It is a relatively straightforward solution to a significant hurdle with the sof **Nodes** -> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](../intro/n00b-syntaxReference) +> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](../intro/n00b-syntaxReference.md) ## Advantages of using Mermaid diff --git a/docs/community/security.md b/docs/community/security.md index 1825ed975..07adbfbf8 100644 --- a/docs/community/security.md +++ b/docs/community/security.md @@ -10,13 +10,13 @@ The Mermaid team takes the security of Mermaid and the applications that use Mer ## Reporting vulnerabilities -To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. +To report a vulnerability, please e-mail with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. We aim to reply within three working days, probably much sooner. -You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to security@mermaid.live again if you do not receive prompt attention and regular updates. +You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to again if you do not receive prompt attention and regular updates. -You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail security@mernaid.live when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk. +You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk. ## Best practices diff --git a/docs/config/8.6.0_docs.md b/docs/config/8.6.0_docs.md index 5a7e58951..abd158712 100644 --- a/docs/config/8.6.0_docs.md +++ b/docs/config/8.6.0_docs.md @@ -12,8 +12,8 @@ With version 8.6.0 comes the release of directives for mermaid, a new system for modifying configurations, with the aim of establishing centralized, sane defaults and simple implementation. -`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](../config/configuration). -This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](directives), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams. +`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](../config/configuration.md). +This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](directives.md), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams. **A likely application for this is in the creation of diagrams/charts inside company/organizational webpages, that rely on mermaid for diagram and chart rendering.** @@ -219,4 +219,4 @@ Example of **object.Assign**: > **Note** > default: current siteConfig (optional, default `getSiteConfig()`) -## For more information, read [Setup](setup/README). +## For more information, read [Setup](./setup/README.md). diff --git a/docs/config/Tutorials.md b/docs/config/Tutorials.md index 696e31d83..41e0508cb 100644 --- a/docs/config/Tutorials.md +++ b/docs/config/Tutorials.md @@ -28,7 +28,7 @@ The definitions that can be generated the Live-Editor are also backwards-compati ## Mermaid with HTML -Examples are provided in [Getting Started](../intro/n00b-gettingStarted) +Examples are provided in [Getting Started](../intro/n00b-gettingStarted.md) **CodePen Examples:** diff --git a/docs/config/setup/modules/defaultConfig.md b/docs/config/setup/modules/defaultConfig.md index c7ad1402f..05f6f8a2c 100644 --- a/docs/config/setup/modules/defaultConfig.md +++ b/docs/config/setup/modules/defaultConfig.md @@ -14,7 +14,7 @@ #### Defined in -[defaultConfig.ts:1881](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1881) +[defaultConfig.ts:1933](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1933) --- diff --git a/docs/config/usage.md b/docs/config/usage.md index a227b7a98..29273e9b5 100644 --- a/docs/config/usage.md +++ b/docs/config/usage.md @@ -18,7 +18,7 @@ Please note that you can switch versions through the dropdown box at the top rig ## Using mermaid -For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](setup/README). +For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](./setup/README.md). We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermaid Live Editor. @@ -41,7 +41,7 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai **Hosting mermaid on a web page.** -> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted) +> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted.md) The easiest way to integrate mermaid on a web page requires two elements: @@ -326,7 +326,7 @@ setting the options in mermaid. 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). +configuration objects are described [in the mermaidAPI documentation](./setup/README.md). ## Using the `mermaidAPI.initialize`/`mermaid.initialize` call @@ -348,7 +348,7 @@ on what kind of integration you use. ## Using the mermaid object -Is it possible to set some configuration via the mermaid object. The two parameters that are supported using this +It is possible to set some configuration via the mermaid object. The two parameters that are supported using this approach are: - mermaid.startOnLoad diff --git a/docs/intro/index.md b/docs/intro/index.md index 84462aa5b..b8a27acff 100644 --- a/docs/intro/index.md +++ b/docs/intro/index.md @@ -10,11 +10,11 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically. -> If you are familiar with Markdown you should have no problem learning [Mermaid's Syntax](n00b-syntaxReference). +> If you are familiar with Markdown you should have no problem learning [Mermaid's Syntax](n00b-syntaxReference.md). -[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) @@ -35,7 +35,7 @@ Use Mermaid with your favorite applications, check out the list of [Integrations For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](../community/n00b-overview.md) and [Usage](../config/usage.md). -🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/docs/development.md) | 🔌 [Plug-Ins](../misc/integrations.md) +🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](../community/development.md) | 🔌 [Plug-Ins](../misc/integrations.md) > 🖖 Keep a steady pulse: mermaid needs more Collaborators, [Read More](https://github.com/knsv/mermaid/issues/866). @@ -163,7 +163,7 @@ Class01 : int gorilla Class08 <--> C2: Cool label ``` -### Git graph +### [Git graph](../syntax/gitgraph.md) ```mermaid-example gitGraph @@ -237,9 +237,9 @@ journey ## Installation -**In depth guides and examples can be found at [Getting Started](n00b-gettingStarted) and [Usage](../config/usage).** +**In depth guides and examples can be found at [Getting Started](./n00b-gettingStarted.md) and [Usage](../config/usage.md).** -**It would also be helpful to learn more about mermaid's [Syntax](n00b-syntaxReference).** +**It would also be helpful to learn more about mermaid's [Syntax](./n00b-syntaxReference.md).** ### CDN @@ -261,7 +261,7 @@ To Deploy Mermaid: - Yarn: `yarn add mermaid` - Pnpm: `pnpm add mermaid` -### [Mermaid API](../config/setup/README): +### [Mermaid API](../config/setup/README.md): **To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaid.initialize` call into the HTML like so:** @@ -274,7 +274,7 @@ To Deploy Mermaid: **Doing so will command the mermaid parser to look for the `
    ` or `
    ` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
     
    -**Examples can be found at** [Other examples](../syntax/examples)
    +**Examples can be found at** [Other examples](../syntax/examples.md)
     
     ## Sibling projects
     
    diff --git a/docs/intro/n00b-gettingStarted.md b/docs/intro/n00b-gettingStarted.md
    index 11a5274b1..498aa1595 100644
    --- a/docs/intro/n00b-gettingStarted.md
    +++ b/docs/intro/n00b-gettingStarted.md
    @@ -53,7 +53,7 @@ graph TD
     
     In the `Code` section one can write or edit raw mermaid code, and instantly `Preview` the rendered result on the panel beside it.
     
    -The `Configuration` Section is for changing the appearance and behavior of mermaid diagrams. An easy introduction to mermaid configuration is found in the [Advanced usage](../config/n00b-advanced.md) section. A complete configuration reference cataloging the default values can be found on the [mermaidAPI](../config/setup/README) page.
    +The `Configuration` Section is for changing the appearance and behavior of mermaid diagrams. An easy introduction to mermaid configuration is found in the [Advanced usage](../config/n00b-advanced.md) section. A complete configuration reference cataloging the default values can be found on the [mermaidAPI](../config/setup/README.md) page.
     
     ![Code,Config and Preview](./img/Code-Preview-Config.png)
     
    diff --git a/docs/intro/n00b-syntaxReference.md b/docs/intro/n00b-syntaxReference.md
    index 7c6d47e93..c51b1680e 100644
    --- a/docs/intro/n00b-syntaxReference.md
    +++ b/docs/intro/n00b-syntaxReference.md
    @@ -42,19 +42,19 @@ erDiagram
               PRODUCT ||--o{ ORDER-ITEM : "ordered in"
     ```
     
    -The [Getting Started](n00b-gettingStarted) section can also provide some practical examples of mermaid syntax.
    +The [Getting Started](./n00b-gettingStarted.md) section can also provide some practical examples of mermaid syntax.
     
     ## Diagram Breaking
     
     One should **beware the use of some words or symbols** that can break diagrams. These words or symbols are few and often only affect specific types of diagrams. The table below will continuously be updated.
     
    -| Diagram Breakers                                                                                               | Reason                                                                  | Solution                                          |
    -| -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------- |
    -| **Comments**                                                                                                   |                                                                         |                                                   |
    -| [` %%{``}%% `](https://github.com/mermaid-js/mermaid/issues/1968)                                              | Similar to [Directives](../config/directives.md) confuses the renderer. | In comments using `%%`, avoid using "{}".         |
    -| **Flow-Charts**                                                                                                |                                                                         |                                                   |
    -| 'end'                                                                                                          | The word "End" can cause Flowcharts and Sequence diagrams to break      | Wrap them in quotation marks to prevent breakage. |
    -| [Nodes inside Nodes](https://mermaid-js.github.io/mermaid/#/flowchart?id=special-characters-that-break-syntax) | Mermaid gets confused with nested shapes                                | wrap them in quotation marks to prevent breaking  |
    +| Diagram Breakers                                                                     | Reason                                                                  | Solution                                          |
    +| ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- | ------------------------------------------------- |
    +| **Comments**                                                                         |                                                                         |                                                   |
    +| [` %%{``}%% `](https://github.com/mermaid-js/mermaid/issues/1968)                    | Similar to [Directives](../config/directives.md) confuses the renderer. | In comments using `%%`, avoid using "{}".         |
    +| **Flow-Charts**                                                                      |                                                                         |                                                   |
    +| 'end'                                                                                | The word "End" can cause Flowcharts and Sequence diagrams to break      | Wrap them in quotation marks to prevent breakage. |
    +| [Nodes inside Nodes](../syntax/flowchart.md?id=special-characters-that-break-syntax) | Mermaid gets confused with nested shapes                                | wrap them in quotation marks to prevent breaking  |
     
     ### Mermaid Live Editor
     
    @@ -64,9 +64,9 @@ Now, that you've seen what you should not add to your diagrams, you can play aro
     
     Configuration is the third part of Mermaid, after deployment and syntax. It deals with the different ways that Mermaid can be customized across different deployments.
     
    -If you are interested in altering and customizing your Mermaid Diagrams, you will find the methods and values available for [Configuration](../config/setup/README) here. It includes themes.
    +If you are interested in altering and customizing your Mermaid Diagrams, you will find the methods and values available for [Configuration](../config/setup/README.md) here. It includes themes.
     This section will introduce the different methods of configuring the behaviors and appearances of Mermaid Diagrams.
    -The following are the most commonly used methods, and they are all tied to Mermaid [Deployment](n00b-gettingStarted) methods.
    +The following are the most commonly used methods, and they are all tied to Mermaid [Deployment](./n00b-gettingStarted.md) methods.
     
     ### Configuration Section in the [Live Editor](https://mermaid.live).
     
    diff --git a/docs/misc/integrations.md b/docs/misc/integrations.md
    index e775af90a..a4c9e31a5 100644
    --- a/docs/misc/integrations.md
    +++ b/docs/misc/integrations.md
    @@ -39,6 +39,7 @@ They also serve as proof of concept, for the variety of things that can be built
       - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
     - [JetBrains IDE eg Pycharm](https://www.jetbrains.com/go/guide/tips/mermaid-js-support-in-markdown/)
     - [mermerd](https://github.com/KarnerTh/mermerd)
    +- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
     
     ## CRM/ERP/Similar
     
    @@ -167,7 +168,6 @@ They also serve as proof of concept, for the variety of things that can be built
     | Extensions for Mermaid   | -                                                                                                            | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | -                                                                                                                            | [🐙🔗](https://github.com/Stefan-S/mermaid-extension)                                                |
     | Chrome Diagrammer        | [🎡🔗](https://chrome.google.com/webstore/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk)         | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
     | Mermaid Diagrams         | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil)          | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
    -| Mermaid Markdown         | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-markdown/mboeoikjijmjcjgpccghbcoegikliijg)          | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
     | Monkeys                  | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
     | Mermaid Previewer        | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-previewer/oidjnlhbegipkcklbdfnbkikplpghfdl)         | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
     
    diff --git a/docs/syntax/c4c.md b/docs/syntax/c4c.md
    index ef1295450..e946aedb6 100644
    --- a/docs/syntax/c4c.md
    +++ b/docs/syntax/c4c.md
    @@ -567,7 +567,7 @@ UpdateRelStyle(customerA, bankA, $offsetY="60")
             Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.")
         }
     
    -    Deployment_Node(comp, "Customer's computer", "Mircosoft Windows or Apple macOS"){
    +    Deployment_Node(comp, "Customer's computer", "Microsoft Windows or Apple macOS"){
             Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox,
    Apple Safari or Microsoft Edge"){ Container(spa, "Single Page Application", "JavaScript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.") } @@ -619,7 +619,7 @@ UpdateRelStyle(customerA, bankA, $offsetY="60") Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.") } - Deployment_Node(comp, "Customer's computer", "Mircosoft Windows or Apple macOS"){ + Deployment_Node(comp, "Customer's computer", "Microsoft Windows or Apple macOS"){ Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox,
    Apple Safari or Microsoft Edge"){ Container(spa, "Single Page Application", "JavaScript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.") } diff --git a/docs/syntax/classDiagram.md b/docs/syntax/classDiagram.md index d57125c84..5870d0743 100644 --- a/docs/syntax/classDiagram.md +++ b/docs/syntax/classDiagram.md @@ -14,6 +14,9 @@ The class diagram is the main building block of object-oriented modeling. It is Mermaid can render class diagrams. ```mermaid-example +--- +title: Animal example +--- classDiagram note "From Duck till Zebra" Animal <|-- Duck @@ -40,6 +43,9 @@ classDiagram ``` ```mermaid +--- +title: Animal example +--- classDiagram note "From Duck till Zebra" Animal <|-- Duck @@ -77,6 +83,9 @@ A single instance of a class in the diagram contains three compartments: - The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase. ```mermaid-example +--- +title: Bank example +--- classDiagram class BankAccount BankAccount : +String owner @@ -87,6 +96,9 @@ classDiagram ``` ```mermaid +--- +title: Bank example +--- classDiagram class BankAccount BankAccount : +String owner @@ -559,7 +571,7 @@ You would define these actions on a separate line after all classes have been de ## Notes -It is possible to add notes on digram using `note "line1\nline2"` or note for class using `note for class "line1\nline2"` +It is possible to add notes on diagram using `note "line1\nline2"` or note for class using `note for class "line1\nline2"` ### Examples diff --git a/docs/syntax/entityRelationshipDiagram.md b/docs/syntax/entityRelationshipDiagram.md index fef7b6fee..9b938bc36 100644 --- a/docs/syntax/entityRelationshipDiagram.md +++ b/docs/syntax/entityRelationshipDiagram.md @@ -13,6 +13,9 @@ Note that practitioners of ER modelling almost always refer to _entity types_ si Mermaid can render ER diagrams ```mermaid-example +--- +title: Order example +--- erDiagram CUSTOMER ||--o{ ORDER : places ORDER ||--|{ LINE-ITEM : contains @@ -20,6 +23,9 @@ erDiagram ``` ```mermaid +--- +title: Order example +--- erDiagram CUSTOMER ||--o{ ORDER : places ORDER ||--|{ LINE-ITEM : contains diff --git a/docs/syntax/examples.md b/docs/syntax/examples.md index 516e65eee..ae2ba0ed3 100644 --- a/docs/syntax/examples.md +++ b/docs/syntax/examples.md @@ -8,9 +8,9 @@ This page contains a collection of examples of diagrams and charts that can be created through mermaid and its myriad applications. -**If you wish to learn how to support mermaid on your webpage, read the [Beginner's Guide](../config/usage?id=usage).** +**If you wish to learn how to support mermaid on your webpage, read the [Beginner's Guide](../config/usage.md?id=usage).** -**If you wish to learn about mermaid's syntax, Read the [Diagram Syntax](../syntax/flowchart?id=flowcharts-basic-syntax) section.** +**If you wish to learn about mermaid's syntax, Read the [Diagram Syntax](../syntax/flowchart.md?id=flowcharts-basic-syntax) section.** ## Basic Pie Chart diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md index 234f46236..8b3859f8a 100644 --- a/docs/syntax/flowchart.md +++ b/docs/syntax/flowchart.md @@ -15,11 +15,17 @@ It can also accommodate different arrow types, multi directional arrows, and lin ### A node (default) ```mermaid-example +--- +title: Node +--- flowchart LR id ``` ```mermaid +--- +title: Node +--- flowchart LR id ``` @@ -33,11 +39,17 @@ found for the node that will be used. Also if you define edges for the node late one previously defined will be used when rendering the box. ```mermaid-example +--- +title: Node with text +--- flowchart LR id1[This is the text in the box] ``` ```mermaid +--- +title: Node with text +--- flowchart LR id1[This is the text in the box] ``` @@ -980,7 +992,7 @@ flowchart LR ## Configuration... -Is it possible to adjust the width of the rendered flowchart. +It is possible to adjust the width of the rendered flowchart. This is done by defining **mermaid.flowchartConfig** or by the CLI to use a JSON file with the configuration. How to use the CLI is described in the mermaidCLI page. mermaid.flowchartConfig can be set to a JSON string with config parameters or the corresponding object. diff --git a/docs/syntax/gantt.md b/docs/syntax/gantt.md index 5d8f6ce68..b20b6b776 100644 --- a/docs/syntax/gantt.md +++ b/docs/syntax/gantt.md @@ -201,7 +201,7 @@ More info in: https://momentjs.com/docs/#/parsing/string-format/ ### Output date format on the axis -The default output date format is YYYY-MM-DD. You can define your custom `axisFormat`, like `2020-Q1` for the first quarter of the year 2020. +The default output date format is `YYYY-MM-DD`. You can define your custom `axisFormat`, like `2020-Q1` for the first quarter of the year 2020. axisFormat %Y-%m-%d @@ -232,7 +232,7 @@ The following formatting strings are supported: %Z - time zone offset, such as "-0700". %% - a literal "%" character. -More info in: https://github.com/mbostock/d3/wiki/Time-Formatting +More info in: ### Axis ticks @@ -357,7 +357,7 @@ To hide the marker, set `todayMarker` to `off`. It is possible to adjust the margins for rendering the gantt diagram. This is done by defining the `ganttConfig` part of the configuration object. -How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI) page. +How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI.md) page. mermaid.ganttConfig can be set to a JSON string with config parameters or the corresponding object. diff --git a/docs/syntax/gitgraph.md b/docs/syntax/gitgraph.md index cd1a3f12a..964fe3886 100644 --- a/docs/syntax/gitgraph.md +++ b/docs/syntax/gitgraph.md @@ -13,31 +13,37 @@ These kind of diagram are particularly helpful to developers and devops teams to Mermaid can render Git diagrams ```mermaid-example - gitGraph - commit - commit - branch develop - checkout develop - commit - commit - checkout main - merge develop - commit - commit +--- +title: Example Git diagram +--- +gitGraph + commit + commit + branch develop + checkout develop + commit + commit + checkout main + merge develop + commit + commit ``` ```mermaid - gitGraph - commit - commit - branch develop - checkout develop - commit - commit - checkout main - merge develop - commit - commit +--- +title: Example Git diagram +--- +gitGraph + commit + commit + branch develop + checkout develop + commit + commit + checkout main + merge develop + commit + commit ``` In Mermaid, we support the basic git operations like: diff --git a/docs/syntax/mindmap.md b/docs/syntax/mindmap.md index 26a1065be..628461c4f 100644 --- a/docs/syntax/mindmap.md +++ b/docs/syntax/mindmap.md @@ -21,7 +21,7 @@ mindmap Popularisation British popular psychology author Tony Buzan Research - On effectivness
    and eatures + On effectiveness
    and features On Automatic creation Uses Creative techniques @@ -42,7 +42,7 @@ mindmap Popularisation British popular psychology author Tony Buzan Research - On effectivness
    and eatures + On effectiveness
    and features On Automatic creation Uses Creative techniques @@ -152,6 +152,18 @@ mindmap id)I am a cloud( ``` +### Hexagon + +```mermaid-example +mindmap + id{{I am a hexagon}} +``` + +```mermaid +mindmap + id{{I am a hexagon}} +``` + ### Default ```mermaid-example diff --git a/docs/syntax/pie.md b/docs/syntax/pie.md index 6801b3619..63f371e87 100644 --- a/docs/syntax/pie.md +++ b/docs/syntax/pie.md @@ -35,7 +35,7 @@ Drawing a pie chart is really simple in mermaid. - Followed by dataSet. Pie slices will be ordered clockwise in the same order as the labels. - `label` for a section in the pie diagram within `" "` quotes. - Followed by `:` colon as separator - - Followed by `positive numeric value` (supported upto two decimal places) + - Followed by `positive numeric value` (supported up to two decimal places) \[pie] \[showData] (OPTIONAL) \[title] \[titlevalue] (OPTIONAL) diff --git a/docs/syntax/sequenceDiagram.md b/docs/syntax/sequenceDiagram.md index b2d33bf69..ad88249be 100644 --- a/docs/syntax/sequenceDiagram.md +++ b/docs/syntax/sequenceDiagram.md @@ -727,10 +727,10 @@ text.actor { ## Configuration -Is it possible to adjust the margins for rendering the sequence diagram. +It is possible to adjust the margins for rendering the sequence diagram. This is done by defining `mermaid.sequenceConfig` or by the CLI to use a json file with the configuration. -How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI) page. +How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI.md) page. `mermaid.sequenceConfig` can be set to a JSON string with config parameters or the corresponding object. ```javascript diff --git a/docs/syntax/stateDiagram.md b/docs/syntax/stateDiagram.md index ec91411f6..72d7ec63b 100644 --- a/docs/syntax/stateDiagram.md +++ b/docs/syntax/stateDiagram.md @@ -6,11 +6,17 @@ # State diagrams -> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the case, while at other times this is a reasonable abstraction." Wikipedia +> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. +> State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the +> case, while at other times this is a reasonable abstraction." Wikipedia -Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml. +Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make +it easier for users to share diagrams between mermaid and plantUml. ```mermaid-example +--- +title: Simple sample +--- stateDiagram-v2 [*] --> Still Still --> [*] @@ -22,6 +28,9 @@ stateDiagram-v2 ``` ```mermaid +--- +title: Simple sample +--- stateDiagram-v2 [*] --> Still Still --> [*] @@ -56,20 +65,23 @@ stateDiagram Crash --> [*] ``` -In state diagrams systems are described in terms of its states and how the systems state can change to another state via a transitions. The example diagram above shows three states **Still**, **Moving** and **Crash**. You start in the state of Still. From Still you can change the state to Moving. In Moving you can change the state either back to Still or to Crash. There is no transition from Still to Crash. +In state diagrams systems are described in terms of _states_ and how one _state_ can change to another _state_ via +a _transition._ The example diagram above shows three states: **Still**, **Moving** and **Crash**. You start in the +**Still** state. From **Still** you can change to the **Moving** state. From **Moving** you can change either back to the **Still** state or to +the **Crash** state. There is no transition from **Still** to **Crash**. (You can't crash if you're still.) ## States -A state can be declared in multiple ways. The simplest way is to define a state id as a description. +A state can be declared in multiple ways. The simplest way is to define a state with just an id: ```mermaid-example stateDiagram-v2 - s1 + stateId ``` ```mermaid stateDiagram-v2 - s1 + stateId ``` Another way is by using the state keyword with a description as per below: @@ -100,7 +112,8 @@ stateDiagram-v2 Transitions are path/edges when one state passes into another. This is represented using text arrow, "-->". -When you define a transition between two states and the states are not already defined the undefined states are defined with the id from the transition. You can later add descriptions to states defined this way. +When you define a transition between two states and the states are not already defined, the undefined states are defined +with the id from the transition. You can later add descriptions to states defined this way. ```mermaid-example stateDiagram-v2 @@ -112,7 +125,7 @@ stateDiagram-v2 s1 --> s2 ``` -It is possible to add text to a transition. To describe what it represents. +It is possible to add text to a transition to describe what it represents: ```mermaid-example stateDiagram-v2 @@ -126,7 +139,8 @@ stateDiagram-v2 ## Start and End -There are two special states indicating the start and stop of the diagram. These are written with the \[\*] syntax and the direction of the transition to it defines it either as a start or a stop state. +There are two special states indicating the start and stop of the diagram. These are written with the \[\*] syntax and +the direction of the transition to it defines it either as a start or a stop state. ```mermaid-example stateDiagram-v2 @@ -142,10 +156,11 @@ stateDiagram-v2 ## Composite states -In a real world use of state diagrams you often end up with diagrams that are multi-dimensional as one state can +In a real world use of state diagrams you often end up with diagrams that are multidimensional as one state can have several internal states. These are called composite states in this terminology. -In order to define a composite state you need to use the state keyword followed by an id and the body of the composite state between {}. See the example below: +In order to define a composite state you need to use the state keyword followed by an id and the body of the composite +state between {}. See the example below: ```mermaid-example stateDiagram-v2 @@ -305,7 +320,7 @@ It is possible to specify a fork in the diagram using <\> <\>. ## Notes -Sometimes nothing says it better then a Post-it note. That is also the case in state diagrams. +Sometimes nothing says it better than a Post-it note. That is also the case in state diagrams. Here you can choose to put the note to the _right of_ or to the _left of_ a node. @@ -375,7 +390,8 @@ stateDiagram-v2 ## Setting the direction of the diagram -With state diagrams you can use the direction statement to set the direction which the diagram will render like in this example. +With state diagrams you can use the direction statement to set the direction which the diagram will render like in this +example. ```mermaid-example stateDiagram @@ -405,7 +421,9 @@ stateDiagram ## Comments -Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax +Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their +own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next +newline will be treated as a comment, including any diagram syntax ```mermaid-example stateDiagram-v2 @@ -429,22 +447,204 @@ stateDiagram-v2 Crash --> [*] ``` -## Styling +## Styling with classDefs -Styling of the a state diagram is done by defining a number of css classes. During rendering these classes are extracted from the file located at src/themes/state.scss +As with other diagrams (like flowcharts), you can define a style in the diagram itself and apply that named style to a +state or states in the diagram. + +**These are the current limitations with state diagram classDefs:** + +1. Cannot be applied to start or end states +2. Cannot be applied to or within composite states + +_These are in development and will be available in a future version._ + +You define a style using the `classDef` keyword, which is short for "class definition" (where "class" means something +like a _CSS class_) +followed by _a name for the style,_ +and then one or more _property-value pairs_. Each _property-value pair_ is +a _[valid CSS property name](https://www.w3.org/TR/CSS/#properties)_ followed by a colon (`:`) and then a _value._ + +Here is an example of a classDef with just one property-value pair: + + classDef movement font-style:italic; + +where + +- the _name_ of the style is `movement` +- the only _property_ is `font-style` and its _value_ is `italic` + +If you want to have more than one _property-value pair_ then you put a comma (`,`) between each _property-value pair._ + +Here is an example with three property-value pairs: + + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + +where + +- the _name_ of the style is `badBadEvent` +- the first _property_ is `fill` and its _value_ is `#f00` +- the second _property_ is `color` and its _value_ is `white` +- the third _property_ is `font-weight` and its _value_ is `bold` +- the fourth _property_ is `stroke-width` and its _value_ is `2px` +- the fifth _property_ is `stroke` and its _value_ is `yello` + +### Apply classDef styles to states + +There are two ways to apply a `classDef` style to a state: + +1. use the `class` keyword to apply a classDef style to one or more states in a single statement, or +2. use the `:::` operator to apply a classDef style to a state as it is being used in a transition statement (e.g. with an arrow + to/from another state) + +#### 1. `class` statement + +A `class` statement tells Mermaid to apply the named classDef to one or more classes. The form is: + +```text + class [one or more state names, separated by commas] [name of a style defined with classDef] +``` + +Here is an example applying the `badBadEvent` style to a state named `Crash`: + +```text +class Crash badBadEvent +``` + +Here is an example applying the `movement` style to the two states `Moving` and `Crash`: + +```text +class Moving, Crash movement +``` + +Here is a diagram that shows the examples in use. Note that the `Crash` state has two classDef styles applied: `movement` +and `badBadEvent` + +```mermaid-example + stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*]--> Still + Still --> [*] + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] + + class Still notMoving + class Moving, Crash movement + class Crash badBadEvent + class end badBadEvent +``` + +```mermaid + stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*]--> Still + Still --> [*] + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] + + class Still notMoving + class Moving, Crash movement + class Crash badBadEvent + class end badBadEvent +``` + +#### 2. `:::` operator to apply a style to a state + +You can apply a classDef style to a state using the `:::` (three colons) operator. The syntax is + +```text +[state]:::[style name] +``` + +You can use this in a diagram within a statement using a class. This includes the start and end states. For example: + +```mermaid-example +stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic; + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*] --> Still:::notMoving + Still --> [*] + Still --> Moving:::movement + Moving --> Still + Moving --> Crash:::movement + Crash:::badBadEvent --> [*] +``` + +```mermaid +stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic; + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*] --> Still:::notMoving + Still --> [*] + Still --> Moving:::movement + Moving --> Still + Moving --> Crash:::movement + Crash:::badBadEvent --> [*] +``` ## Spaces in state names -Spaces can be added to a state by defining it at the top and referencing the acronym later. +Spaces can be added to a state by first defining the state with an id and then referencing the id later. + +In the following example there is a state with the id **yswsii** and description **Your state with spaces in it**. +After it has been defined, **yswsii** is used in the diagram in the first transition (`[*] --> yswsii`) +and also in the transition to **YetAnotherState** (`yswsii --> YetAnotherState`).\ +(**yswsii** has been styled so that it is different from the other states.) ```mermaid-example -stateDiagram-v2 - Yswsii: Your state with spaces in it - [*] --> Yswsii +stateDiagram + classDef yourState font-style:italic,font-weight:bold,fill:white + + yswsii: Your state with spaces in it + [*] --> yswsii:::yourState + [*] --> SomeOtherState + SomeOtherState --> YetAnotherState + yswsii --> YetAnotherState + YetAnotherState --> [*] ``` ```mermaid -stateDiagram-v2 - Yswsii: Your state with spaces in it - [*] --> Yswsii +stateDiagram + classDef yourState font-style:italic,font-weight:bold,fill:white + + yswsii: Your state with spaces in it + [*] --> yswsii:::yourState + [*] --> SomeOtherState + SomeOtherState --> YetAnotherState + yswsii --> YetAnotherState + YetAnotherState --> [*] ``` diff --git a/package.json b/package.json index 401408109..31d89a63e 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "version": "9.2.2", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "type": "module", - "packageManager": "pnpm@7.15.0", + "packageManager": "pnpm@7.17.0", "keywords": [ "diagram", "markdown", @@ -15,8 +15,9 @@ "git graph" ], "scripts": { - "build:mermaid": "ts-node-esm --transpileOnly .vite/build.ts --mermaid", "build:vite": "ts-node-esm --transpileOnly .vite/build.ts", + "build:mermaid": "pnpm build:vite --mermaid", + "build:viz": "pnpm build:mermaid --visualize", "build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly", "build:watch": "pnpm build:vite --watch", "build": "pnpm run -r clean && concurrently \"pnpm build:vite\" \"pnpm build:types\"", @@ -53,57 +54,61 @@ ] }, "devDependencies": { - "@applitools/eyes-cypress": "3.27.6", - "@commitlint/cli": "17.2.0", - "@commitlint/config-conventional": "17.2.0", - "@cspell/eslint-plugin": "6.14.2", - "@types/eslint": "8.4.10", - "@types/express": "4.17.14", - "@types/jsdom": "20.0.1", - "@types/lodash": "4.14.188", - "@types/mdast": "3.0.10", + "@applitools/eyes-cypress": "^3.27.6", + "@commitlint/cli": "^17.2.0", + "@commitlint/config-conventional": "^17.2.0", + "@cspell/eslint-plugin": "^6.14.2", + "@types/eslint": "^8.4.10", + "@types/express": "^4.17.14", + "@types/jsdom": "^20.0.1", + "@types/js-yaml": "^4.0.5", + "@types/lodash": "^4.14.188", + "@types/mdast": "^3.0.10", "@types/node": "^18.11.9", - "@types/prettier": "2.7.1", - "@typescript-eslint/eslint-plugin": "5.42.1", - "@typescript-eslint/parser": "5.42.1", - "@vitest/coverage-c8": "0.25.1", - "@vitest/ui": "0.25.1", - "concurrently": "7.5.0", - "coveralls": "3.1.1", - "cypress": "10.11.0", - "cypress-image-snapshot": "4.0.1", - "esbuild": "0.15.13", - "eslint": "8.27.0", - "eslint-config-prettier": "8.5.0", - "eslint-plugin-cypress": "2.12.1", - "eslint-plugin-html": "7.1.0", - "eslint-plugin-jest": "27.1.5", - "eslint-plugin-jsdoc": "39.6.2", - "eslint-plugin-json": "3.1.0", - "eslint-plugin-markdown": "3.0.0", - "eslint-plugin-no-only-tests": "3.1.0", - "eslint-plugin-tsdoc": "0.2.17", - "express": "4.18.2", - "globby": "13.1.2", - "husky": "8.0.2", - "identity-obj-proxy": "3.0.0", - "jest": "29.3.1", - "jison": "0.4.18", - "jsdom": "20.0.2", - "lint-staged": "13.0.3", - "path-browserify": "1.0.1", - "pnpm": "7.15.0", - "prettier": "2.7.1", - "prettier-plugin-jsdoc": "0.4.2", - "rimraf": "3.0.2", - "start-server-and-test": "1.14.0", - "ts-node": "10.9.1", - "typescript": "4.8.4", - "vite": "3.2.3", - "vitest": "0.25.1" - }, - "resolutions": { - "d3": "7.6.1" + "@types/prettier": "^2.7.1", + "@types/rollup-plugin-visualizer": "^4.2.1", + "@typescript-eslint/eslint-plugin": "^5.42.1", + "@typescript-eslint/parser": "^5.42.1", + "@vitest/coverage-c8": "^0.25.1", + "@vitest/ui": "^0.25.1", + "concurrently": "^7.5.0", + "coveralls": "^3.1.1", + "cypress": "^10.11.0", + "cypress-image-snapshot": "^4.0.1", + "esbuild": "^0.15.13", + "eslint": "^8.27.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-cypress": "^2.12.1", + "eslint-plugin-html": "^7.1.0", + "eslint-plugin-jest": "^27.1.5", + "eslint-plugin-jsdoc": "^39.6.2", + "eslint-plugin-json": "^3.1.0", + "eslint-plugin-markdown": "^3.0.0", + "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-tsdoc": "^0.2.17", + "express": "^4.18.2", + "globby": "^13.1.2", + "husky": "^8.0.2", + "identity-obj-proxy": "^3.0.0", + "jest": "^29.3.1", + "jison": "^0.4.18", + "jsdom": "^20.0.2", + "js-yaml": "^4.1.0", + "lint-staged": "^13.0.3", + "path-browserify": "^1.0.1", + "pnpm": "^7.15.0", + "prettier": "^2.7.1", + "prettier-plugin-jsdoc": "^0.4.2", + "rimraf": "^3.0.2", + "rollup-plugin-visualizer": "^5.8.3", + "start-server-and-test": "^1.14.0", + "ts-node": "^10.9.1", + "typescript": "^4.8.4", + "vite": "^3.2.3", + "vitepress": "^1.0.0-alpha.28", + "vitepress-plugin-mermaid": "^2.0.8", + "vitepress-plugin-search": "^1.0.4-alpha.15", + "vitest": "^0.25.1" }, "sideEffects": [ "**/*.css", @@ -112,4 +117,4 @@ "volta": { "node": "18.12.1" } -} +} \ No newline at end of file diff --git a/packages/mermaid-example-diagram/package.json b/packages/mermaid-example-diagram/package.json index f05a0bb49..8e958806a 100644 --- a/packages/mermaid-example-diagram/package.json +++ b/packages/mermaid-example-diagram/package.json @@ -50,8 +50,8 @@ }, "dependencies": {}, "devDependencies": { - "concurrently": "7.5.0", - "rimraf": "3.0.2" + "concurrently": "^7.5.0", + "rimraf": "^3.0.2" }, "resolutions": { "d3": "^7.0.0" diff --git a/packages/mermaid-mindmap/package.json b/packages/mermaid-mindmap/package.json index 43dcf49fc..852c0871b 100644 --- a/packages/mermaid-mindmap/package.json +++ b/packages/mermaid-mindmap/package.json @@ -47,9 +47,9 @@ "non-layered-tidy-tree-layout": "^2.0.2" }, "devDependencies": { - "concurrently": "7.5.0", + "concurrently": "^7.5.0", "mermaid": "workspace:*", - "rimraf": "3.0.2" + "rimraf": "^3.0.2" }, "resolutions": { "d3": "^7.0.0" diff --git a/packages/mermaid-mindmap/src/mindmap.spec.js b/packages/mermaid-mindmap/src/mindmap.spec.js index b9e9abf6e..e3f018350 100644 --- a/packages/mermaid-mindmap/src/mindmap.spec.js +++ b/packages/mermaid-mindmap/src/mindmap.spec.js @@ -172,6 +172,18 @@ root expect(mm.children.length).toEqual(0); expect(mm.type).toEqual(mindmap.yy.nodeType.BANG); }); + + it('MMP-12-a mutiple types (hexagon)', function () { + let str = `mindmap + root{{the root}} +`; + + mindmap.parse(str); + const mm = mindmap.yy.getMindmap(); + expect(mm.type).toEqual(mindmap.yy.nodeType.HEXAGON); + expect(mm.descr).toEqual('the root'); + expect(mm.children.length).toEqual(0); + }); }); describe('decorations', function () { it('MMP-13 should be possible to set an icon for the node', function () { diff --git a/packages/mermaid-mindmap/src/mindmapDb.js b/packages/mermaid-mindmap/src/mindmapDb.js index 2ae98c223..16861cd23 100644 --- a/packages/mermaid-mindmap/src/mindmapDb.js +++ b/packages/mermaid-mindmap/src/mindmapDb.js @@ -42,6 +42,9 @@ export const addNode = (level, id, descr, type) => { case nodeType.RECT: node.padding = 2 * conf.mindmap.padding; break; + case nodeType.HEXAGON: + node.padding = 2 * conf.mindmap.padding; + break; default: node.padding = conf.mindmap.padding; } @@ -79,6 +82,7 @@ export const nodeType = { CIRCLE: 3, CLOUD: 4, BANG: 5, + HEXAGON: 6, }; export const getType = (startStr, endStr) => { @@ -94,6 +98,8 @@ export const getType = (startStr, endStr) => { return nodeType.CLOUD; case '))': return nodeType.BANG; + case '{{': + return nodeType.HEXAGON; default: return nodeType.DEFAULT; } @@ -127,6 +133,8 @@ export const type2Str = (type) => { return 'cloud'; case nodeType.BANG: return 'bang'; + case nodeType.HEXAGON: + return 'hexgon'; default: return 'no-border'; } diff --git a/packages/mermaid-mindmap/src/mindmapRenderer.js b/packages/mermaid-mindmap/src/mindmapRenderer.js index c0760e4ac..9fd557e51 100644 --- a/packages/mermaid-mindmap/src/mindmapRenderer.js +++ b/packages/mermaid-mindmap/src/mindmapRenderer.js @@ -92,10 +92,6 @@ function addNodes(mindmap, cy, conf, level) { */ function layoutMindmap(node, conf) { return new Promise((resolve) => { - if (node.children.length === 0) { - return node; - } - // Add temporary render element const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none'); const cy = cytoscape({ diff --git a/packages/mermaid-mindmap/src/parser/mindmap.jison b/packages/mermaid-mindmap/src/parser/mindmap.jison index bd008db7f..a96ee6261 100644 --- a/packages/mermaid-mindmap/src/parser/mindmap.jison +++ b/packages/mermaid-mindmap/src/parser/mindmap.jison @@ -33,11 +33,12 @@ "))" { 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'; } "[" { this.begin('NODE');return 'NODE_DSTART'; } [\s]+ return 'SPACELIST' /* skip all whitespace */ ; // !(-\() return 'NODE_ID'; -[^\(\[\n\-\)]+ return 'NODE_ID'; +[^\(\[\n\-\)\{\}]+ return 'NODE_ID'; <> return 'EOF'; ["] { yy.getLogger().trace('Starting NSTR');this.begin("NSTR");} [^"]+ { yy.getLogger().trace('description:', yytext); return "NODE_DESCR";} @@ -45,11 +46,12 @@ [\)]\) {this.popState();yy.getLogger().trace('node end ))');return "NODE_DEND";} [\)] {this.popState();yy.getLogger().trace('node end )');return "NODE_DEND";} [\]] {this.popState();yy.getLogger().trace('node end ...',yytext);return "NODE_DEND";} +"}}" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} "(-" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";} "-)" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";} "((" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} -"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} -[^\)\]\(]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';} +"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} +[^\)\]\(\}]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';} .+(?!\(\() { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';} // [\[] return 'NODE_START'; // .+ return 'TXT' ; diff --git a/packages/mermaid-mindmap/src/styles.js b/packages/mermaid-mindmap/src/styles.js index a409aa4e5..986a04514 100644 --- a/packages/mermaid-mindmap/src/styles.js +++ b/packages/mermaid-mindmap/src/styles.js @@ -17,7 +17,7 @@ const genSections = (options) => { sections += ` .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${ i - 1 - } path { + } polygon, .section-${i - 1} path { fill: ${options['cScale' + i]}; } .section-${i - 1} text { @@ -55,7 +55,7 @@ const getStyles = (options) => stroke-width: 3; } ${genSections(options)} - .section-root rect, .section-root path, .section-root circle { + .section-root rect, .section-root path, .section-root circle, .section-root polygon { fill: ${options.git0}; } .section-root text { diff --git a/packages/mermaid-mindmap/src/svgDraw.js b/packages/mermaid-mindmap/src/svgDraw.js index 314503b20..d4f57f1f1 100644 --- a/packages/mermaid-mindmap/src/svgDraw.js +++ b/packages/mermaid-mindmap/src/svgDraw.js @@ -145,6 +145,45 @@ const circleBkg = function (elem, node) { .attr('class', 'node-bkg node-' + db.type2Str(node.type)) .attr('r', node.width / 2); }; + +/** + * + * @param parent + * @param w + * @param h + * @param points + * @param node + */ +function insertPolygonShape(parent, w, h, points, node) { + return parent + .insert('polygon', ':first-child') + .attr( + 'points', + points + .map(function (d) { + return d.x + ',' + d.y; + }) + .join(' ') + ) + .attr('transform', 'translate(' + (node.width - w) / 2 + ', ' + h + ')'); +} + +const hexagonBkg = function (elem, node) { + const h = node.height; + const f = 4; + const m = h / f; + const w = node.width - node.padding + 2 * m; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 }, + ]; + const shapeSvg = insertPolygonShape(elem, w, h, points, node); +}; + const roundedRectBkg = function (elem, node) { elem .append('rect') @@ -252,6 +291,9 @@ export const drawNode = function (elem, node, fullSection, conf) { case db.nodeType.BANG: bangBkg(bkgElem, node, section, conf); break; + case db.nodeType.HEXAGON: + hexagonBkg(bkgElem, node, section, conf); + break; } // Position the node to its coordinate diff --git a/packages/mermaid/README.md b/packages/mermaid/README.md index 90ae1ad4c..91c2d1640 100644 --- a/packages/mermaid/README.md +++ b/packages/mermaid/README.md @@ -1,23 +1,6 @@ # mermaid -[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) - -# Whoa, what's 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 some changes.. - -# We use pnpm now - -# The source code has moved - -It is now located in the src folder for each respective package located as subfolders in packages. +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) English | [简体中文](./README.zh-CN.md) diff --git a/packages/mermaid/README.zh-CN.md b/packages/mermaid/README.zh-CN.md index fcaa1f523..0ccef27e4 100644 --- a/packages/mermaid/README.zh-CN.md +++ b/packages/mermaid/README.zh-CN.md @@ -1,6 +1,6 @@ # mermaid -[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) [English](./README.md) | 简体中文 diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index aa7b15524..5e6ce9992 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -54,8 +54,7 @@ "dependencies": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", - "dagre": "^0.8.5", - "dagre-d3": "^0.6.4", + "dagre-d3-es": "7.0.2", "dompurify": "2.4.1", "graphlib": "^2.1.8", "khroma": "^2.0.0", @@ -66,41 +65,37 @@ "uuid": "^9.0.0" }, "devDependencies": { - "@types/d3": "7.4.0", - "@types/dompurify": "2.4.0", - "@types/jsdom": "20.0.1", - "@types/lodash": "4.14.188", - "@types/micromatch": "4.0.2", - "@types/prettier": "2.7.1", - "@types/stylis": "4.0.2", - "@types/uuid": "8.3.4", - "@typescript-eslint/eslint-plugin": "5.42.1", - "@typescript-eslint/parser": "5.42.1", - "chokidar": "3.5.3", - "concurrently": "7.5.0", - "coveralls": "3.1.1", - "globby": "13.1.2", - "identity-obj-proxy": "3.0.0", - "jison": "0.4.18", - "js-base64": "3.7.2", - "jsdom": "20.0.2", + "@types/d3": "^7.4.0", + "@types/dompurify": "^2.4.0", + "@types/jsdom": "^20.0.1", + "@types/lodash": "^4.14.188", + "@types/micromatch": "^4.0.2", + "@types/prettier": "^2.7.1", + "@types/stylis": "^4.0.2", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^5.42.1", + "@typescript-eslint/parser": "^5.42.1", + "chokidar": "^3.5.3", + "concurrently": "^7.5.0", + "coveralls": "^3.1.1", + "globby": "^13.1.2", + "identity-obj-proxy": "^3.0.0", + "jison": "^0.4.18", + "js-base64": "^3.7.2", + "jsdom": "^20.0.2", "micromatch": "^4.0.5", - "moment": "2.29.4", - "path-browserify": "1.0.1", - "prettier": "2.7.1", - "remark": "14.0.2", - "rimraf": "3.0.2", - "shiki": "0.11.1", - "start-server-and-test": "1.14.0", - "typedoc": "0.23.18", - "typedoc-plugin-markdown": "3.13.6", - "typescript": "4.8.4", - "unist-util-flatmap": "1.0.0", - "vitepress": "1.0.0-alpha.28", - "vitepress-plugin-search": "1.0.4-alpha.15" - }, - "resolutions": { - "d3": "^7.0.0" + "moment": "^2.29.4", + "path-browserify": "^1.0.1", + "prettier": "^2.7.1", + "remark": "^14.0.2", + "rimraf": "^3.0.2", + "start-server-and-test": "^1.14.0", + "typedoc": "^0.23.18", + "typedoc-plugin-markdown": "^3.13.6", + "typescript": "^4.8.4", + "unist-util-flatmap": "^1.0.0", + "vitepress": "^1.0.0-alpha.28", + "vitepress-plugin-search": "^1.0.4-alpha.15" }, "files": [ "dist", diff --git a/packages/mermaid/src/Diagram.ts b/packages/mermaid/src/Diagram.ts index 798adf501..a2349c255 100644 --- a/packages/mermaid/src/Diagram.ts +++ b/packages/mermaid/src/Diagram.ts @@ -2,6 +2,7 @@ import * as configApi from './config'; import { log } from './logger'; import { getDiagram, registerDiagram } from './diagram-api/diagramAPI'; import { detectType, getDiagramLoader } from './diagram-api/detectType'; +import { extractFrontMatter } from './diagram-api/frontmatter'; import { isDetailedError, type DetailedError } from './utils'; export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void; @@ -29,6 +30,16 @@ export class Diagram { this.db.clear?.(); this.renderer = diagram.renderer; this.parser = diagram.parser; + const originalParse = this.parser.parse.bind(this.parser); + // Wrap the jison parse() method to handle extracting frontmatter. + // + // This can't be done in this.parse() because some code + // directly calls diagram.parser.parse(), bypassing this.parse(). + // + // Similarly, we can't do this in getDiagramFromText() because some code + // calls diagram.db.clear(), which would reset anything set by + // extractFrontMatter(). + this.parser.parse = (text: string) => originalParse(extractFrontMatter(text, this.db)); this.parser.parser.yy = this.db; if (diagram.init) { diagram.init(cnf); @@ -45,7 +56,7 @@ export class Diagram { } try { text = text + '\n'; - this.db.clear(); + this.db.clear?.(); this.parser.parse(text); return true; } catch (error) { diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index cbcd2f661..ff199ca8b 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -189,6 +189,7 @@ export interface C4DiagramConfig extends BaseDiagramConfig { } export interface GitGraphDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; diagramPadding?: number; nodeLabel?: NodeLabel; mainBranchName?: string; @@ -227,6 +228,7 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig { export type PieDiagramConfig = BaseDiagramConfig; export interface ErDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; diagramPadding?: number; layoutDirection?: string; minEntityWidth?: number; @@ -238,6 +240,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig { } export interface StateDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; arrowMarkerAbsolute?: boolean; dividerMargin?: number; sizeUnit?: number; @@ -258,6 +261,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig { } export interface ClassDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; arrowMarkerAbsolute?: boolean; dividerMargin?: number; padding?: number; @@ -343,6 +347,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig { } export interface FlowchartDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; arrowMarkerAbsolute?: boolean; diagramPadding?: number; htmlLabels?: boolean; diff --git a/packages/mermaid/src/dagre-wrapper/index.js b/packages/mermaid/src/dagre-wrapper/index.js index 72652ff8c..43fe311b3 100644 --- a/packages/mermaid/src/dagre-wrapper/index.js +++ b/packages/mermaid/src/dagre-wrapper/index.js @@ -1,4 +1,4 @@ -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import graphlib from 'graphlib'; import insertMarkers from './markers'; import { updateNodeBounds } from './shapes/util'; @@ -95,7 +95,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => { log.info('### Layout ###'); log.info('#############################################'); log.info(graph); - dagre.layout(graph); + dagreLayout(graph); log.info('Graph after layout:', graphlib.json.write(graph)); // Move the nodes to the correct place let diff = 0; diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js index 8155bbf70..a09e17f02 100644 --- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js +++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js @@ -1,5 +1,4 @@ import graphlib from 'graphlib'; -import dagre from 'dagre'; import { validate, adjustClustersAndEdges, diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts index 2ddae580c..37d4f71ff 100644 --- a/packages/mermaid/src/defaultConfig.ts +++ b/packages/mermaid/src/defaultConfig.ts @@ -154,6 +154,17 @@ const config: Partial = { /** The object containing configurations specific for flowcharts */ flowchart: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the flowchart | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, + /** * | Parameter | Description | Type | Required | Values | * | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ | @@ -851,6 +862,16 @@ const config: Partial = { sectionColours: ['#fff'], }, class: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the class diagram | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, arrowMarkerAbsolute: false, dividerMargin: 10, padding: 5, @@ -884,6 +905,16 @@ const config: Partial = { defaultRenderer: 'dagre-wrapper', }, state: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the state diagram | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, dividerMargin: 10, sizeUnit: 5, padding: 8, @@ -932,6 +963,17 @@ const config: Partial = { /** The object containing configurations specific for entity relationship diagrams */ er: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the diagram | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, + /** * | Parameter | Description | Type | Required | Values | * | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ | @@ -1085,6 +1127,16 @@ const config: Partial = { line_height: 20, }, gitGraph: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the Git diagram | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, diagramPadding: 8, nodeLabel: { width: 75, diff --git a/packages/mermaid/src/diagram-api/detectType.ts b/packages/mermaid/src/diagram-api/detectType.ts index 1c1abc51c..6f9857221 100644 --- a/packages/mermaid/src/diagram-api/detectType.ts +++ b/packages/mermaid/src/diagram-api/detectType.ts @@ -1,6 +1,7 @@ import { MermaidConfig } from '../config.type'; import { log } from '../logger'; import { DetectorRecord, DiagramDetector, DiagramLoader } from './types'; +import { frontMatterRegex } from './frontmatter'; const directive = /[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi; @@ -31,7 +32,7 @@ const detectors: Record = {}; * @returns A graph definition key */ export const detectType = function (text: string, config?: MermaidConfig): string { - text = text.replace(directive, '').replace(anyComment, '\n'); + text = text.replace(frontMatterRegex, '').replace(directive, '').replace(anyComment, '\n'); for (const [key, { detector }] of Object.entries(detectors)) { const diagram = detector(text, config); if (diagram) { diff --git a/packages/mermaid/src/diagram-api/frontmatter.spec.ts b/packages/mermaid/src/diagram-api/frontmatter.spec.ts new file mode 100644 index 000000000..4eb9789e2 --- /dev/null +++ b/packages/mermaid/src/diagram-api/frontmatter.spec.ts @@ -0,0 +1,78 @@ +import { vi } from 'vitest'; +import { extractFrontMatter } from './frontmatter'; + +const dbMock = () => ({ setDiagramTitle: vi.fn() }); + +describe('extractFrontmatter', () => { + it('returns text unchanged if no frontmatter', () => { + expect(extractFrontMatter('diagram', dbMock())).toEqual('diagram'); + }); + + it('returns text unchanged if frontmatter lacks closing delimiter', () => { + const text = `---\ntitle: foo\ndiagram`; + expect(extractFrontMatter(text, dbMock())).toEqual(text); + }); + + it('handles empty frontmatter', () => { + const db = dbMock(); + const text = `---\n\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).not.toHaveBeenCalled(); + }); + + it('handles frontmatter without mappings', () => { + const db = dbMock(); + const text = `---\n1\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).not.toHaveBeenCalled(); + }); + + it('does not try to parse frontmatter at the end', () => { + const db = dbMock(); + const text = `diagram\n---\ntitle: foo\n---\n`; + expect(extractFrontMatter(text, db)).toEqual(text); + expect(db.setDiagramTitle).not.toHaveBeenCalled(); + }); + + it('handles frontmatter with multiple delimiters', () => { + const db = dbMock(); + const text = `---\ntitle: foo---bar\n---\ndiagram\n---\ntest`; + expect(extractFrontMatter(text, db)).toEqual('diagram\n---\ntest'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('foo---bar'); + }); + + it('handles frontmatter with multi-line string and multiple delimiters', () => { + const db = dbMock(); + const text = `---\ntitle: |\n multi-line string\n ---\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('multi-line string\n---\n'); + }); + + it('handles frontmatter with title', () => { + const db = dbMock(); + const text = `---\ntitle: foo\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('foo'); + }); + + it('handles booleans in frontmatter properly', () => { + const db = dbMock(); + const text = `---\ntitle: true\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('true'); + }); + + it('ignores unspecified frontmatter keys', () => { + const db = dbMock(); + const text = `---\ninvalid: true\ntitle: foo\ntest: bar\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('foo'); + }); + + it('throws exception for invalid YAML syntax', () => { + const text = `---\n!!!\n---\ndiagram`; + expect(() => extractFrontMatter(text, dbMock())).toThrow( + 'tag suffix cannot contain exclamation marks' + ); + }); +}); diff --git a/packages/mermaid/src/diagram-api/frontmatter.ts b/packages/mermaid/src/diagram-api/frontmatter.ts new file mode 100644 index 000000000..800e7399b --- /dev/null +++ b/packages/mermaid/src/diagram-api/frontmatter.ts @@ -0,0 +1,40 @@ +import { DiagramDb } from './types'; +// The "* as yaml" part is necessary for tree-shaking +import * as yaml from 'js-yaml'; + +// Match Jekyll-style front matter blocks (https://jekyllrb.com/docs/front-matter/). +// Based on regex used by Jekyll: https://github.com/jekyll/jekyll/blob/6dd3cc21c40b98054851846425af06c64f9fb466/lib/jekyll/document.rb#L10 +// Note that JS doesn't support the "\A" anchor, which means we can't use +// multiline mode. +// Relevant YAML spec: https://yaml.org/spec/1.2.2/#914-explicit-documents +export const frontMatterRegex = /^(?:---\s*[\r\n])(.*?)(?:[\r\n]---\s*[\r\n]+)/s; + +type FrontMatterMetadata = { + title?: string; +}; + +/** + * Extract and parse frontmatter from text, if present, and sets appropriate + * properties in the provided db. + * @param text - The text that may have a YAML frontmatter. + * @param db - Diagram database, could be of any diagram. + * @returns text with frontmatter stripped out + */ +export function extractFrontMatter(text: string, db: DiagramDb): string { + const matches = text.match(frontMatterRegex); + if (matches) { + const parsed: FrontMatterMetadata = yaml.load(matches[1], { + // To keep things simple, only allow strings, arrays, and plain objects. + // https://www.yaml.org/spec/1.2/spec.html#id2802346 + schema: yaml.FAILSAFE_SCHEMA, + }) as FrontMatterMetadata; + + if (parsed?.title) { + db.setDiagramTitle?.(parsed.title); + } + + return text.slice(matches[0].length); + } else { + return text; + } +} diff --git a/packages/mermaid/src/diagram-api/types.ts b/packages/mermaid/src/diagram-api/types.ts index d45eac6aa..23810d133 100644 --- a/packages/mermaid/src/diagram-api/types.ts +++ b/packages/mermaid/src/diagram-api/types.ts @@ -8,8 +8,16 @@ export interface InjectUtils { _setupGraphViewbox: any; } +/** + * Generic Diagram DB that may apply to any diagram type. + */ +export interface DiagramDb { + clear?: () => void; + setDiagramTitle?: (title: string) => void; +} + export interface DiagramDefinition { - db: any; + db: DiagramDb; renderer: any; parser: any; styles: any; diff --git a/packages/mermaid/src/diagrams/class/classDb.js b/packages/mermaid/src/diagrams/class/classDb.js index 83ef6072b..9830c059e 100644 --- a/packages/mermaid/src/diagrams/class/classDb.js +++ b/packages/mermaid/src/diagrams/class/classDb.js @@ -10,6 +10,8 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; const MERMAID_DOM_ID_PREFIX = 'classid-'; @@ -408,4 +410,6 @@ export default { getTooltip, setTooltip, lookUpDomId, + setDiagramTitle, + getDiagramTitle, }; diff --git a/packages/mermaid/src/diagrams/class/classRenderer-v2.js b/packages/mermaid/src/diagrams/class/classRenderer-v2.js index fbc2e4833..bca3c01c8 100644 --- a/packages/mermaid/src/diagrams/class/classRenderer-v2.js +++ b/packages/mermaid/src/diagrams/class/classRenderer-v2.js @@ -3,6 +3,7 @@ import graphlib from 'graphlib'; import { log } from '../../logger'; import { getConfig } from '../../config'; import { render } from '../../dagre-wrapper/index.js'; +import utils from '../../utils'; import { curveLinear } from 'd3'; import { interpolateToCurve, getStylesFromArray } from '../../utils'; import { setupGraphViewbox } from '../../setupGraphViewbox'; @@ -429,6 +430,8 @@ export const draw = function (text, id, _version, diagObj) { id ); + utils.insertTitle(svg, 'classTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle()); + setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth); // Add label rects for non html labels diff --git a/packages/mermaid/src/diagrams/class/classRenderer.js b/packages/mermaid/src/diagrams/class/classRenderer.js index 23b586192..357647427 100644 --- a/packages/mermaid/src/diagrams/class/classRenderer.js +++ b/packages/mermaid/src/diagrams/class/classRenderer.js @@ -1,5 +1,5 @@ import { select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import graphlib from 'graphlib'; import { log } from '../../logger'; import svgDraw from './svgDraw'; @@ -238,7 +238,7 @@ export const draw = function (text, id, _version, diagObj) { } }); - dagre.layout(g); + dagreLayout(g); g.nodes().forEach(function (v) { if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') { log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))); diff --git a/packages/mermaid/src/diagrams/class/styles.js b/packages/mermaid/src/diagrams/class/styles.js index bc391114e..981cd7b73 100644 --- a/packages/mermaid/src/diagrams/class/styles.js +++ b/packages/mermaid/src/diagrams/class/styles.js @@ -148,6 +148,11 @@ g.classGroup line { font-size: 11px; } +.classTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/er/erDb.js b/packages/mermaid/src/diagrams/er/erDb.js index ad3454f84..96b60836b 100644 --- a/packages/mermaid/src/diagrams/er/erDb.js +++ b/packages/mermaid/src/diagrams/er/erDb.js @@ -8,6 +8,8 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; let entities = {}; @@ -94,4 +96,6 @@ export default { getAccTitle, setAccDescription, getAccDescription, + setDiagramTitle, + getDiagramTitle, }; diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js index 323bb4607..d0771fe39 100644 --- a/packages/mermaid/src/diagrams/er/erRenderer.js +++ b/packages/mermaid/src/diagrams/er/erRenderer.js @@ -1,8 +1,9 @@ import graphlib from 'graphlib'; import { line, curveBasis, select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import { getConfig } from '../../config'; import { log } from '../../logger'; +import utils from '../../utils'; import erMarkers from './erMarkers'; import { configureSvgSize } from '../../setupGraphViewbox'; import addSVGAccessibilityFields from '../../accessibility'; @@ -210,9 +211,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { const typeRect = groupNode .insert('rect', '#' + attributeNode.tn.node().id) .classed(`er ${attribStyle}`, true) - .style('fill', conf.fill) - .style('fill-opacity', '100%') - .style('stroke', conf.stroke) .attr('x', 0) .attr('y', heightOffset) .attr('width', maxTypeWidth + widthPadding * 2 + spareColumnWidth) @@ -230,9 +228,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { const nameRect = groupNode .insert('rect', '#' + attributeNode.nn.node().id) .classed(`er ${attribStyle}`, true) - .style('fill', conf.fill) - .style('fill-opacity', '100%') - .style('stroke', conf.stroke) .attr('x', nameXOffset) .attr('y', heightOffset) .attr('width', maxNameWidth + widthPadding * 2 + spareColumnWidth) @@ -252,9 +247,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { const keyTypeRect = groupNode .insert('rect', '#' + attributeNode.kn.node().id) .classed(`er ${attribStyle}`, true) - .style('fill', conf.fill) - .style('fill-opacity', '100%') - .style('stroke', conf.stroke) .attr('x', keyTypeAndCommentXOffset) .attr('y', heightOffset) .attr('width', maxKeyWidth + widthPadding * 2 + spareColumnWidth) @@ -275,9 +267,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { groupNode .insert('rect', '#' + attributeNode.cn.node().id) .classed(`er ${attribStyle}`, 'true') - .style('fill', conf.fill) - .style('fill-opacity', '100%') - .style('stroke', conf.stroke) .attr('x', keyTypeAndCommentXOffset) .attr('y', heightOffset) .attr('width', maxCommentWidth + widthPadding * 2 + spareColumnWidth) @@ -347,9 +336,6 @@ const drawEntities = function (svgNode, entities, graph) { const rectNode = groupNode .insert('rect', '#' + textId) .classed('er entityBox', true) - .style('fill', conf.fill) - .style('fill-opacity', '100%') - .style('stroke', conf.stroke) .attr('x', 0) .attr('y', 0) .attr('width', entityWidth) @@ -547,9 +533,7 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { .attr('x', labelPoint.x - labelBBox.width / 2) .attr('y', labelPoint.y - labelBBox.height / 2) .attr('width', labelBBox.width) - .attr('height', labelBBox.height) - .style('fill', 'white') - .style('fill-opacity', '85%'); + .attr('height', labelBBox.height); }; /** @@ -637,7 +621,7 @@ export const draw = function (text, id, _version, diagObj) { // Add all the relationships to the graph const relationships = addRelationships(diagObj.db.getRelationships(), g); - dagre.layout(g); // Node and edge positions will be updated + dagreLayout(g); // Node and edge positions will be updated // Adjust the positions of the entities so that they adhere to the layout adjustEntities(svg, g); @@ -649,6 +633,8 @@ export const draw = function (text, id, _version, diagObj) { const padding = conf.diagramPadding; + utils.insertTitle(svg, 'entityTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle()); + const svgBounds = svg.node().getBBox(); const width = svgBounds.width + padding * 2; const height = svgBounds.height + padding * 2; diff --git a/packages/mermaid/src/diagrams/er/styles.js b/packages/mermaid/src/diagrams/er/styles.js index 907d813b6..7a525e28a 100644 --- a/packages/mermaid/src/diagrams/er/styles.js +++ b/packages/mermaid/src/diagrams/er/styles.js @@ -27,6 +27,12 @@ const getStyles = (options) => .relationshipLine { stroke: ${options.lineColor}; } + + .entityTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js b/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js index b66bfe730..d02d484c4 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js +++ b/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js @@ -1,4 +1,5 @@ -import dagreD3 from 'dagre-d3'; +import { intersectPolygon } from 'dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js'; +import { intersectRect } from 'dagre-d3-es/src/dagre-js/intersect/intersect-rect.js'; /** * @param parent @@ -17,7 +18,7 @@ function question(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, s, s, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -42,7 +43,7 @@ function hexagon(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -64,7 +65,7 @@ function rect_left_inv_arrow(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -85,7 +86,7 @@ function lean_right(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -106,7 +107,7 @@ function lean_left(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -127,7 +128,7 @@ function trapezoid(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -148,7 +149,7 @@ function inv_trapezoid(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -170,7 +171,7 @@ function rect_right_inv_arrow(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -194,7 +195,7 @@ function stadium(parent, bbox, node) { .attr('height', h); node.intersect = function (point) { - return dagreD3.intersect.rect(node, point); + return intersectRect(node, point); }; return shapeSvg; } @@ -221,7 +222,7 @@ function subroutine(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -270,7 +271,7 @@ function cylinder(parent, bbox, node) { .attr('transform', 'translate(' + -w / 2 + ',' + -(h / 2 + ry) + ')'); node.intersect = function (point) { - const pos = dagreD3.intersect.rect(node, point); + const pos = intersectRect(node, point); const x = pos.x - node.x; if ( diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.js b/packages/mermaid/src/diagrams/flowchart/flowDb.js index 6abc22659..38754c667 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.js +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.js @@ -10,6 +10,8 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; const MERMAID_DOM_ID_PREFIX = 'flowchart-'; @@ -785,4 +787,6 @@ export default { }, exists, makeUniq, + setDiagramTitle, + getDiagramTitle, }; diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js index 6b7c4c1bf..0a736b22b 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js @@ -3,9 +3,10 @@ import { select, curveLinear, selectAll } from 'd3'; import flowDb from './flowDb'; import { getConfig } from '../../config'; +import utils from '../../utils'; import { render } from '../../dagre-wrapper/index.js'; -import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; +import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js'; import { log } from '../../logger'; import common, { evaluate } from '../common/common'; import { interpolateToCurve, getStylesFromArray } from '../../utils'; @@ -437,6 +438,8 @@ export const draw = function (text, id, _version, diagObj) { const element = root.select('#' + id + ' g'); render(element, g, ['point', 'circle', 'cross'], 'flowchart', id); + utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle()); + setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth); // Index nodes diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js index c403b7fe3..0fcbce545 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js @@ -1,8 +1,9 @@ import graphlib from 'graphlib'; import { select, curveLinear, selectAll } from 'd3'; import { getConfig } from '../../config'; -import dagreD3 from 'dagre-d3'; -import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; +import { render as Render } from 'dagre-d3-es'; +import { applyStyle } from 'dagre-d3-es/src/dagre-js/util.js'; +import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js'; import { log } from '../../logger'; import common, { evaluate } from '../common/common'; import { interpolateToCurve, getStylesFromArray } from '../../utils'; @@ -370,7 +371,6 @@ export const draw = function (text, id, _version, diagObj) { addEdges(edges, g, diagObj); // Create the renderer - const Render = dagreD3.render; const render = new Render(); // Add custom shapes @@ -390,7 +390,7 @@ export const draw = function (text, id, _version, diagObj) { .attr('orient', 'auto'); const path = marker.append('path').attr('d', 'M 0 0 L 0 0 L 0 0 z'); - dagreD3.util.applyStyle(path, edge[type + 'Style']); + applyStyle(path, edge[type + 'Style']); }; // Override normal arrowhead defined in d3. Remove style & add class to allow css styling. diff --git a/packages/mermaid/src/diagrams/flowchart/styles.ts b/packages/mermaid/src/diagrams/flowchart/styles.ts index 82fb1f875..a89d33d3d 100644 --- a/packages/mermaid/src/diagrams/flowchart/styles.ts +++ b/packages/mermaid/src/diagrams/flowchart/styles.ts @@ -103,6 +103,12 @@ const getStyles = (options: FlowChartStyleOptions) => pointer-events: none; z-index: 100; } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/git/gitGraphAst.js b/packages/mermaid/src/diagrams/git/gitGraphAst.js index 496e578b7..65980933d 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphAst.js +++ b/packages/mermaid/src/diagrams/git/gitGraphAst.js @@ -10,6 +10,8 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; let mainBranchName = getConfig().gitGraph.mainBranchName; @@ -529,5 +531,7 @@ export default { getAccTitle, getAccDescription, setAccDescription, + setDiagramTitle, + getDiagramTitle, commitType, }; diff --git a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js index 71698a500..75e8d445d 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js +++ b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js @@ -1,6 +1,7 @@ import { select } from 'd3'; import { getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI'; import { log } from '../../logger'; +import utils from '../../utils'; import addSVGAccessibilityFields from '../../accessibility'; let allCommitsDict = {}; @@ -521,6 +522,12 @@ export const draw = function (txt, id, ver, diagObj) { } drawArrows(diagram, allCommitsDict); drawCommits(diagram, allCommitsDict, true); + utils.insertTitle( + diagram, + 'gitTitleText', + gitGraphConfig.titleTopMargin, + diagObj.db.getDiagramTitle() + ); // Setup the view box and size of the svg element setupGraphViewbox( diff --git a/packages/mermaid/src/diagrams/git/styles.js b/packages/mermaid/src/diagrams/git/styles.js index 7e09ff7e0..741760235 100644 --- a/packages/mermaid/src/diagrams/git/styles.js +++ b/packages/mermaid/src/diagrams/git/styles.js @@ -51,6 +51,11 @@ const getStyles = (options) => } .arrow { stroke-width: 8; stroke-linecap: round; fill: none} + .gitTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } } `; diff --git a/packages/mermaid/src/diagrams/pie/pieDetector.ts b/packages/mermaid/src/diagrams/pie/pieDetector.ts index 65a011c7a..e267c710a 100644 --- a/packages/mermaid/src/diagrams/pie/pieDetector.ts +++ b/packages/mermaid/src/diagrams/pie/pieDetector.ts @@ -1,5 +1,6 @@ import type { DiagramDetector } from '../../diagram-api/types'; export const pieDetector: DiagramDetector = (txt) => { - return txt.match(/^\s*pie/) !== null; + const logOutput = txt.match(/^\s*pie/) !== null || txt.match(/^\s*bar/) !== null; + return logOutput; }; diff --git a/packages/mermaid/src/diagrams/pie/pieRenderer.js b/packages/mermaid/src/diagrams/pie/pieRenderer.js index 6cbb99fa3..60e9a59c9 100644 --- a/packages/mermaid/src/diagrams/pie/pieRenderer.js +++ b/packages/mermaid/src/diagrams/pie/pieRenderer.js @@ -157,11 +157,11 @@ export const draw = (txt, id, _version, diagObj) => { .append('g') .attr('class', 'legend') .attr('transform', function (d, i) { - var height = legendRectSize + legendSpacing; - var offset = (height * color.domain().length) / 2; - var horz = 12 * legendRectSize; - var vert = i * height - offset; - return 'translate(' + horz + ',' + vert + ')'; + const height = legendRectSize + legendSpacing; + const offset = (height * color.domain().length) / 2; + const horizontal = 12 * legendRectSize; + const vertical = i * height - offset; + return 'translate(' + horizontal + ',' + vertical + ')'; }); legend diff --git a/packages/mermaid/src/diagrams/requirement/requirementRenderer.js b/packages/mermaid/src/diagrams/requirement/requirementRenderer.js index 79d67e76e..0338ec50c 100644 --- a/packages/mermaid/src/diagrams/requirement/requirementRenderer.js +++ b/packages/mermaid/src/diagrams/requirement/requirementRenderer.js @@ -1,5 +1,5 @@ import { line, select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import graphlib from 'graphlib'; import { log } from '../../logger'; import { configureSvgSize } from '../../setupGraphViewbox'; @@ -348,7 +348,7 @@ export const draw = (text, id, _version, diagObj) => { drawReqs(requirements, g, svg); drawElements(elements, g, svg); addRelationships(relationships, g); - dagre.layout(g); + dagreLayout(g); adjustEntities(svg, g); relationships.forEach(function (rel) { diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js index 0dc437721..ed4373514 100644 --- a/packages/mermaid/src/diagrams/sequence/svgDraw.js +++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js @@ -752,7 +752,7 @@ export const insertSequenceNumber = function (elem) { // .style("fill", '#f00'); }; /** - * Setup arrow head and define the marker. The result is appended to the svg. + * Setup cross head and define the marker. The result is appended to the svg. * * @param {any} elem */ @@ -764,26 +764,16 @@ export const insertArrowCrossHead = function (elem) { .attr('markerWidth', 15) .attr('markerHeight', 8) .attr('orient', 'auto') - .attr('refX', 16) - .attr('refY', 4); - - // The arrow - marker - .append('path') - .attr('fill', 'black') - .attr('stroke', '#000000') - .style('stroke-dasharray', '0, 0') - .attr('stroke-width', '1px') - .attr('d', 'M 9,2 V 6 L16,4 Z'); - + .attr('refX', 4) + .attr('refY', 5); // The cross marker .append('path') .attr('fill', 'none') .attr('stroke', '#000000') .style('stroke-dasharray', '0, 0') - .attr('stroke-width', '1px') - .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7'); + .attr('stroke-width', '1pt') + .attr('d', 'M 1,2 L 6,7 M 6,2 L 1,7'); // this is actual shape for arrowhead }; diff --git a/packages/mermaid/src/diagrams/state/parser/state-style.spec.js b/packages/mermaid/src/diagrams/state/parser/state-style.spec.js index 3c734ff7d..75ecb4b13 100644 --- a/packages/mermaid/src/diagrams/state/parser/state-style.spec.js +++ b/packages/mermaid/src/diagrams/state/parser/state-style.spec.js @@ -184,6 +184,27 @@ describe('ClassDefs and classes when parsing a State diagram', () => { }); }); }); + + describe('comments parsing', () => { + it('working inside states', function () { + let diagram = ''; + diagram += 'stateDiagram-v2\n\n'; + diagram += '[*] --> Moving\n'; + diagram += 'Moving --> Still\n'; + diagram += 'Moving --> Crash\n'; + diagram += 'state Moving {\n'; + diagram += '%% comment inside state\n'; + diagram += 'slow --> fast\n'; + diagram += '}\n'; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const states = stateDiagram.parser.yy.getStates(); + + expect(states['Moving'].doc.length).toEqual(1); + }); + }); }); }); }); diff --git a/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison b/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison index 1115edfe9..67073210b 100644 --- a/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison +++ b/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison @@ -109,6 +109,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili [^\n\s\{]+ {/*console.log('COMPOSIT_STATE', yytext);*/return 'COMPOSIT_STATE';} \n {this.popState();} \{ {this.popState();this.pushState('struct'); /*console.log('begin struct', yytext);*/return 'STRUCT_START';} +\%\%(?!\{)[^\n]* /* skip comments inside state*/ \} { /*console.log('Ending struct');*/ this.popState(); return 'STRUCT_STOP';}} [\n] /* nothing */ diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js index d0877847c..19ecbe65f 100644 --- a/packages/mermaid/src/diagrams/state/stateDb.js +++ b/packages/mermaid/src/diagrams/state/stateDb.js @@ -9,6 +9,8 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; import { @@ -31,9 +33,20 @@ const FILL_KEYWORD = 'fill'; const BG_FILL = 'bgFill'; const STYLECLASS_SEP = ','; +/** + * Returns a new list of classes. + * In the future, this can be replaced with a class common to all diagrams. + * ClassDef information = { id: id, styles: [], textStyles: [] } + * + * @returns {{}} + */ +function newClassesList() { + return {}; +} + let direction = DEFAULT_DIAGRAM_DIRECTION; let rootDoc = []; -let classes = []; // style classes defined by a classDef +let classes = newClassesList(); // style classes defined by a classDef const newDoc = () => { return { @@ -270,11 +283,9 @@ export const clear = function (saveCommon) { }; currentDocument = documents.root; - currentDocument = documents.root; - // number of start and end nodes; used to construct ids startEndCount = 0; - classes = []; + classes = newClassesList(); if (!saveCommon) { commonClear(); } @@ -300,7 +311,7 @@ export const getRelations = function () { * else return the given id * * @param {string} id - * @returns {{id: string, type: string}} - the id and type that should be used + * @returns {string} - the id (original or constructed) */ function startIdIfNeeded(id = '') { let fixedId = id; @@ -329,7 +340,7 @@ function startTypeIfNeeded(id = '', type = DEFAULT_STATE_TYPE) { * else return the given id * * @param {string} id - * @returns {{id: string, type: string}} - the id and type that should be used + * @returns {string} - the id (original or constructed) */ function endIdIfNeeded(id = '') { let fixedId = id; @@ -442,12 +453,12 @@ const getDividerId = () => { * @example classDef my-style fill:#f96; * * @param {string} id - the id of this (style) class - * @param {string} styleAttributes - the string with 1 or more style attributes (each separated by a comma) + * @param {string | null} styleAttributes - the string with 1 or more style attributes (each separated by a comma) */ export const addStyleClass = function (id, styleAttributes = '') { // create a new style class object with this id if (typeof classes[id] === 'undefined') { - classes[id] = { id: id, styles: [], textStyles: [] }; + classes[id] = { id: id, styles: [], textStyles: [] }; // This is a classDef } const foundClass = classes[id]; if (typeof styleAttributes !== 'undefined') { @@ -562,4 +573,6 @@ export default { addStyleClass, setCssClass, addDescription, + setDiagramTitle, + getDiagramTitle, }; diff --git a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js index 39ec0f0d2..7ed5555db 100644 --- a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js +++ b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js @@ -3,6 +3,7 @@ import stateDb from './stateDb'; import stateDiagram from './parser/stateDiagram.jison'; describe('state diagram V2, ', function () { + // TODO - these examples should be put into ./parser/stateDiagram.spec.js describe('when parsing an info graph it', function () { beforeEach(function () { parser.yy = stateDb; diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js index 1011fb6b1..03c678789 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js @@ -5,6 +5,7 @@ import { render } from '../../dagre-wrapper/index.js'; import { log } from '../../logger'; import { configureSvgSize } from '../../setupGraphViewbox'; import common from '../common/common'; +import utils from '../../utils'; import addSVGAccessibilityFields from '../../accessibility'; import { DEFAULT_DIAGRAM_DIRECTION, @@ -58,11 +59,6 @@ const G_EDGE_LABELTYPE = 'text'; const G_EDGE_THICKNESS = 'normal'; // -------------------------------------- -// When information is parsed and processed (extracted) by stateDb.extract() -// These are globals so the information can be accessed as needed (e.g. in setUpNode, etc.) -let diagramStates = []; -let diagramClasses = []; - // List of nodes created from the parsed diagram statement items let nodeDb = {}; @@ -81,25 +77,20 @@ export const setConf = function (cnf) { }; /** - * Returns the all the styles from classDef statements in the graph definition. + * Returns the all the classdef styles (a.k.a. classes) from classDef statements in the graph definition. * * @param {string} text - the diagram text to be parsed - * @param {Diagram} diagramObj - * @returns {object} ClassDef styles + * @param diagramObj + * @returns {object} ClassDef styles (a Map with keys = strings, values = ) */ export const getClasses = function (text, diagramObj) { log.trace('Extracting classes'); - if (diagramClasses.length > 0) { - return diagramClasses; // we have already extracted the classes - } - diagramObj.db.clear(); try { // Parse the graph definition diagramObj.parser.parse(text); // must run extract() to turn the parsed statements into states, relationships, classes, etc. diagramObj.db.extract(diagramObj.db.getRootDocV2()); - return diagramObj.db.getClasses(); } catch (e) { return e; @@ -107,7 +98,7 @@ export const getClasses = function (text, diagramObj) { }; /** - * Get classes from the db info item. + * Get classes from the db for the info item. * If there aren't any or if dbInfoItem isn't defined, return an empty string. * Else create 1 string from the list of classes found * @@ -132,7 +123,7 @@ function getClassesFromDbInfo(dbInfoItem) { * * @param itemId * @param counter - * @param type + * @param {string | null} type * @param typeSpacer * @returns {string} */ @@ -147,10 +138,11 @@ export function stateDomId(itemId = '', counter = 0, type = '', typeSpacer = DOM * @param g - graph * @param {object} parent * @param {object} parsedItem - parsed statement item + * @param {object[]} diagramStates - the list of all known states for the diagram * @param {object} diagramDb * @param {boolean} altFlag - for clusters, add the "statediagram-cluster-alt" CSS class */ -const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => { +const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => { const itemId = parsedItem.id; const classStr = getClassesFromDbInfo(diagramStates[itemId]); @@ -307,7 +299,7 @@ const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => { } if (parsedItem.doc) { log.trace('Adding nodes children '); - setupDoc(g, parsedItem, parsedItem.doc, diagramDb, !altFlag); + setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag); } }; @@ -318,25 +310,26 @@ const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => { * @param g * @param parentParsedItem - parsed Item that is the parent of this document (doc) * @param doc - the document to set up + * @param {object} diagramStates - the list of all known states for the diagram * @param diagramDb - * @param altFlag + * @param {boolean} altFlag * @todo This duplicates some of what is done in stateDb.js extract method */ -const setupDoc = (g, parentParsedItem, doc, diagramDb, altFlag) => { +const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => { // graphItemCount = 0; log.trace('items', doc); doc.forEach((item) => { switch (item.stmt) { case STMT_STATE: - setupNode(g, parentParsedItem, item, diagramDb, altFlag); + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); break; case DEFAULT_STATE_TYPE: - setupNode(g, parentParsedItem, item, diagramDb, altFlag); + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); break; case STMT_RELATION: { - setupNode(g, parentParsedItem, item.state1, diagramDb, altFlag); - setupNode(g, parentParsedItem, item.state2, diagramDb, altFlag); + setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag); + setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag); const edgeData = { id: 'edge' + graphItemCount, arrowhead: 'normal', @@ -407,8 +400,7 @@ export const draw = function (text, id, _version, diag) { diag.db.extract(diag.db.getRootDocV2()); log.info(diag.db.getRootDocV2()); - diagramStates = diag.db.getStates(); - diagramClasses = diag.db.getClasses(); + const diagramStates = diag.db.getStates(); // Create the input mermaid.graph const g = new graphlib.Graph({ @@ -426,7 +418,7 @@ export const draw = function (text, id, _version, diag) { return {}; }); - setupNode(g, undefined, diag.db.getRootDocV2(), diag.db, true); + setupNode(g, undefined, diag.db.getRootDocV2(), diagramStates, diag.db, true); // Set up an SVG group so that we can translate the final graph. let sandboxElement; @@ -446,8 +438,9 @@ export const draw = function (text, id, _version, diag) { const padding = 8; - const bounds = svg.node().getBBox(); + utils.insertTitle(svg, 'statediagramTitleText', conf.titleTopMargin, diag.db.getDiagramTitle()); + const bounds = svg.node().getBBox(); const width = bounds.width + padding * 2; const height = bounds.height + padding * 2; diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js new file mode 100644 index 000000000..3a118e607 --- /dev/null +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js @@ -0,0 +1,31 @@ +import { expectTypeOf } from 'vitest'; + +import { parser } from './parser/stateDiagram'; +import stateDb from './stateDb'; +import stateRendererV2 from './stateRenderer-v2'; + +// Can use this instead of having to register diagrams and load/orchestrate them, etc. +class FauxDiagramObj { + db = stateDb; + parser = parser; + renderer = stateRendererV2; + + constructor(options = { db: stateDb, parser: parser, renderer: stateRendererV2 }) { + this.db = options.db; + this.parser = options.parser; + this.renderer = options.renderer; + this.parser.yy = this.db; + } +} + +describe('stateRenderer-v2', () => { + describe('getClasses', () => { + const diagramText = 'statediagram-v2\n'; + const fauxStateDiagram = new FauxDiagramObj(); + + it('returns a {}', () => { + const result = stateRendererV2.getClasses(diagramText, fauxStateDiagram); + expectTypeOf(result).toBeObject(); + }); + }); +}); diff --git a/packages/mermaid/src/diagrams/state/stateRenderer.js b/packages/mermaid/src/diagrams/state/stateRenderer.js index 73717a645..783460cc6 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer.js @@ -1,5 +1,5 @@ import { select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import graphlib from 'graphlib'; import { log } from '../../logger'; import common from '../common/common'; @@ -239,7 +239,7 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) = ); }); - dagre.layout(graph); + dagreLayout(graph); log.debug('Graph after layout', graph.nodes()); const svgElem = diagram.node(); diff --git a/packages/mermaid/src/diagrams/state/styles.js b/packages/mermaid/src/diagrams/state/styles.js index 4a1c46512..f4783b477 100644 --- a/packages/mermaid/src/diagrams/state/styles.js +++ b/packages/mermaid/src/diagrams/state/styles.js @@ -194,6 +194,12 @@ g.stateGroup line { stroke: ${options.lineColor}; stroke-width: 1; } + +.statediagramTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} `; export default getStyles; diff --git a/packages/mermaid/src/docs.mts b/packages/mermaid/src/docs.mts index e2f46ff1e..aa57a3c01 100644 --- a/packages/mermaid/src/docs.mts +++ b/packages/mermaid/src/docs.mts @@ -245,7 +245,7 @@ const transformHtml = (filename: string) => { }; const getGlobs = (globs: string[]): string[] => { - globs.push('!**/dist'); + globs.push('!**/dist', '!**/redirect.spec.ts'); if (!vitepress) { globs.push('!**/.vitepress', '!**/vite.config.ts', '!src/docs/index.md'); } diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index 0304c2fe2..216541d52 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -3,6 +3,8 @@ import MermaidExample from './mermaid-markdown-all'; import { defineConfig, MarkdownOptions } from 'vitepress'; const allMarkdownTransformers: MarkdownOptions = { + // the shiki theme to highlight code blocks + theme: 'github-dark', config: async (md) => { await MermaidExample(md); }, @@ -33,7 +35,7 @@ function nav() { { text: 'Intro', link: '/intro/', activeMatch: '/intro/' }, { text: 'Configuration', - link: '/config/Tutorials', + link: '/config/configuration', activeMatch: '/config/', }, { text: 'Syntax', link: '/syntax/classDiagram', activeMatch: '/syntax/' }, @@ -117,6 +119,7 @@ function sidebarConfig() { text: '⚙️ Deployment and Configuration', collapsible: true, items: [ + { text: 'Configuration', link: '/config/configuration' }, { text: 'Tutorials', link: '/config/Tutorials' }, { text: 'API-Usage', link: '/config/usage' }, { text: 'Mermaid API Configuration', link: '/config/setup/README' }, @@ -125,7 +128,6 @@ function sidebarConfig() { { text: 'Accessibility', link: '/config/accessibility' }, { text: 'Mermaid CLI', link: '/config/mermaidCLI' }, { text: 'Advanced usage', link: '/config/n00b-advanced' }, - { text: 'Configuration', link: '/config/configuration' }, ], }, ]; diff --git a/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts b/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts index e2178a653..9c3b35a68 100644 --- a/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts +++ b/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts @@ -1,5 +1,4 @@ import type { MarkdownRenderer } from 'vitepress'; -import { getHighlighter } from 'shiki'; const MermaidExample = async (md: MarkdownRenderer) => { const defaultRenderer = md.renderer.rules.fence; @@ -8,27 +7,31 @@ const MermaidExample = async (md: MarkdownRenderer) => { throw new Error('defaultRenderer is undefined'); } - const highlighter = await getHighlighter({ - theme: 'material-palenight', - langs: ['mermaid'], - }); - md.renderer.rules.fence = (tokens, index, options, env, slf) => { const token = tokens[index]; if (token.info.trim() === 'mermaid-example') { - const highlight = highlighter - .codeToHtml(token.content, { lang: 'mermaid' }) - .replace(/Code: -
    - - mermaid -${highlight} -
    `; + // doing ```mermaid-example {line-numbers=5 highlight=14-17} is not supported + const langAttrs = ''; + return ` +
    Code:
    +
    + + mermaid + ${ + // html is pre-escaped by the highlight function + // (it also adds `v-pre` to ignore Vue template syntax) + md.options.highlight(token.content, 'mermaid', langAttrs) + } +
    `; } else if (token.info.trim() === 'mermaid') { const key = index; return ` diff --git a/packages/mermaid/src/docs/.vitepress/theme/index.js b/packages/mermaid/src/docs/.vitepress/theme/index.js deleted file mode 100644 index b565838a9..000000000 --- a/packages/mermaid/src/docs/.vitepress/theme/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import DefaultTheme from 'vitepress/theme'; -import './custom.css'; -import Mermaid from './Mermaid.vue'; -export default { - ...DefaultTheme, - enhanceApp(ctx) { - // register global components - DefaultTheme.enhanceApp(ctx); - ctx.app.component('Mermaid', Mermaid); - }, -}; diff --git a/packages/mermaid/src/docs/.vitepress/theme/index.ts b/packages/mermaid/src/docs/.vitepress/theme/index.ts new file mode 100644 index 000000000..a56a7bade --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/theme/index.ts @@ -0,0 +1,26 @@ +import DefaultTheme from 'vitepress/theme'; +import './custom.css'; +// @ts-ignore +import Mermaid from './Mermaid.vue'; +import { getRedirect } from './redirect'; + +export default { + ...DefaultTheme, + enhanceApp({ app, router }) { + // register global components + app.component('Mermaid', Mermaid); + router.onBeforeRouteChange = (to) => { + if (router.route.path !== '/') { + return; + } + try { + const newPath = getRedirect(to); + if (newPath) { + console.log(`Redirecting to ${newPath} from ${window.location}`); + // router.go isn't loading the ID properly. + window.location.href = `/mermaid/${newPath}`; + } + } catch (e) { } + }; + }, +} as typeof DefaultTheme; diff --git a/packages/mermaid/src/docs/.vitepress/theme/redirect.ts b/packages/mermaid/src/docs/.vitepress/theme/redirect.ts new file mode 100644 index 000000000..ca4606be0 --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/theme/redirect.ts @@ -0,0 +1,89 @@ +export interface Redirect { + path: string; + id?: string; +} + +/** + * Extracts the base slug from the old URL. + * @param link - The old URL. + */ +const getBaseFile = (link: string): Redirect => { + const url = new URL(link); + if ( + (url.hostname !== 'mermaid-js.github.io' && url.hostname !== 'localhost') || + url.pathname !== '/mermaid/' + ) { + throw new Error('Not mermaidjs url'); + } + const [path, params, ...rest] = url.hash + .toLowerCase() + .replace('.md', '') + .replace(/^#\/?/g, '') + .replace(/^\.\//g, '') + .split('?'); + + // Find id in params + const id = params + ?.split('&') + .find((param) => param.startsWith('id=')) + ?.split('=')[1]; + + return { path, id }; +}; + +const redirectMap: Record = { + '8.6.0_docs': '', + accessibility: 'config/theming', + breakingchanges: '', + c4c: 'syntax/c4c', + classdiagram: 'syntax/classDiagram', + configuration: 'config/configuration', + demos: 'misc/integrations', + development: 'community/development', + directives: 'config/directives', + entityrelationshipdiagram: 'syntax/entityRelationshipDiagram', + examples: 'syntax/examples', + faq: 'misc/faq', + flowchart: 'syntax/flowchart', + gantt: 'syntax/gantt', + gitgraph: 'syntax/gitgraph', + integrations: 'misc/integrations', + 'language-highlight': '', + markdown: '', + mermaidapi: 'config/usage', + mermaidcli: 'config/mermaidCLI', + mindmap: 'syntax/mindmap', + 'more-pages': '', + 'n00b-advanced': 'config/n00b-advanced', + 'n00b-gettingstarted': 'intro/n00b-gettingStarted', + 'n00b-overview': 'community/n00b-overview', + 'n00b-syntaxreference': '', + newdiagram: 'community/newDiagram', + pie: 'syntax/pie', + plugins: '', + quickstart: 'intro/n00b-gettingStarted', + requirementdiagram: 'syntax/requirementDiagram', + security: 'community/security', + sequencediagram: 'syntax/sequenceDiagram', + setup: 'config/setup/README', + statediagram: 'syntax/stateDiagram', + themes: 'config/theming', + theming: 'config/theming', + tutorials: 'config/Tutorials', + upgrading: '', + usage: 'config/usage', + 'user-journey': 'syntax/userJourney', +}; + +/** + * + * @param link - The old documentation URL. + * @returns The new documentation path. + */ +export const getRedirect = (link: string): string | undefined => { + const { path, id } = getBaseFile(link); + if (!(path in redirectMap)) { + return; + } + return `${redirectMap[path]}.html${id ? `#${id}` : ''}`; +}; diff --git a/packages/mermaid/src/docs/community/development.md b/packages/mermaid/src/docs/community/development.md index 80edb7719..bfa5ddfcf 100644 --- a/packages/mermaid/src/docs/community/development.md +++ b/packages/mermaid/src/docs/community/development.md @@ -6,7 +6,7 @@ So you want to help? That's great! Here are a few things to get you started on the right path. -**The Docs Structure is dictated by [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)** +**The Docs Structure is dictated by [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. **Note: Commits and Pull Requests should be directed to the develop branch.** @@ -26,7 +26,7 @@ We make all changes via Pull Requests. As we have many Pull Requests from develo - Large changes reviewed by knsv or other developer asked to review by knsv - Smaller, low-risk changes like dependencies, documentation, etc. can be merged by active collaborators -- Documentation (we encourage updates to the `src/docs` folder; you can submit them via direct commits) +- Documentation (we encourage updates to the `/packages/mermaid/src/docs` folder; you can submit them via direct commits) When you commit code, create a branch with the following naming convention: @@ -44,9 +44,9 @@ Start with the type, such as **feature** or **bug**, followed by the issue numbe If it is not in the documentation, it's like it never happened. Wouldn't that be sad? With all the effort that was put into the feature? -The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via the **[sidebar](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**. +The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via **[.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. -> **All the documents displayed in the GitHub.io page are listed in [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**. +> **All the documents displayed in the GitHub.io page are listed in [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. The contents of [https://mermaid-js.github.io/mermaid/](https://mermaid-js.github.io/mermaid/) are based on the docs from the `master` branch. Updates committed to the `master` branch are reflected in the [Mermaid Docs](https://mermaid-js.github.io/mermaid/) once released. @@ -58,7 +58,7 @@ The documentation is located in the `src/docs` directory and organized according The `docs` folder will be automatically generated when committing to `src/docs` and should not be edited manually. -We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s) +We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s) ### Add Unit Tests for Parsing @@ -111,7 +111,7 @@ Markdown is used to format the text, for more information about Markdown [see th To edit Docs on your computer: -1. Find the Markdown file (.md) to edit in the [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs) directory in the `develop` branch. +1. Find the Markdown file (.md) to edit in the [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs) directory in the `develop` branch. 2. Create a fork of the develop branch. 3. Make changes or add new documentation. 4. Commit changes to your fork and push it to GitHub. @@ -120,7 +120,7 @@ To edit Docs on your computer: To edit Docs on GitHub: 1. Login to [GitHub.com](https://www.github.com). -2. Navigate to [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). +2. Navigate to [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). 3. To edit a file, click the pencil icon at the top-right of the file contents panel. 4. Describe what you changed in the **Propose file change** section, located at the bottom of the page. 5. Submit your changes by clicking the button **Propose file change** at the bottom (by automatic creation of a fork and a new branch). diff --git a/packages/mermaid/src/docs/community/n00b-overview.md b/packages/mermaid/src/docs/community/n00b-overview.md index c88875345..a72e500bd 100644 --- a/packages/mermaid/src/docs/community/n00b-overview.md +++ b/packages/mermaid/src/docs/community/n00b-overview.md @@ -39,7 +39,7 @@ It is a relatively straightforward solution to a significant hurdle with the sof **Nodes** -> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](../intro/n00b-syntaxReference) +> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](../intro/n00b-syntaxReference.md) ## Advantages of using Mermaid diff --git a/packages/mermaid/src/docs/community/security.md b/packages/mermaid/src/docs/community/security.md index 7e61a60cf..e7a0db6ed 100644 --- a/packages/mermaid/src/docs/community/security.md +++ b/packages/mermaid/src/docs/community/security.md @@ -4,13 +4,13 @@ The Mermaid team takes the security of Mermaid and the applications that use Mer ## Reporting vulnerabilities -To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. +To report a vulnerability, please e-mail with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. We aim to reply within three working days, probably much sooner. -You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to security@mermaid.live again if you do not receive prompt attention and regular updates. +You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to again if you do not receive prompt attention and regular updates. -You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail security@mernaid.live when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk. +You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk. ## Best practices diff --git a/packages/mermaid/src/docs/config/8.6.0_docs.md b/packages/mermaid/src/docs/config/8.6.0_docs.md index 40d1cc946..bc19e08d5 100644 --- a/packages/mermaid/src/docs/config/8.6.0_docs.md +++ b/packages/mermaid/src/docs/config/8.6.0_docs.md @@ -6,8 +6,8 @@ With version 8.6.0 comes the release of directives for mermaid, a new system for modifying configurations, with the aim of establishing centralized, sane defaults and simple implementation. -`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](../config/configuration). -This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](directives), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams. +`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](../config/configuration.md). +This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](directives.md), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams. **A likely application for this is in the creation of diagrams/charts inside company/organizational webpages, that rely on mermaid for diagram and chart rendering.** @@ -210,4 +210,4 @@ Ensures options parameter does not attempt to override siteConfig secure keys. default: current siteConfig (optional, default `getSiteConfig()`) ``` -## For more information, read [Setup](setup/README). +## For more information, read [Setup](./setup/README.md). diff --git a/packages/mermaid/src/docs/config/Tutorials.md b/packages/mermaid/src/docs/config/Tutorials.md index 54c6a845a..e07635641 100644 --- a/packages/mermaid/src/docs/config/Tutorials.md +++ b/packages/mermaid/src/docs/config/Tutorials.md @@ -22,7 +22,7 @@ The definitions that can be generated the Live-Editor are also backwards-compati ## Mermaid with HTML -Examples are provided in [Getting Started](../intro/n00b-gettingStarted) +Examples are provided in [Getting Started](../intro/n00b-gettingStarted.md) **CodePen Examples:** diff --git a/packages/mermaid/src/docs/config/usage.md b/packages/mermaid/src/docs/config/usage.md index 93f0429b7..3eac4ad6f 100644 --- a/packages/mermaid/src/docs/config/usage.md +++ b/packages/mermaid/src/docs/config/usage.md @@ -12,7 +12,7 @@ Please note that you can switch versions through the dropdown box at the top rig ## Using mermaid -For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](setup/README). +For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](./setup/README.md). We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermaid Live Editor. @@ -37,7 +37,7 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai **Hosting mermaid on a web page.** -> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted) +> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted.md) The easiest way to integrate mermaid on a web page requires two elements: @@ -324,7 +324,7 @@ setting the options in mermaid. 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). +configuration objects are described [in the mermaidAPI documentation](./setup/README.md). ## Using the `mermaidAPI.initialize`/`mermaid.initialize` call @@ -347,7 +347,7 @@ This is the preferred way of configuring mermaid. ## Using the mermaid object -Is it possible to set some configuration via the mermaid object. The two parameters that are supported using this +It is possible to set some configuration via the mermaid object. The two parameters that are supported using this approach are: - mermaid.startOnLoad diff --git a/packages/mermaid/src/docs/index.md b/packages/mermaid/src/docs/index.md index 975546f4b..6c2763904 100644 --- a/packages/mermaid/src/docs/index.md +++ b/packages/mermaid/src/docs/index.md @@ -32,6 +32,7 @@ features: