Skip to content

Commit

Permalink
feat: support mermaid diagrams (#8599)
Browse files Browse the repository at this point in the history
  • Loading branch information
yufeih authored Apr 6, 2023
1 parent 15df6e8 commit 4551e4e
Show file tree
Hide file tree
Showing 26 changed files with 1,419 additions and 228 deletions.
95 changes: 95 additions & 0 deletions docs/docs/markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,101 @@ $$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \

$$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)$$

## Mermaid Diagrams

You can embed [mermaid](https://mermaid.js.org/) diagrams using markdown code block:

Example:

```mermaid
flowchart LR

A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```

This will be rendered as:

```mermaid
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```

> [!NOTE]
> Mermaid diagrams is only supported in the `modern` template.
There are plenty of other diagrams supported by mermaid such as:

Pie chart

```mermaid
pie
"Dogs" : 386
"Cats" : 85.9
"Rats" : 15
```

Bar chart

```mermaid
gantt
title Git Issues - days since last update
dateFormat X
axisFormat %s
section Issue19062
71 : 0, 71
section Issue19401
36 : 0, 36
section Issue193
34 : 0, 34
section Issue7441
9 : 0, 9
section Issue1300
5 : 0, 5
```

User Journey diagram

```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: 3: Me
```

Class diagram

```mermaid
classDiagram
Class01 <|-- AveryLongClass : Cool
<<Interface>> Class01
Class09 --> C2 : Where am I?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
class Class10 {
<<service>>
int id
size()
}
```

## Include Markdown Files

Where markdown files need to be repeated in multiple articles, you can use an include file. The includes feature replace the reference with the contents of the included file at build time.
Expand Down
133 changes: 27 additions & 106 deletions samples/seed/articles/markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,8 @@

[Markdown](https://daringfireball.net/projects/markdown/) is a lightweight markup language with plain text formatting syntax. Docfx supports [CommonMark](https://commonmark.org/) compliant Markdown parsed through the [Markdig](https://github.com/xoofx/markdig) parsing engine.

## Markdown Extensions

Docfx supports additional markdown syntax that provide richer content. These syntax are specific to docfx and won't be rendered elsewhere like GitHub.

To use a custom markdown extension:

1. Use docfx as a NuGet library:

```xml
<PackageReference Include="Microsoft.DocAsCode.App" Version="2.61.0" />
```

2. Configure the markdig markdown pipeline:

```cs
var options = new BuildOptions
{
// Enable custom markdown extensions here
ConfigureMarkdig = pipeline => pipeline.UseCitations(),
}

await Docset.Build("docfx.json", options);
```

Here is a list of markdown extensions provided by docfx by default.

## Alerts

Alerts are block quotes that render with colors and icons that indicate the significance of the content.

The following alert types are supported:

```markdown
> [!NOTE]
> Information the user should notice even if skimming.

> [!TIP]
> Optional information to help a user be more successful.

> [!IMPORTANT]
> Essential information required for user success.

> [!CAUTION]
> Negative potential consequences of an action.

> [!WARNING]
> Dangerous certain consequences of an action.
```

They look like this in rendered page:

> [!NOTE]
> Information the user should notice even if skimming.
Expand All @@ -70,71 +21,45 @@ They look like this in rendered page:
## Image

You can embed a image in your page by using the following Markdown syntax:

```md
![ <alt-text> ]( <image-link> )
```

Example:
```md
![alt-text](https://learn.microsoft.com/en-us/media/learn/not-found/learn-not-found-light-mode.png?branch=main)
```

This will be rendered as:

![alt-text](https://learn.microsoft.com/en-us/media/learn/not-found/learn-not-found-light-mode.png?branch=main)

## Include Markdown Files
## Mermaid Diagrams

Where markdown files need to be repeated in multiple articles, you can use an include file. The includes feature replace the reference with the contents of the included file at build time.
Flowchart

You can reuse a common text snippet within a sentence using inline include:
```mermaid
flowchart LR
```markdown
Text before [!INCLUDE [<title>](<filepath>)] and after.
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```

Or reuse an entire Markdown file as a block, nested within a section of an article. Block include is on its own line:
Pie chart

```markdown
[!INCLUDE [<title>](<filepath>)]
```mermaid
pie
"Dogs" : 386
"Cats" : 85.9
"Rats" : 15
```

Where `<title>` is the name of the file and `<filepath>` is the relative path to the file.

Included markdown files needs to be excluded from build, they are usually placed in the `/includes` folder.

## Code Snippet

There are several ways to include code in an article. The code snippet syntax replaces code from another file:

```markdown
[!code-csharp[](Program.cs)]
User Journey diagram

```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: 3: Me
```

You can include selected lines from the code snippet using region or line range syntax:

```markdown
[!code-csharp[](Program.cs#region)]
[!code-csharp[](Program.cs#L12-L16)]
```

Code snippets are indicated by using a specific link syntax described as follows:

```markdown
[!code-<language>[](<filepath><query-options>)]
```

Where `<language>` is the syntax highlighting language of the code and `<filepath>` is the relative path to the markdown file.

### Highlight Selected Lines

Code Snippets typically include more code than necessary in order to provide context. It helps readability when you highlight the key lines that you're focusing on. To highlight key lines, use the `highlight` query options:

```markdown
[!code-csharp[](Program.cs?highlight=2,5-7,9-)]
```
## Code Snippet

The example highlights lines 2, line 5 to 7 and lines 9 to the end of the file.

Expand All @@ -154,10 +79,6 @@ To split <span>$</span>100 in half, we calculate $100/2$

## Tabs

Tabs enable content that is multi-faceted. They allow sections of a document to contain variant content renderings and eliminates duplicate content.

Here's an example of the tab experience:

# [Linux](#tab/linux)

Content for Linux...
Expand Down
3 changes: 1 addition & 2 deletions templates/modern/src/docfx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ declare global {
window.docfx = {}

document.addEventListener('DOMContentLoaded', function() {
highlight()
enableSearch()

renderMarkdown()
renderFooter()
highlight()

Promise.all([renderNavbar(), renderToc()])
.then(([navbar, toc]) => renderBreadcrumb([...navbar, ...toc]))
Expand Down
18 changes: 18 additions & 0 deletions templates/modern/src/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import { breakWord } from './helper'
import AnchorJs from 'anchor-js'
import { html, render } from 'lit-html'
import mermaid from 'mermaid'
import { getTheme } from './theme'

/**
* Initialize markdown rendering.
*/
export function renderMarkdown() {
renderMermaid()
renderWordBreaks()
renderTables()
renderAlerts()
Expand All @@ -19,6 +22,21 @@ export function renderMarkdown() {
renderClickableImage()
}

/**
* Render mermaid diagrams.
*/
function renderMermaid() {
document.querySelectorAll('pre code.lang-mermaid').forEach(code => {
const pre = code.parentElement
pre.classList.add('mermaid')
code.remove()
pre.appendChild(document.createTextNode(code.textContent))
})

const theme = getTheme() === 'dark' ? 'dark' : 'default'
mermaid.initialize({ startOnLoad: true, deterministicIds: true, theme })
}

/**
* Add <wbr> to break long text.
*/
Expand Down
4 changes: 4 additions & 0 deletions templates/modern/src/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ function setTheme(theme: Theme) {
}
}

export function getTheme(): 'light' | 'dark' {
return document.documentElement.getAttribute('data-bs-theme') as 'light' | 'dark'
}

export function themePicker(refresh: () => void) {
const theme = localStorage.getItem('theme') as Theme || 'auto'
setTheme(theme)
Expand Down
Loading

0 comments on commit 4551e4e

Please sign in to comment.