mirror of
https://github.com/facebook/docusaurus.git
synced 2025-12-26 01:33:02 +00:00
feat: support mermaid code blocks in Markdown (#7490)
Co-authored-by: Joshua Chen <sidachen2003@gmail.com> Co-authored-by: sebastienlorber <lorber.sebastien@gmail.com> # Conflicts: # project-words.txt # website/package.json # yarn.lock
This commit is contained in:
parent
a990a5eaea
commit
433f08b3f7
|
|
@ -40,6 +40,7 @@
|
|||
"@docusaurus/types": "2.1.0",
|
||||
"@types/escape-html": "^1.0.2",
|
||||
"@types/mdast": "^3.0.10",
|
||||
"@types/mermaid": "^8.2.9",
|
||||
"@types/stringify-object": "^3.3.1",
|
||||
"@types/unist": "^2.0.6",
|
||||
"rehype-stringify": "^8.0.0",
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ import toc from './remark/toc';
|
|||
import unwrapMdxCodeBlocks from './remark/unwrapMdxCodeBlocks';
|
||||
import transformImage from './remark/transformImage';
|
||||
import transformLinks from './remark/transformLinks';
|
||||
import mermaid from './remark/mermaid';
|
||||
|
||||
import transformAdmonitions from './remark/admonitions';
|
||||
import type {MarkdownConfig} from '@docusaurus/types';
|
||||
import type {LoaderContext} from 'webpack';
|
||||
import type {Processor, Plugin} from 'unified';
|
||||
import type {AdmonitionOptions} from './remark/admonitions';
|
||||
|
|
@ -61,6 +63,7 @@ export type MDXOptions = {
|
|||
};
|
||||
|
||||
export type Options = Partial<MDXOptions> & {
|
||||
markdownConfig: MarkdownConfig;
|
||||
staticDirs: string[];
|
||||
siteDir: string;
|
||||
isMDXPartial?: (filePath: string) => boolean;
|
||||
|
|
@ -71,7 +74,6 @@ export type Options = Partial<MDXOptions> & {
|
|||
frontMatter: {[key: string]: unknown};
|
||||
metadata: {[key: string]: unknown};
|
||||
}) => {[key: string]: unknown};
|
||||
filepath: string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -171,6 +173,7 @@ export async function mdxLoader(
|
|||
...(reqOptions.beforeDefaultRemarkPlugins ?? []),
|
||||
...getAdmonitionsPlugins(reqOptions.admonitions ?? false),
|
||||
...DEFAULT_OPTIONS.remarkPlugins,
|
||||
...(reqOptions.markdownConfig.mermaid ? [mermaid] : []),
|
||||
[
|
||||
transformImage,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`mermaid remark plugin does nothing if there's no mermaid code block 1`] = `
|
||||
"
|
||||
|
||||
|
||||
const layoutProps = {
|
||||
|
||||
};
|
||||
const MDXLayout = "wrapper"
|
||||
export default function MDXContent({
|
||||
components,
|
||||
...props
|
||||
}) {
|
||||
return <MDXLayout {...layoutProps} {...props} components={components} mdxType="MDXLayout">
|
||||
<h1>{\`Heading 1\`}</h1>
|
||||
<p>{\`No Mermaid diagram :(\`}</p>
|
||||
<pre><code parentName="pre" {...{
|
||||
"className": "language-js"
|
||||
}}>{\`this is not mermaid
|
||||
\`}</code></pre>
|
||||
</MDXLayout>;
|
||||
}
|
||||
|
||||
;
|
||||
MDXContent.isMDXComponent = true;"
|
||||
`;
|
||||
|
||||
exports[`mermaid remark plugin works for basic mermaid code blocks 1`] = `
|
||||
"
|
||||
|
||||
|
||||
const layoutProps = {
|
||||
|
||||
};
|
||||
const MDXLayout = "wrapper"
|
||||
export default function MDXContent({
|
||||
components,
|
||||
...props
|
||||
}) {
|
||||
return <MDXLayout {...layoutProps} {...props} components={components} mdxType="MDXLayout">
|
||||
<h1>{\`Heading 1\`}</h1>
|
||||
<mermaid {...{
|
||||
"value": "graph TD;/n A-->B;/n A-->C;/n B-->D;/n C-->D;"
|
||||
}}></mermaid>
|
||||
</MDXLayout>;
|
||||
}
|
||||
|
||||
;
|
||||
MDXContent.isMDXComponent = true;"
|
||||
`;
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {createCompiler} from '@mdx-js/mdx';
|
||||
import mermaid from '..';
|
||||
|
||||
describe('mermaid remark plugin', () => {
|
||||
function createTestCompiler() {
|
||||
return createCompiler({
|
||||
remarkPlugins: [mermaid],
|
||||
});
|
||||
}
|
||||
|
||||
it("does nothing if there's no mermaid code block", async () => {
|
||||
const mdxCompiler = createTestCompiler();
|
||||
const result = await mdxCompiler.process(
|
||||
`# Heading 1
|
||||
|
||||
No Mermaid diagram :(
|
||||
|
||||
\`\`\`js
|
||||
this is not mermaid
|
||||
\`\`\`
|
||||
`,
|
||||
);
|
||||
expect(result.contents).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('works for basic mermaid code blocks', async () => {
|
||||
const mdxCompiler = createTestCompiler();
|
||||
const result = await mdxCompiler.process(`# Heading 1
|
||||
|
||||
\`\`\`mermaid
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
\`\`\``);
|
||||
expect(result.contents).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit from 'unist-util-visit';
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Code} from 'mdast';
|
||||
|
||||
// TODO: this plugin shouldn't be in the core MDX loader
|
||||
// After we allow plugins to provide Remark/Rehype plugins (see
|
||||
// https://github.com/facebook/docusaurus/issues/6370), this should be provided
|
||||
// by theme-mermaid itself
|
||||
export default function plugin(): Transformer {
|
||||
return (root) => {
|
||||
visit(root, 'code', (node: Code, index, parent) => {
|
||||
if (node.lang === 'mermaid') {
|
||||
parent!.children.splice(index, 1, {
|
||||
type: 'mermaidCodeBlock',
|
||||
data: {
|
||||
hName: 'mermaid',
|
||||
hProperties: {
|
||||
value: node.value,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
@ -455,6 +455,7 @@ export default async function pluginContentBlog(
|
|||
(author) => author.imageURL,
|
||||
),
|
||||
}),
|
||||
markdownConfig: siteConfig.markdown,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -375,6 +375,7 @@ export default async function pluginContentDocs(
|
|||
}) => ({
|
||||
image: frontMatter.image,
|
||||
}),
|
||||
markdownConfig: siteConfig.markdown,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ export default function pluginContentPages(
|
|||
`${docuHash(aliasedSource)}.json`,
|
||||
);
|
||||
},
|
||||
markdownConfig: siteConfig.markdown,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -788,6 +788,7 @@ declare module '@theme/MDXComponents' {
|
|||
import type MDXUl from '@theme/MDXComponents/Ul';
|
||||
import type MDXImg from '@theme/MDXComponents/Img';
|
||||
import type Admonition from '@theme/Admonition';
|
||||
import type Mermaid from '@theme/Mermaid';
|
||||
|
||||
export type MDXComponentsObject = {
|
||||
readonly head: typeof MDXHead;
|
||||
|
|
@ -804,6 +805,7 @@ declare module '@theme/MDXComponents' {
|
|||
readonly h5: (props: ComponentProps<'h5'>) => JSX.Element;
|
||||
readonly h6: (props: ComponentProps<'h6'>) => JSX.Element;
|
||||
readonly admonition: typeof Admonition;
|
||||
readonly mermaid: typeof Mermaid;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[tagName: string]: ComponentType<any>;
|
||||
};
|
||||
|
|
@ -1112,6 +1114,14 @@ declare module '@theme/SearchBar' {
|
|||
export default function SearchBar(): JSX.Element;
|
||||
}
|
||||
|
||||
declare module '@theme/Mermaid' {
|
||||
export interface Props {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export default function Mermaid(props: Props): JSX.Element;
|
||||
}
|
||||
|
||||
declare module '@theme/TabItem' {
|
||||
import type {ReactNode} from 'react';
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import MDXHeading from '@theme/MDXComponents/Heading';
|
|||
import MDXUl from '@theme/MDXComponents/Ul';
|
||||
import MDXImg from '@theme/MDXComponents/Img';
|
||||
import Admonition from '@theme/Admonition';
|
||||
import Mermaid from '@theme/Mermaid';
|
||||
|
||||
import type {MDXComponentsObject} from '@theme/MDXComponents';
|
||||
|
||||
|
|
@ -33,6 +34,7 @@ const MDXComponents: MDXComponentsObject = {
|
|||
h5: (props) => <MDXHeading as="h5" {...props} />,
|
||||
h6: (props) => <MDXHeading as="h6" {...props} />,
|
||||
admonition: Admonition,
|
||||
mermaid: Mermaid,
|
||||
};
|
||||
|
||||
export default MDXComponents;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// This component is meant to be implemented by a Mermaid renderer theme
|
||||
// It is notable created to be overridden by docusaurus-theme-mermaid
|
||||
|
||||
// By default, the classic theme does not provide any Mermaid implementation
|
||||
// Yet we declare it there so that we can register it in MDX
|
||||
// TODO later the mermaid theme should be able to register its MDX component
|
||||
// see https://github.com/facebook/docusaurus/pull/7490#issuecomment-1279117288
|
||||
|
||||
export {default} from '@docusaurus/Noop';
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.tsbuildinfo*
|
||||
tsconfig*
|
||||
__tests__
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Docusaurus Theme Mermaid
|
||||
|
||||
The mermaid components for Docusaurus.
|
||||
|
||||
## Installation
|
||||
|
||||
Add `docusaurus/theme-mermaid` to your package:
|
||||
|
||||
```bash
|
||||
npm i @docusaurus/theme-mermaid
|
||||
# or
|
||||
yarn add @docusaurus/theme-mermaid
|
||||
```
|
||||
|
||||
## Swizzling components
|
||||
|
||||
```bash
|
||||
$ npm swizzle @docusaurus/theme-mermaid [component name]
|
||||
```
|
||||
|
||||
All components used by this theme can be found [here](https://github.com/facebook/docusaurus/tree/main/packages/docusaurus-theme-mermaid/src/theme)
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"name": "@docusaurus/theme-mermaid",
|
||||
"version": "2.1.0",
|
||||
"description": "Mermaid components for Docusaurus.",
|
||||
"main": "lib/index.js",
|
||||
"types": "src/theme-mermaid.d.ts",
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
"./lib/*": "./lib/*",
|
||||
"./src/*": "./src/*",
|
||||
"./client": {
|
||||
"type": "./lib/client/index.d.ts",
|
||||
"default": "./lib/client/index.js"
|
||||
},
|
||||
".": {
|
||||
"types": "./src/theme-mermaid.d.ts",
|
||||
"default": "./lib/index.js"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/docusaurus.git",
|
||||
"directory": "packages/docusaurus-theme-mermaid"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "tsc --build && node ../../admin/scripts/copyUntypedFiles.js && prettier --config ../../.prettierrc --write \"lib/theme/**/*.js\"",
|
||||
"watch": "run-p -c copy:watch build:watch",
|
||||
"build:watch": "tsc --build --watch",
|
||||
"copy:watch": "node ../../admin/scripts/copyUntypedFiles.js --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "2.1.0",
|
||||
"@docusaurus/module-type-aliases": "2.1.0",
|
||||
"@docusaurus/theme-common": "2.1.0",
|
||||
"@docusaurus/types": "^2.1.0",
|
||||
"@docusaurus/utils-validation": "2.1.0",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"mermaid": "^9.1.1",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mdx-js__react": "^1.5.5",
|
||||
"@types/mermaid": "^8.2.9",
|
||||
"react-test-renderer": "^17.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.4 || ^17.0.0",
|
||||
"react-dom": "^16.8.4 || ^17.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {
|
||||
validateThemeConfig,
|
||||
DEFAULT_THEME_CONFIG,
|
||||
} from '../validateThemeConfig';
|
||||
import type {Joi} from '@docusaurus/utils-validation';
|
||||
import type {ThemeConfig, UserThemeConfig} from '@docusaurus/theme-mermaid';
|
||||
|
||||
function testValidateThemeConfig(themeConfig: UserThemeConfig) {
|
||||
function validate(
|
||||
schema: Joi.ObjectSchema<ThemeConfig>,
|
||||
cfg: UserThemeConfig,
|
||||
) {
|
||||
const {value, error} = schema.validate(cfg, {
|
||||
convert: false,
|
||||
});
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
return validateThemeConfig({validate, themeConfig});
|
||||
}
|
||||
|
||||
describe('validateThemeConfig', () => {
|
||||
it('undefined config', () => {
|
||||
const mermaid = undefined;
|
||||
expect(testValidateThemeConfig({mermaid})).toEqual(DEFAULT_THEME_CONFIG);
|
||||
});
|
||||
|
||||
it('nonexistent config', () => {
|
||||
expect(testValidateThemeConfig({})).toEqual(DEFAULT_THEME_CONFIG);
|
||||
});
|
||||
|
||||
it('empty config', () => {
|
||||
const mermaid = {};
|
||||
expect(testValidateThemeConfig({mermaid})).toEqual(DEFAULT_THEME_CONFIG);
|
||||
});
|
||||
|
||||
it('theme', () => {
|
||||
const mermaid = {
|
||||
theme: {
|
||||
light: 'light',
|
||||
dark: 'dark',
|
||||
},
|
||||
};
|
||||
expect(testValidateThemeConfig({mermaid})).toEqual({
|
||||
mermaid: {
|
||||
...DEFAULT_THEME_CONFIG.mermaid,
|
||||
...mermaid,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('mermaid options', () => {
|
||||
const mermaid = {
|
||||
options: {
|
||||
fontFamily: 'Ariel',
|
||||
},
|
||||
};
|
||||
expect(testValidateThemeConfig({mermaid})).toEqual({
|
||||
mermaid: {
|
||||
...DEFAULT_THEME_CONFIG.mermaid,
|
||||
...mermaid,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {useMemo} from 'react';
|
||||
import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
|
||||
import mermaid from 'mermaid';
|
||||
import type mermaidAPI from 'mermaid/mermaidAPI';
|
||||
import type {ThemeConfig} from '@docusaurus/theme-mermaid';
|
||||
|
||||
// Stable className to allow users to easily target with CSS
|
||||
export const MermaidContainerClassName = 'docusaurus-mermaid-container';
|
||||
|
||||
export function useMermaidThemeConfig(): ThemeConfig['mermaid'] {
|
||||
return (useThemeConfig() as unknown as ThemeConfig).mermaid;
|
||||
}
|
||||
|
||||
export function useMermaidConfig(): mermaidAPI.Config {
|
||||
const {colorMode} = useColorMode();
|
||||
const mermaidThemeConfig = useMermaidThemeConfig();
|
||||
|
||||
const theme = mermaidThemeConfig.theme[colorMode];
|
||||
const {options} = mermaidThemeConfig;
|
||||
|
||||
return useMemo(
|
||||
() => ({startOnLoad: false, ...options, theme}),
|
||||
[theme, options],
|
||||
);
|
||||
}
|
||||
|
||||
export function useMermaidSvg(
|
||||
txt: string,
|
||||
mermaidConfigParam?: mermaidAPI.Config,
|
||||
): string {
|
||||
/*
|
||||
For flexibility, we allow the hook to receive a custom Mermaid config
|
||||
The user could inject a modified version of the default config for example
|
||||
*/
|
||||
const defaultMermaidConfig = useMermaidConfig();
|
||||
const mermaidConfig = mermaidConfigParam ?? defaultMermaidConfig;
|
||||
|
||||
return useMemo(() => {
|
||||
/*
|
||||
Mermaid API is really weird :s
|
||||
It is a big mutable singleton with multiple config levels
|
||||
Note: most recent API type definitions are missing
|
||||
|
||||
There are 2 kind of configs:
|
||||
|
||||
- siteConfig: some kind of global/protected shared config
|
||||
you can only set with "initialize"
|
||||
|
||||
- config/currentConfig
|
||||
the config the renderer will use
|
||||
it is reset to siteConfig before each render
|
||||
but it can be altered by the mermaid txt content itself through directives
|
||||
|
||||
To use a new mermaid config (on colorMode change for example) we should
|
||||
update siteConfig, and it can only be done with initialize()
|
||||
*/
|
||||
mermaid.mermaidAPI.initialize(mermaidConfig);
|
||||
|
||||
/*
|
||||
Random client-only id, we don't care much about it
|
||||
But mermaid want an id so...
|
||||
*/
|
||||
const mermaidId = `mermaid-svg-${Math.round(Math.random() * 10000000)}`;
|
||||
|
||||
/*
|
||||
Not even documented: mermaid.render returns the svg string
|
||||
Using the documented form is un-necessary
|
||||
*/
|
||||
return mermaid.render(mermaidId, txt);
|
||||
}, [txt, mermaidConfig]);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import type {Plugin} from '@docusaurus/types';
|
||||
|
||||
export default function themeMermaid(): Plugin<void> {
|
||||
return {
|
||||
name: 'docusaurus-theme-mermaid',
|
||||
|
||||
getThemePath() {
|
||||
return '../lib/theme';
|
||||
},
|
||||
getTypeScriptThemePath() {
|
||||
return '../src/theme';
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export {validateThemeConfig} from './validateThemeConfig';
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/// <reference types="@docusaurus/module-type-aliases" />
|
||||
|
||||
declare module '@docusaurus/theme-mermaid' {
|
||||
import type {DeepPartial} from 'utility-types';
|
||||
import type mermaidAPI from 'mermaid/mermaidAPI';
|
||||
import type {Plugin} from '@docusaurus/types';
|
||||
|
||||
export type ThemeConfig = {
|
||||
mermaid: {
|
||||
theme: {
|
||||
light: mermaidAPI.Theme;
|
||||
dark: mermaidAPI.Theme;
|
||||
};
|
||||
options: mermaidAPI.Config;
|
||||
};
|
||||
};
|
||||
export type UserThemeConfig = DeepPartial<ThemeConfig>;
|
||||
|
||||
export default function themeMermaid(): Plugin<undefined>;
|
||||
}
|
||||
|
||||
declare module '@theme/Mermaid' {
|
||||
export interface Props {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export default function Mermaid(props: Props): JSX.Element;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
import {
|
||||
MermaidContainerClassName,
|
||||
useMermaidSvg,
|
||||
} from '@docusaurus/theme-mermaid/client';
|
||||
|
||||
import type {Props} from '@theme/Mermaid';
|
||||
|
||||
import styles from './styles.module.css';
|
||||
|
||||
function MermaidDiagram({value}: Props): JSX.Element {
|
||||
const svg = useMermaidSvg(value);
|
||||
return (
|
||||
<div
|
||||
className={`${MermaidContainerClassName} ${styles.container}`}
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{__html: svg}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Mermaid(props: Props): JSX.Element {
|
||||
return <BrowserOnly>{() => <MermaidDiagram {...props} />}</BrowserOnly>;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.container {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.container > svg {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {Joi} from '@docusaurus/utils-validation';
|
||||
import type {ThemeConfig} from '@docusaurus/theme-mermaid';
|
||||
import type mermaidAPI from 'mermaid/mermaidAPI';
|
||||
import type {ThemeConfigValidationContext} from '@docusaurus/types';
|
||||
|
||||
export const DEFAULT_THEME_CONFIG: ThemeConfig = {
|
||||
mermaid: {
|
||||
theme: {
|
||||
dark: 'dark' as mermaidAPI.Theme,
|
||||
light: 'default' as mermaidAPI.Theme,
|
||||
},
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
|
||||
export const Schema = Joi.object<ThemeConfig>({
|
||||
mermaid: Joi.object({
|
||||
theme: Joi.object({
|
||||
dark: Joi.string().default(DEFAULT_THEME_CONFIG.mermaid.theme.dark),
|
||||
light: Joi.string().default(DEFAULT_THEME_CONFIG.mermaid.theme.light),
|
||||
}).default(DEFAULT_THEME_CONFIG.mermaid.theme),
|
||||
options: Joi.object().default(DEFAULT_THEME_CONFIG.mermaid.options),
|
||||
}).default(DEFAULT_THEME_CONFIG.mermaid),
|
||||
});
|
||||
|
||||
export function validateThemeConfig({
|
||||
validate,
|
||||
themeConfig,
|
||||
}: ThemeConfigValidationContext<ThemeConfig>): ThemeConfig {
|
||||
return validate(Schema, themeConfig);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false,
|
||||
"composite": true,
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo-client",
|
||||
"rootDir": "src",
|
||||
"outDir": "lib",
|
||||
"module": "esnext",
|
||||
"target": "esnext"
|
||||
},
|
||||
"include": ["src/theme", "src/*.d.ts"],
|
||||
"exclude": ["**/__tests__/**"]
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"references": [{"path": "./tsconfig.client.json"}],
|
||||
"compilerOptions": {
|
||||
"noEmit": false,
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo",
|
||||
"module": "commonjs",
|
||||
"rootDir": "src",
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["src/theme", "**/__tests__/**"]
|
||||
}
|
||||
|
|
@ -16,6 +16,20 @@ export type ThemeConfig = {
|
|||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type MarkdownConfig = {
|
||||
/**
|
||||
* Allow mermaid language code blocks to be rendered into Mermaid diagrams:
|
||||
*
|
||||
* - `true`: code blocks with language mermaid will be rendered.
|
||||
* - `false` | `undefined` (default): code blocks with language mermaid
|
||||
* will be left as code blocks.
|
||||
*
|
||||
* @see https://docusaurus.io/docs/markdown-features/diagrams/
|
||||
* @default false
|
||||
*/
|
||||
mermaid?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Docusaurus config, after validation/normalization.
|
||||
*/
|
||||
|
|
@ -277,6 +291,8 @@ export type DocusaurusConfig = {
|
|||
*/
|
||||
jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule);
|
||||
};
|
||||
/** Markdown-related options. */
|
||||
markdown: MarkdownConfig;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
export {
|
||||
ReportingSeverity,
|
||||
ThemeConfig,
|
||||
MarkdownConfig,
|
||||
DocusaurusConfig,
|
||||
Config,
|
||||
} from './config';
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
|
|||
],
|
||||
"path": "i18n",
|
||||
},
|
||||
"markdown": {
|
||||
"mermaid": false,
|
||||
},
|
||||
"noIndex": false,
|
||||
"onBrokenLinks": "throw",
|
||||
"onBrokenMarkdownLinks": "warn",
|
||||
|
|
@ -54,6 +57,9 @@ exports[`loadSiteConfig website with valid async config 1`] = `
|
|||
],
|
||||
"path": "i18n",
|
||||
},
|
||||
"markdown": {
|
||||
"mermaid": false,
|
||||
},
|
||||
"noIndex": false,
|
||||
"onBrokenLinks": "throw",
|
||||
"onBrokenMarkdownLinks": "warn",
|
||||
|
|
@ -94,6 +100,9 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
|
|||
],
|
||||
"path": "i18n",
|
||||
},
|
||||
"markdown": {
|
||||
"mermaid": false,
|
||||
},
|
||||
"noIndex": false,
|
||||
"onBrokenLinks": "throw",
|
||||
"onBrokenMarkdownLinks": "warn",
|
||||
|
|
@ -134,6 +143,9 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
|
|||
],
|
||||
"path": "i18n",
|
||||
},
|
||||
"markdown": {
|
||||
"mermaid": false,
|
||||
},
|
||||
"noIndex": false,
|
||||
"onBrokenLinks": "throw",
|
||||
"onBrokenMarkdownLinks": "warn",
|
||||
|
|
@ -177,6 +189,9 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
|
|||
],
|
||||
"path": "i18n",
|
||||
},
|
||||
"markdown": {
|
||||
"mermaid": false,
|
||||
},
|
||||
"noIndex": false,
|
||||
"onBrokenLinks": "throw",
|
||||
"onBrokenMarkdownLinks": "warn",
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ exports[`load loads props for site with custom i18n path 1`] = `
|
|||
],
|
||||
"path": "i18n",
|
||||
},
|
||||
"markdown": {
|
||||
"mermaid": false,
|
||||
},
|
||||
"noIndex": false,
|
||||
"onBrokenLinks": "throw",
|
||||
"onBrokenMarkdownLinks": "warn",
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ import {
|
|||
DEFAULT_CONFIG,
|
||||
validateConfig,
|
||||
} from '../configValidation';
|
||||
import type {Config} from '@docusaurus/types';
|
||||
import type {Config, DocusaurusConfig} from '@docusaurus/types';
|
||||
import type {DeepPartial} from 'utility-types';
|
||||
|
||||
const baseConfig = {
|
||||
baseUrl: '/',
|
||||
|
|
@ -18,7 +19,7 @@ const baseConfig = {
|
|||
url: 'https://mysite.com',
|
||||
} as Config;
|
||||
|
||||
const normalizeConfig = (config: Partial<Config>) =>
|
||||
const normalizeConfig = (config: DeepPartial<Config>) =>
|
||||
validateConfig({...baseConfig, ...config}, 'docusaurus.config.js');
|
||||
|
||||
describe('normalizeConfig', () => {
|
||||
|
|
@ -57,6 +58,9 @@ describe('normalizeConfig', () => {
|
|||
crossorigin: 'anonymous',
|
||||
},
|
||||
],
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
},
|
||||
};
|
||||
const normalizedConfig = normalizeConfig(userConfig);
|
||||
expect(normalizedConfig).toEqual(userConfig);
|
||||
|
|
@ -466,3 +470,44 @@ describe('config warning and error', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('markdown', () => {
|
||||
it('accepts undefined object', () => {
|
||||
expect(
|
||||
normalizeConfig({
|
||||
markdown: undefined,
|
||||
}),
|
||||
).toEqual(expect.objectContaining({markdown: DEFAULT_CONFIG.markdown}));
|
||||
});
|
||||
|
||||
it('accepts empty object', () => {
|
||||
expect(
|
||||
normalizeConfig({
|
||||
markdown: {},
|
||||
}),
|
||||
).toEqual(expect.objectContaining({markdown: DEFAULT_CONFIG.markdown}));
|
||||
});
|
||||
|
||||
it('accepts valid markdown object', () => {
|
||||
const markdown: DocusaurusConfig['markdown'] = {
|
||||
mermaid: true,
|
||||
};
|
||||
expect(
|
||||
normalizeConfig({
|
||||
markdown,
|
||||
}),
|
||||
).toEqual(expect.objectContaining({markdown}));
|
||||
});
|
||||
|
||||
it('throw for null object', () => {
|
||||
expect(() => {
|
||||
normalizeConfig({
|
||||
// @ts-expect-error: test
|
||||
markdown: null,
|
||||
});
|
||||
}).toThrowErrorMatchingInlineSnapshot(`
|
||||
""markdown" must be of type object
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ export const DEFAULT_CONFIG: Pick<
|
|||
| 'tagline'
|
||||
| 'baseUrlIssueBanner'
|
||||
| 'staticDirectories'
|
||||
| 'markdown'
|
||||
> = {
|
||||
i18n: DEFAULT_I18N_CONFIG,
|
||||
onBrokenLinks: 'throw',
|
||||
|
|
@ -63,6 +64,9 @@ export const DEFAULT_CONFIG: Pick<
|
|||
tagline: '',
|
||||
baseUrlIssueBanner: true,
|
||||
staticDirectories: [DEFAULT_STATIC_DIR_NAME],
|
||||
markdown: {
|
||||
mermaid: false,
|
||||
},
|
||||
};
|
||||
|
||||
function createPluginSchema(theme: boolean) {
|
||||
|
|
@ -262,6 +266,9 @@ export const ConfigSchema = Joi.object<DocusaurusConfig>({
|
|||
.try(Joi.string().equal('babel'), Joi.function())
|
||||
.optional(),
|
||||
}).optional(),
|
||||
markdown: Joi.object({
|
||||
mermaid: Joi.boolean().default(DEFAULT_CONFIG.markdown.mermaid),
|
||||
}).default(DEFAULT_CONFIG.markdown),
|
||||
}).messages({
|
||||
'docusaurus.configValidationWarning':
|
||||
'Docusaurus config validation warning. Field {#label}: {#warningMessage}',
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
import path from 'path';
|
||||
import type {RuleSetRule} from 'webpack';
|
||||
import type {HtmlTagObject, LoadedPlugin, LoadContext} from '@docusaurus/types';
|
||||
import type {Options as MDXLoaderOptions} from '@docusaurus/mdx-loader';
|
||||
|
||||
/**
|
||||
* Make a synthetic plugin to:
|
||||
|
|
@ -96,7 +97,7 @@ export function createMDXFallbackPlugin({
|
|||
return isMDXRule ? (rule.include as string[]) : [];
|
||||
});
|
||||
}
|
||||
const mdxLoaderOptions = {
|
||||
const mdxLoaderOptions: MDXLoaderOptions = {
|
||||
admonitions: true,
|
||||
staticDirs: siteConfig.staticDirectories.map((dir) =>
|
||||
path.resolve(siteDir, dir),
|
||||
|
|
@ -106,6 +107,7 @@ export function createMDXFallbackPlugin({
|
|||
isMDXPartial: () => true,
|
||||
// External MDX files might have front matter, just disable the warning
|
||||
isMDXPartialFrontMatterWarningDisabled: true,
|
||||
markdownConfig: siteConfig.markdown,
|
||||
};
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,10 @@ formik
|
|||
fouc
|
||||
froms
|
||||
funboxteam
|
||||
gantt
|
||||
gabrielcsapo
|
||||
getopts
|
||||
gitgraph
|
||||
gitpod
|
||||
globbing
|
||||
globby
|
||||
|
|
@ -261,6 +264,7 @@ refactorings
|
|||
regexes
|
||||
rehype
|
||||
reponame
|
||||
reqs
|
||||
requireindex
|
||||
retrocompatibility
|
||||
retrocompatible
|
||||
|
|
@ -340,6 +344,7 @@ urlset
|
|||
userland
|
||||
vannicatte
|
||||
vercel
|
||||
verifymethod
|
||||
vetter
|
||||
vfile
|
||||
vicenti
|
||||
|
|
|
|||
|
|
@ -0,0 +1,316 @@
|
|||
# Diagram Examples
|
||||
|
||||
## Sequence Diagram
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant Bob
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Health check
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts <br/>prevail!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
```
|
||||
|
||||
## Sequence Diagram (forest theme directive)
|
||||
|
||||
It is possible to override default config locally with Mermaid text directives such as:
|
||||
|
||||
```
|
||||
%%{init: { "theme": "forest" } }%%
|
||||
```
|
||||
|
||||
```mermaid
|
||||
%%{init: { "theme": "forest" } }%%
|
||||
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant Bob
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Health check
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts <br/>prevail!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
```
|
||||
|
||||
## Gantt Chart
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
```
|
||||
|
||||
## Flow Chart
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Start] --> B{Is it?}
|
||||
B -->|Yes| C[OK]
|
||||
C --> D[Rethink]
|
||||
D --> B
|
||||
B ---->|No| E[End]
|
||||
```
|
||||
|
||||
## Class Diagram
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
Animal <|-- Duck
|
||||
Animal <|-- Fish
|
||||
Animal <|-- Zebra
|
||||
Animal : +int age
|
||||
Animal : +String gender
|
||||
Animal: +isMammal()
|
||||
Animal: +mate()
|
||||
class Duck{
|
||||
+String beakColor
|
||||
+swim()
|
||||
+quack()
|
||||
}
|
||||
class Fish{
|
||||
-int sizeInFeet
|
||||
-canEat()
|
||||
}
|
||||
class Zebra{
|
||||
+bool is_wild
|
||||
+run()
|
||||
}
|
||||
```
|
||||
|
||||
## State Diagram
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Active
|
||||
|
||||
state Active {
|
||||
[*] --> NumLockOff
|
||||
NumLockOff --> NumLockOn : EvNumLockPressed
|
||||
NumLockOn --> NumLockOff : EvNumLockPressed
|
||||
--
|
||||
[*] --> CapsLockOff
|
||||
CapsLockOff --> CapsLockOn : EvCapsLockPressed
|
||||
CapsLockOn --> CapsLockOff : EvCapsLockPressed
|
||||
--
|
||||
[*] --> ScrollLockOff
|
||||
ScrollLockOff --> ScrollLockOn : EvScrollLockPressed
|
||||
ScrollLockOn --> ScrollLockOff : EvScrollLockPressed
|
||||
}
|
||||
```
|
||||
|
||||
## Entity Relationship Diagram
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
CAR ||--o{ NAMED-DRIVER : allows
|
||||
CAR {
|
||||
string registrationNumber
|
||||
string make
|
||||
string model
|
||||
}
|
||||
PERSON ||--o{ NAMED-DRIVER : is
|
||||
PERSON {
|
||||
string firstName
|
||||
string lastName
|
||||
int age
|
||||
}
|
||||
```
|
||||
|
||||
## User Journey
|
||||
|
||||
```mermaid
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
If there's too much space above it's due to a [Mermaid bug](https://github.com/mermaid-js/mermaid/issues/3501)
|
||||
|
||||
:::
|
||||
|
||||
## Pie Chart
|
||||
|
||||
```mermaid
|
||||
pie showData
|
||||
title Key elements in Product X
|
||||
"Calcium" : 42.96
|
||||
"Potassium" : 50.05
|
||||
"Magnesium" : 10.01
|
||||
"Iron" : 5
|
||||
```
|
||||
|
||||
## Requirement Diagram
|
||||
|
||||
```mermaid
|
||||
requirementDiagram
|
||||
|
||||
requirement test_req {
|
||||
id: 1
|
||||
text: the test text.
|
||||
risk: high
|
||||
verifymethod: test
|
||||
}
|
||||
|
||||
functionalRequirement test_req2 {
|
||||
id: 1.1
|
||||
text: the second test text.
|
||||
risk: low
|
||||
verifymethod: inspection
|
||||
}
|
||||
|
||||
performanceRequirement test_req3 {
|
||||
id: 1.2
|
||||
text: the third test text.
|
||||
risk: medium
|
||||
verifymethod: demonstration
|
||||
}
|
||||
|
||||
interfaceRequirement test_req4 {
|
||||
id: 1.2.1
|
||||
text: the fourth test text.
|
||||
risk: medium
|
||||
verifymethod: analysis
|
||||
}
|
||||
|
||||
physicalRequirement test_req5 {
|
||||
id: 1.2.2
|
||||
text: the fifth test text.
|
||||
risk: medium
|
||||
verifymethod: analysis
|
||||
}
|
||||
|
||||
designConstraint test_req6 {
|
||||
id: 1.2.3
|
||||
text: the sixth test text.
|
||||
risk: medium
|
||||
verifymethod: analysis
|
||||
}
|
||||
|
||||
element test_entity {
|
||||
type: simulation
|
||||
}
|
||||
|
||||
element test_entity2 {
|
||||
type: word doc
|
||||
docRef: reqs/test_entity
|
||||
}
|
||||
|
||||
element test_entity3 {
|
||||
type: "test suite"
|
||||
docRef: github.com/all_the_tests
|
||||
}
|
||||
|
||||
|
||||
test_entity - satisfies -> test_req2
|
||||
test_req - traces -> test_req2
|
||||
test_req - contains -> test_req3
|
||||
test_req3 - contains -> test_req4
|
||||
test_req4 - derives -> test_req5
|
||||
test_req5 - refines -> test_req6
|
||||
test_entity3 - verifies -> test_req5
|
||||
test_req <- copies - test_entity2
|
||||
```
|
||||
|
||||
## Gitgraph (Git) Diagram
|
||||
|
||||
```mermaid
|
||||
%%{init: { 'logLevel': 'debug', 'theme': 'base' } }%%
|
||||
gitGraph
|
||||
commit
|
||||
branch hotfix
|
||||
checkout hotfix
|
||||
commit
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id:"ash" tag:"abc"
|
||||
branch featureB
|
||||
checkout featureB
|
||||
commit type:HIGHLIGHT
|
||||
checkout main
|
||||
checkout hotfix
|
||||
commit type:NORMAL
|
||||
checkout develop
|
||||
commit type:REVERSE
|
||||
checkout featureB
|
||||
commit
|
||||
checkout main
|
||||
merge hotfix
|
||||
checkout featureB
|
||||
commit
|
||||
checkout develop
|
||||
branch featureA
|
||||
commit
|
||||
checkout develop
|
||||
merge hotfix
|
||||
checkout featureA
|
||||
commit
|
||||
checkout featureB
|
||||
commit
|
||||
checkout develop
|
||||
merge featureA
|
||||
branch release
|
||||
checkout release
|
||||
commit
|
||||
checkout main
|
||||
commit
|
||||
checkout release
|
||||
merge main
|
||||
checkout develop
|
||||
merge release
|
||||
```
|
||||
|
||||
## Mermaid in tabs
|
||||
|
||||
````mdx-code-block
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="tab-a">
|
||||
|
||||
The following mermaid diagram is shown:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
a ---> c(10)
|
||||
b ---> c(10)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="tab-b">
|
||||
|
||||
This mermaid diagram is not displayed:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
d ---> z(42)
|
||||
e ---> z(42)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
````
|
||||
|
|
@ -27,6 +27,7 @@ import Readme from "../README.md"
|
|||
- [Asset linking tests](/tests/pages/markdown-tests)
|
||||
- [General Markdown tests](/tests/pages/markdownPageTests)
|
||||
- [TOC tests](/tests/pages/page-toc-tests)
|
||||
- [Diagram tests](/tests/pages/diagrams)
|
||||
- [Tabs tests](/tests/pages/tabs-tests)
|
||||
- [z-index tests](/tests/pages/z-index-tests)
|
||||
- [Head metadata tests](/tests/pages/head-metadata)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ See the <a href={require('@docusaurus/useBaseUrl').default('showcase')}>showcase
|
|||
- [docusaurus-plugin-module-alias](https://github.com/atomicpages/docusaurus-plugin-module-alias) - A Docusaurus v2 plugin for quickly aliasing local modules
|
||||
- [docusaurus-protobuffet](https://github.com/protobuffet/docusaurus-protobuffet) - Docusaurus toolset for Protobuf contract documentation
|
||||
- [docusaurus-prince-pdf](https://github.com/signcl/docusaurus-prince-pdf) - Generate PDF with PrinceXML for better font subsetting and ToC features. Support Docusaurus v2 sites
|
||||
- [mdx-mermaid](https://github.com/sjwall/mdx-mermaid) - A Docusaurus v2 compatible MDX plugin for displaying [Mermaid](https://mermaid-js.github.io/mermaid) diagrams
|
||||
- [redocusaurus](https://github.com/rohit-gohri/redocusaurus) - A Docusaurus preset for integrating OpenAPI documentation into your docs with [Redoc](https://github.com/redocly/redoc)
|
||||
- [plugin-image-zoom](https://github.com/flexanalytics/plugin-image-zoom) - An Image Zoom plugin for Docusaurus 2
|
||||
- [docusaurus-plugin-typedoc](https://github.com/tgreyuk/typedoc-plugin-markdown/tree/master/packages/docusaurus-plugin-typedoc) - A Docusaurus 2 plugin to build documentation with [TypeDoc](https://typedoc.org/)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
---
|
||||
id: diagrams
|
||||
title: Diagrams
|
||||
description: Writing diagrams with Mermaid
|
||||
slug: /markdown-features/diagrams
|
||||
---
|
||||
|
||||
# Diagrams
|
||||
|
||||
Diagrams can be rendered using [Mermaid](https://mermaid-js.github.io/mermaid/) in a code block.
|
||||
|
||||
## Installation {#installation}
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save @docusaurus/theme-mermaid
|
||||
```
|
||||
|
||||
Enable Mermaid functionality by adding plugin `@docusaurus/theme-mermaid` and setting `markdown.mermaid` to `true` in your `docusaurus.config.js`.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
},
|
||||
themes: ['@docusaurus/theme-mermaid'],
|
||||
};
|
||||
```
|
||||
|
||||
## Usage {#usage}
|
||||
|
||||
Add a code block with language `mermaid`:
|
||||
|
||||
````md title="Example Mermaid diagram"
|
||||
```mermaid
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
```
|
||||
````
|
||||
|
||||
```mermaid
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
```
|
||||
|
||||
See the [Mermaid syntax documentation](https://mermaid-js.github.io/mermaid/#/./n00b-syntaxReference) for more information on the Mermaid syntax.
|
||||
|
||||
## Theming {#theming}
|
||||
|
||||
The diagram dark and light themes can be changed by setting `mermaid.theme` values in the `themeConfig` in your `docusaurus.config.js`. You can set themes for both light and dark mode.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
themeConfig: {
|
||||
mermaid: {
|
||||
theme: {light: 'neutral', dark: 'forest'},
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
See the [Mermaid theme documentation](https://mermaid-js.github.io/mermaid/#/theming) for more information on theming Mermaid diagrams.
|
||||
|
||||
## Mermaid Config {#configuration}
|
||||
|
||||
Options in `mermaid.mermaidOptions` will be passed directly to `mermaid.initialize`:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
themeConfig: {
|
||||
mermaid: {
|
||||
mermaidOptions: {
|
||||
maxTextSize: 50,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
See the [Mermaid configuration documentation](https://mermaid-js.github.io/mermaid/#/./Setup?id=configuration) for the available config options.
|
||||
|
|
@ -114,6 +114,9 @@ const config = {
|
|||
},
|
||||
}),
|
||||
},
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
},
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/docusaurus.ico',
|
||||
|
|
@ -276,6 +279,7 @@ const config = {
|
|||
],
|
||||
},
|
||||
],
|
||||
'@docusaurus/theme-mermaid',
|
||||
...dogfoodingPluginInstances,
|
||||
],
|
||||
presets: [
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
"@docusaurus/remark-plugin-npm2yarn": "2.1.0",
|
||||
"@docusaurus/theme-classic": "2.1.0",
|
||||
"@docusaurus/theme-common": "2.1.0",
|
||||
"@docusaurus/theme-mermaid": "2.1.0",
|
||||
"@docusaurus/theme-live-codeblock": "2.1.0",
|
||||
"@docusaurus/utils": "2.1.0",
|
||||
"@docusaurus/utils-common": "2.1.0",
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ const sidebars = {
|
|||
'guides/markdown-features/links',
|
||||
'guides/markdown-features/plugins',
|
||||
'guides/markdown-features/math-equations',
|
||||
'guides/markdown-features/diagrams',
|
||||
'guides/markdown-features/head-metadata',
|
||||
],
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue