Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions docs/reference/diagrams.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ popular and flexible solution for drawing diagrams.
<!-- md:version 8.2.0 -->

This configuration enables native support for [Mermaid.js] diagrams. Material
for MkDocs will automatically initialize the JavaScript runtime when a page
for MkDocs will automatically initialize the JavaScript runtime when a page
includes a `mermaid` code block:

``` yaml
Expand All @@ -38,14 +38,40 @@ No further configuration is necessary. Advantages over a custom integration:
[^1]:
While all [Mermaid.js] features should work out-of-the-box, Material for
MkDocs will currently only adjust the fonts and colors for flowcharts,
sequence diagrams, class diagrams, state diagrams and entity relationship
sequence diagrams, class diagrams, state diagrams and entity relationship
diagrams. See the section on [other diagrams] for more information why this
is currently not implemented for all diagrams.

[instant loading]: ../setup/setting-up-navigation.md#instant-loading
[additional style sheets]: ../customization.md#additional-css
[other diagrams]: #other-diagram-types

### Loading additional icon packs

You can define additional [icon packs](https://mermaid.js.org/config/icons.html) you want be loaded by specifying list in `theme.mermaid.iconPacks`

Options:
- `url:<prefix>:<url>` for loading from Icon Packs from URL
- `iconify:<package>@<version>` for loading icons from iconify

``` yaml
theme:
mermaid:
iconPacks:
- iconify:logos@1
- url:aws:https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v19.0/dist/aws-icons-mermaid.json
```

### Overriding Mermaid JS version

Mermaid JS version can be overrided by providing `theme.mermaid.version` value. Use this carefully.

``` yaml
theme:
mermaid:
version: "11"
```

## Usage

### Using flowcharts
Expand Down Expand Up @@ -82,7 +108,7 @@ graph LR

### Using sequence diagrams

[Sequence diagrams] describe a specific scenario as sequential interactions
[Sequence diagrams] describe a specific scenario as sequential interactions
between multiple objects or actors, including the messages that are exchanged
between those actors:

Expand Down Expand Up @@ -194,7 +220,7 @@ classDiagram
+int postalCode
+String country
-validate()
+outputAsLabel()
+outputAsLabel()
}
```
````
Expand Down Expand Up @@ -226,7 +252,7 @@ classDiagram
+int postalCode
+String country
-validate()
+outputAsLabel()
+outputAsLabel()
}
```

Expand Down
33 changes: 33 additions & 0 deletions docs/schema/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,39 @@
}
}
]
},
"mermaid": {
"title": "Mermaid JS configuration",
"type": "object",
"properties": {
"version": {
"title": "Mermaid JS version",
"description": "ID of version to be substituted in https://unpkg.com/mermaid@(VERSION)/dist/mermaid.min.js",
"examples": [
"11"
]
},
"iconPacks": {
"title": "Icon packs",
"type": "array",
"items": {
"title": "Name of icon pack",
"description": "url:https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v19.0/dist/aws-icons-mermaid.json or iconify:logos@1",
"type": "string",
"examples": [
"url:aws:https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v19.0/dist/aws-icons-mermaid.json",
"iconify:logos@1"
]
},
"examples": [
[
"url:aws:https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v19.0/dist/aws-icons-mermaid.json",
"iconify:logos@1"
]
]
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
Expand Down
2 changes: 1 addition & 1 deletion material/overrides/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
{% endblock %}
{% block scripts %}
{{ super() }}
<script src="{{ 'assets/javascripts/custom.00e08f28.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/custom.4e16f5b8.min.js' | url }}"></script>
{% endblock %}
5 changes: 4 additions & 1 deletion material/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,15 @@
] -%}
{%- set _ = translations.update({ key: lang.t(key) }) -%}
{%- endfor -%}
{%- if config.theme.mermaid -%}
{%- set _ = app.update({ "mermaid": config.theme.mermaid }) -%}
{%- endif -%}
<script id="__config" type="application/json">
{{- app | tojson -}}
</script>
{% endblock %}
{% block scripts %}
<script src="{{ 'assets/javascripts/bundle.5090c770.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.b64615fe.min.js' | url }}"></script>
{% for script in config.extra_javascript %}
{{ script | script_tag }}
{% endfor %}
Expand Down
9 changes: 9 additions & 0 deletions src/templates/assets/javascripts/_/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ export interface Versioning {
alias?: boolean /* Show alias */
}

/**
* Mermaid JS Configuration
*/
export interface MermaidConfig {
version?: string
iconPacks?: string[]
}

/**
* Configuration
*/
Expand All @@ -96,6 +104,7 @@ export interface Config {
search: string /* Search worker URL */
tags?: Record<string, string> /* Tags mapping */
version?: Versioning /* Versioning */
mermaid?: MermaidConfig /* Mermaid JS configuration */
}

/* ----------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

import { Observable, merge } from "rxjs"

import { feature } from "~/_"
import { configuration, feature } from "~/_"
import { Viewport, getElements } from "~/browser"

import { Component } from "../../_"
Expand Down Expand Up @@ -114,7 +114,7 @@ export function mountContent(

/* Mermaid diagrams */
...getElements("pre.mermaid", el)
.map(child => mountMermaid(child)),
.map(child => mountMermaid(child, configuration().mermaid)),

/* Data tables */
...getElements("table:not([class])", el)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {

import { watchScript } from "~/browser"
import { h } from "~/utilities"
import { MermaidConfig } from "~/_"

import { Component } from "../../_"

Expand Down Expand Up @@ -67,16 +68,70 @@ let sequence = 0
*
* @returns Mermaid scripts observable
*/
function fetchScripts(): Observable<void> {
function fetchScripts(config?: MermaidConfig): Observable<void> {
let version = "11";
if (config && config.version) {
version = config.version;
}

return typeof mermaid === "undefined" || mermaid instanceof Element
? watchScript("https://unpkg.com/mermaid@11/dist/mermaid.min.js")
? watchScript(`https://unpkg.com/mermaid@${version}/dist/mermaid.min.js`)
: of(undefined)
}

/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */


/**
* Icon descriptor for Mermaid JS icon Packs
*/
interface IconPackDescriptor {
name: string,
loader: () => Promise<any>
}

/**
* Prepare details about icon packs for Mermaid JS
*
* @param iconName - Icon name. url:https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v19.0/dist/aws-icons-mermaid.json or iconify:logos@1
* @returns icon pack descriptor for Mermaid JS
*/
export function prepareIconDescriptor(iconName: string): IconPackDescriptor | undefined {
// First - we need to strip type from full icon name
const parts = iconName.split(':');
if (parts.length < 2) {
return undefined;
}

switch (parts[0]){
case 'url':
if (parts.length < 3) {
return undefined;
}

const url = parts.slice(2).join(':');
return {
name: parts[1],
loader: () => fetch(url).then((res) => res.json()),
}
case 'iconify':
const iconifyParts = parts[1].split('@', 2);
if (iconifyParts.length !== 2) {
return undefined;
}

return {
name: iconifyParts[0],
loader: () => fetch(`https://unpkg.com/@iconify-json/${parts[1]}/icons.json`).then((res) => res.json()),
}

default:
return undefined;
}
}

/**
* Mount Mermaid diagram
*
Expand All @@ -85,20 +140,29 @@ function fetchScripts(): Observable<void> {
* @returns Mermaid diagram component observable
*/
export function mountMermaid(
el: HTMLElement
el: HTMLElement, config?: MermaidConfig
): Observable<Component<Mermaid>> {
el.classList.remove("mermaid") // Hack: mitigate https://bit.ly/3CiN6Du
mermaid$ ||= fetchScripts()
mermaid$ ||= fetchScripts(config)
.pipe(
tap(() => mermaid.initialize({
startOnLoad: false,
themeCSS,
sequence: {
actorFontSize: "16px", // Hack: mitigate https://bit.ly/3y0NEi3
messageFontSize: "16px",
noteFontSize: "16px"
tap(() => {
mermaid.initialize({
startOnLoad: false,
themeCSS,
sequence: {
actorFontSize: "16px", // Hack: mitigate https://bit.ly/3y0NEi3
messageFontSize: "16px",
noteFontSize: "16px"
}
});

/* Load icon packs */
if (config && config.iconPacks) {
mermaid.registerIconPacks(
config.iconPacks.map(name => prepareIconDescriptor(name)).filter(descriptor => descriptor !== undefined)
);
}
})),
}),
map(() => undefined),
shareReplay(1)
)
Expand Down
5 changes: 5 additions & 0 deletions src/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@
{%- set _ = translations.update({ key: lang.t(key) }) -%}
{%- endfor -%}

<!-- Mermaid -->
{%- if config.theme.mermaid -%}
{%- set _ = app.update({ "mermaid": config.theme.mermaid }) -%}
{%- endif -%}

<!-- Configuration -->
<script id="__config" type="application/json">
{{- app | tojson -}}
Expand Down