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 .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Preserve the upstream bundle bytes so its documented SHA-256 stays verifiable.
src/SQLBI.Whiteboard/Mermaid/Web/mermaid.min.js binary
20 changes: 18 additions & 2 deletions .github/workflows/publish-winget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,27 @@ jobs:
# $urls, not @urls: the @ prefix is splatting, which applies to cmdlets. A plain
# array passed to a native command already expands to one argument per element.
$urls = $env:URLS -split ' '
$manifests = Join-Path $env:RUNNER_TEMP 'winget-manifests'

# update writes the manifests locally instead of submitting them, because it
# cannot add a dependency, and scripts/winget-dependencies.ps1 adds the WebView2
# Runtime that Mermaid diagrams need (decision 34) before they are submitted.
& $exe update SQLBI.Whiteboard `
--version $env:VERSION `
--urls $urls `
--submit `
--out $manifests `
--token $env:WINGET_TOKEN
if ($LASTEXITCODE -ne 0) {
throw "wingetcreate update exited with $LASTEXITCODE."
}

./scripts/winget-dependencies.ps1 -ManifestDirectory $manifests
$folder = Get-ChildItem -LiteralPath $manifests -Recurse -File -Filter 'SQLBI.Whiteboard.installer.yaml' |
Select-Object -First 1 -ExpandProperty DirectoryName

& $exe submit $folder `
--prtitle "New version: SQLBI.Whiteboard version $env:VERSION" `
--token $env:WINGET_TOKEN
if ($LASTEXITCODE -ne 0) {
throw "wingetcreate exited with $LASTEXITCODE. If the fork could not be synced, sync it on GitHub and run this workflow again; docs/release-management.md has the cause."
throw "wingetcreate submit exited with $LASTEXITCODE. If the fork could not be synced, sync it on GitHub and run this workflow again; docs/release-management.md has the cause."
}
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ broke. The heading is parsed by `scripts/release-notes.ps1`, so keep its shape;
under it is ordinary Markdown, and the renderer handles paragraphs, lists, links, `code`
and **bold**.

## 1.7.5 - 1 October 2026

### Mermaid diagrams in Markdown
A `mermaid` code block in a Markdown container is drawn as a diagram: flowcharts, sequence and
state diagrams, mind maps, charts, timelines, and the other Mermaid 12 diagram types. The board
saves each diagram with its source, so it reopens and exports as it was. New or changed diagrams
need the Microsoft Edge WebView2 Runtime, which Windows 11 includes; without it, a diagram shows
its source and says what is missing.

## 1.7.4 - 30 September 2026

### Templates from Microsoft Whiteboard
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
scripts/build-installer.ps1 both read it from here, so releasing is a reviewed change
to this line rather than an edit in a pipeline variable group.
-->
<VersionPrefix>1.7.4</VersionPrefix>
<VersionPrefix>1.7.5</VersionPrefix>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ How the project is developed and shipped is documented separately:
- SVG is stored as its markup and redrawn as vectors at every zoom and resize. Pasting SVG markup that was copied as text — the output of a DAX SVG measure, for instance — creates a picture, and copying an SVG container puts both the markup and a bitmap on the clipboard. Text set in a Microsoft 365 font such as Aptos is drawn in that font when Office has it on the machine
- Image selection, movement, resizing, and deletion
- Text containers created by pasting plain text, with display and in-place edit modes
- Seventeen text-container types: fifteen languages with live syntax highlighting, plus Prompt and Markdown, and local F6 formatting for DAX, SQL Server, and KQL
- Seventeen text-container types: fifteen languages with live syntax highlighting, plus Prompt and Markdown with Mermaid diagrams, and local F6 formatting for DAX, SQL Server, and KQL
- An **Insert** tab with nine shapes drawn by dragging, with outline color, fill, line thickness, and text of their own in ten fonts; three connectors that bind wherever an end is dropped on a shape or a container, follow it, and can be drawn from the four arrows on a selected shape; and text labels typed on the board. A shape or a label turns to any angle by its handle, and the pin at the end of the row makes it a palette you can move
- Selection by area: drag with Select for a rectangle, or hold Select for a freehand outline. Ctrl+A takes everything and Ctrl+Shift+A the ink alone, and the **…** on the selection offers Delete, Copy, Duplicate, and the four depth commands. Ink is taken too, and everything the area takes moves, resizes, recolors, reorders, and deletes as one
- An optional background grid, Lines or Dots, whose spacing is fixed in board pixels and coarsens as the zoom goes out. It is drawn on screen only and never appears in an export or a preview
Expand Down Expand Up @@ -253,6 +253,8 @@ Prompt detection uses clipboard format `SQLBI.PromptAssistant.Metadata.v1` conta

Choose **Markdown** from the title-bar chip for a formatted answer or a note: headings, emphasis, lists, tables, quotations, and code blocks keep their layout. Paste recognizes Markdown through Snippet format order, and converts structured clipboard HTML when it carries formatting the plain text has lost. **F2** edits the Markdown source and **Ctrl+Enter** renders it again; **F6** does nothing on it, the corner handle scales the rendered visual, and the right edge reflows it. Markdown exports as a picture to preserve its layout, with its source retained in PowerPoint notes; see [docs/markdown.md](docs/markdown.md) for clipboard behavior, supported structures, and limitations.

A `mermaid` code block in Markdown is drawn as a diagram, in any of the 32 diagram types built into Mermaid 12, including flowcharts, sequence diagrams, mind maps, charts, timelines, and architecture diagrams. A bundled copy of Mermaid draws it locally in the Microsoft Edge WebView2 Runtime, and the board saves the result with the source, so a saved diagram reopens and exports without the runtime. See [docs/markdown.md](docs/markdown.md#mermaid-diagrams) for the diagram types and limits.

Image files, and `.txt`, `.dax`, `.sql`, and `.kql` files, can be dropped directly from File Explorer. Their initial center is the board position at which they were dropped. DAX, SQL, and KQL files open in the matching language mode. Other dropped text files use Snippet format order.

### `.wimport` recipes
Expand Down
37 changes: 37 additions & 0 deletions docs/decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,43 @@ application to annotate a demo needs none of them, and every one of them is in t

---

## 34. Mermaid diagrams are drawn by a bundled Mermaid in WebView2

**Implemented.**

Mermaid is a JavaScript library that needs a browser DOM to lay out a diagram, so drawing
one needs a browser engine. Whiteboard bundles `mermaid.min.js` unmodified and runs it in a
hidden WebView2 controller, which uses the Microsoft Edge WebView2 Runtime already on the
machine. No CDN, Node.js runtime, or Mermaid CLI is involved, and the controller blocks
network requests, so a diagram's source does not leave the PC.

- **The installer does not carry the runtime, and the minimum Windows version did not
move.** Windows 11 includes the runtime, and Microsoft delivered it to most Windows 10
machines through Windows Update, but no Windows 10 version guarantees it, and a clean install
or an LTSC edition can lack it. Raising the minimum would therefore not have closed the gap.
Before starting the browser, `MermaidRenderer` asks the WebView2 loader for an installed
runtime. Without one, every new or changed diagram shows its source with a message naming
the runtime and pointing to the FAQ, which links to Microsoft's download. Saved diagrams
still show from their snapshots. The installers are plain MSIs, and running the WebView2
bootstrapper from one would mean a custom action that downloads and starts another
installer, or a Burn bundle in front of the four products of decision 6. Neither was
worth it for the few machines affected.
- **winget installs the runtime where it is missing.** Each submission declares
`Microsoft.EdgeWebView2Runtime` as a package dependency, which winget skips when the
runtime is already installed. The workflow adds it to every submission rather than once
by hand, as [release-management.md](release-management.md#winget) describes.
- **The WebView2 binaries are not in the signing step.** `Microsoft.Web.WebView2.*.dll` and
`WebView2Loader.dll` arrive from NuGet already signed by Microsoft, and the installer
harvests them with the rest of the publish folder. The Mermaid bundle is a script, not an
assembly. Its version, source, and SHA-256 are recorded in [mermaid.md](mermaid.md), and
`.gitattributes` marks it binary so the recorded hash stays verifiable.
- **A board saves each diagram as SVG beside its source.** Reopening a board decodes the
saved SVG without starting a browser, and the diagram looks the same where the runtime is
missing. The field is optional, so the archive version did not move, and releases before
1.7.5 ignore it.

---

## Open questions

- arm64 is not built; add it if Surface devices matter for a pen application.
Expand Down
64 changes: 63 additions & 1 deletion docs/markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,71 @@ table/text objects. PowerPoint notes retain the source. The image fallback is ca
- Raw HTML is displayed as literal text, except simple line breaks in table cells.
- HTML clipboard conversion preserves semantic markup, not arbitrary CSS, fonts, or colors.
Merged/nested HTML tables are not reproduced as merged/nested tables.
- Mathematical notation, Mermaid diagrams, task-checkbox widgets, and other Markdown
- Mathematical notation, task-checkbox widgets, and other Markdown
extensions beyond the supported subset are not rendered specially.

## Mermaid diagrams

Fenced `mermaid` blocks render the 32 diagram families built into Mermaid 12.0.0.
Paste their Markdown source, or drop
[the sample file](samples/mermaid-diagrams.md) onto the board. Choose **Markdown**
if your Snippet format order selects another language. Edit with **F2** and commit
with **Ctrl+Enter**. A copied diagram picture carries no editable Mermaid source.

Mind maps support indented branches, node shapes, and multiline styled labels. State
diagrams support transitions, start/end markers, nested states, notes, choices,
forks/joins, and concurrent regions. Try [the mind-map and state samples](samples/mermaid-mindmaps-states.md).

The full catalogue is listed below. Aliases, layouts, and notations within a family
are not counted as separate families, and `info`, a library diagnostic, is not counted.

| Group | Families | Samples |
| --- | --- | --- |
| Diagrams | Flowchart, sequence, entity relationship, mind map, state | [Basic diagrams](samples/mermaid-diagrams.md), [mind maps and states](samples/mermaid-mindmaps-states.md) |
| Charts | Pie, XY, quadrant, radar, Sankey, treemap, Venn, Ishikawa | [Chart samples](samples/mermaid-catalogue-charts.md) |
| Processes | Timeline, Gantt, user journey, Kanban, swimlanes, AgentFlow, event modeling, Cynefin, Wardley | [Process samples](samples/mermaid-catalogue-processes.md) |
| Structures | Class, block, architecture, C4, use case, requirement, Git graph, packet, tree view, railroad | [Structure samples](samples/mermaid-catalogue-structures.md) |

The samples show the exact keywords, including `-beta` where Mermaid requires it.
C4 includes context, container, component, dynamic, and deployment diagrams. Railroad
includes its native notation, EBNF, ABNF, and PEG. Mermaid detects the diagram type, and
Whiteboard keeps no list of allowed types of its own. Third-party plugins are not bundled.

Rendering uses the bundled Mermaid engine through one hidden WebView2 controller, created
on the first new or changed diagram. Generating diagrams requires the Microsoft Edge
WebView2 Runtime, which Windows 11 includes; the installer does not install it. No diagram
source is sent to a server. Generated SVG becomes a frozen WPF drawing, shared by unchanged
diagram sources and replayed during drawing, pan, and zoom. No browser control is placed
on the canvas. See [mermaid.md](mermaid.md) for implementation details.

Diagrams use their natural size at 100%, shrinking proportionally only when they exceed
the available width. Smaller diagrams are centered, and height fits the rendered content.
Canvas zoom and corner resizing still scale the whole container; reflow recalculates
the width limit. After rendering, the container's height updates without an extra undo
step or stretching existing ink. Wait for the diagrams to appear before annotating, since
the content below a pending diagram moves when its height is known. Syntax errors,
unsupported diagram types, or an unavailable runtime show an explanation and source.

The board saves the original Markdown source and successful SVG diagram snapshots.
Reopening uses those snapshots without starting WebView2. They retain the saved diagram
layout, including when the runtime is unavailable. Editing a diagram regenerates only
the sources that have changed, and unchanged diagrams remain visible if regeneration fails.
Missing or invalid snapshots are regenerated from the source when the runtime is available.

Save, session recovery copies, export previews, PowerPoint, and PDF wait for pending
diagrams and use their final container heights. Failed diagrams retain an explanation
and their source in the output. A save captures the board at the time of the request,
so edits made during the wait remain unsaved. Releases before 1.7.5 ignore the optional
snapshot metadata and can drop it when saving.

A Markdown container accepts up to 16 distinct diagrams, 12,000 characters per diagram,
and 200 flowchart edges. Embedded configuration, interactive links, remote images,
external fonts, and icon-font packs are not enabled. Built-in architecture icons work
locally. HTML labels generated internally by Mermaid are converted to passive SVG text,
preserving line wrapping and basic font styles, so no HTML is stored or executed when
reopening a board. Experimental families retain Mermaid's beta status. Tests cover
representative syntax and styling for each family, not every combination.

## Validation

Core smoke tests cover detection-order migration, source/archive fidelity, linked ink,
Expand Down
Loading
Loading