Skip to content
Merged
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
2 changes: 2 additions & 0 deletions FSharp.Formatting.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{194B
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{312E452A-1068-4804-89E7-0AFBAD5F885F}"
ProjectSection(SolutionItems) = preProject
docs\_body.html = docs\_body.html
docs\_template.html = docs\_template.html
docs\apidocs.fsx = docs\apidocs.fsx
docs\codeformat.fsx = docs\codeformat.fsx
Expand All @@ -29,6 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{312E452A-1
docs\index.md = docs\index.md
docs\literate.fsx = docs\literate.fsx
docs\markdown.fsx = docs\markdown.fsx
docs\mermaid.md = docs\mermaid.md
docs\styling.md = docs\styling.md
docs\upgrade.md = docs\upgrade.md
docs\users.md = docs\users.md
Expand Down
5 changes: 5 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [Unreleased]

### Changed
* Rewrote the Mermaid documentation recipe as `docs/mermaid.md` (moved from the oddly-named `docs/sidebyside/sidemermaid.md`) to follow the approach used by the fantomas docs: diagrams are written as plain ```mermaid fenced code blocks, which GitHub renders natively, and an `_body.html` script promotes those blocks into `<div class="mermaid">` elements on fsdocs pages. The FSharp.Formatting docs now ship that script (`docs/_body.html`), so the recipe page actually demonstrates working diagrams.

## [22.2.0] - 2026-08-31

### Changed
Expand Down
7 changes: 7 additions & 0 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,11 @@ pipeline "Verify" {
runIfOnlySpecified true
}

// Start the documentation site in watch mode with the locally built fsdocs tool.
// Runs until interrupted (Ctrl+C); the site is served on http://localhost:8901.
pipeline "Docs" {
stage "WatchDocs" { run "dotnet run --project src/fsdocs-tool -- watch" }
runIfOnlySpecified true
}

tryPrintPipelineCommandHelp ()
23 changes: 23 additions & 0 deletions docs/_body.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';

// A ```mermaid fenced block renders natively on GitHub, but reaches fsdocs
// as a syntax-highlighted code block. Promote those blocks to
// <div class="mermaid"> elements so one plain fence works in both places.
for (const code of document.querySelectorAll('code[lang="mermaid"]')) {
// fsdocs wraps the snippet in <table class="pre"><tr><td><pre><code>...;
// replace the outermost wrapper so no table scaffolding is left around
// the diagram.
const snippet = code.closest('table.pre') ?? code.closest('pre');
if (!snippet) continue;
const diagram = document.createElement('div');
diagram.className = 'mermaid';
// textContent, not innerHTML: the source arrives HTML-escaped
// (arrows come through with escaped angle brackets) and mermaid needs
// the raw arrows back.
diagram.textContent = code.textContent;
snippet.replaceWith(diagram);
}

mermaid.initialize({ startOnLoad: true });
</script>
10 changes: 9 additions & 1 deletion docs/content/fsdocs-theme.css
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
/* Override any variables here */
/* Override any variables here */

.mermaid {
margin: 1rem auto;
& svg {
display: block;
margin: 0 auto;
}
}
112 changes: 112 additions & 0 deletions docs/mermaid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: Mermaid Diagrams
category: Examples
categoryindex: 2
index: 4
---
# Example: Mermaid Diagrams

[Mermaid](https://mermaid.js.org/) is a JavaScript-based diagramming and charting tool that renders Markdown-inspired text definitions into diagrams.

The recommended way to use Mermaid with fsdocs is to write diagrams as plain fenced code blocks, and add a small script that turns those blocks into diagrams when the page loads. The Markdown stays portable: GitHub renders ` ```mermaid ` fences natively, and your fsdocs site shows the real diagrams. This very page uses the pattern below, so the diagrams you see are fenced code blocks promoted by a `_body.html` script.

## Setup

Create or edit a `_body.html` file in your `docs` folder. fsdocs injects it at the end of every page, after the content. The script imports mermaid and promotes fenced mermaid blocks to the `<div class="mermaid">` elements mermaid looks for:

````html
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';

// A ```mermaid fenced block renders natively on GitHub, but reaches fsdocs
// as a syntax-highlighted code block. Promote those blocks to
// <div class="mermaid"> elements so one plain fence works in both places.
for (const code of document.querySelectorAll('code[lang="mermaid"]')) {
// fsdocs wraps the snippet in <table class="pre"><tr><td><pre><code>...;
// replace the outermost wrapper so no table scaffolding is left around
// the diagram.
const snippet = code.closest('table.pre') ?? code.closest('pre');
if (!snippet) continue;
const diagram = document.createElement('div');
diagram.className = 'mermaid';
// textContent, not innerHTML: the source arrives HTML-escaped
// (arrows come through with escaped angle brackets) and mermaid needs
// the raw arrows back.
diagram.textContent = code.textContent;
snippet.replaceWith(diagram);
}

mermaid.initialize({ startOnLoad: true });
</script>
````

## Usage

Write your diagram in a fenced code block with the `mermaid` language tag:

````text
```mermaid
graph LR
A[Input docs] --> B[fsdocs build]
B --> C[HTML output]
B --> D[API reference]
```
````

On this site, the block above is rendered as:

```mermaid
graph LR
A[Input docs] --> B[fsdocs build]
B --> C[HTML output]
B --> D[API reference]
```

## More Examples

Sequence diagram:

```mermaid
sequenceDiagram
participant User
participant fsdocs
participant Browser
User->>fsdocs: dotnet fsdocs watch
fsdocs-->>Browser: Serve docs
User->>fsdocs: Edit .md or .fsx
fsdocs-->>Browser: Reload page
```

Class diagram:

```mermaid
classDiagram
class ApiDocComment {
+Summary: string
+Remarks: string option
+Parameters: ApiDocSection list
}
class ApiDocMember {
+Name: string
+Comment: ApiDocComment
}
ApiDocMember --> ApiDocComment
```

## Tips

- To customise the Mermaid theme, pass options to `mermaid.initialize()`, for example `theme: "base"` together with `themeVariables`.
- To centre the diagrams, add a rule for the promoted element to your `docs/content/fsdocs-theme.css`:

```css
.mermaid {
margin: 1rem auto;
& svg {
display: block;
margin: 0 auto;
}
}
```

- You can also write `<div class="mermaid">` blocks directly in your Markdown. The promotion script only touches fenced code blocks, so both forms can coexist.
- See the [Mermaid documentation](https://mermaid.js.org/intro/) for the full list of supported diagram types.
79 changes: 0 additions & 79 deletions docs/sidebyside/sidemermaid.md

This file was deleted.

Loading