Color mode

WaveDrom

Renders ```wavedrom code blocks as WaveDrom timing diagrams.

日本語

Overview

wavedrom() replaces ```wavedrom (and ```wavejson) code blocks with a <figure> that carries the normalized WaveJSON in a data-wavedrom-spec attribute. The diagram itself is drawn in the browser by initWaveDrom, which dynamically imports wavedrom. The build only emits markup. Execution order is order: -10.

Configuration

ts
import { defineConfig } from "@riebeckite/core";
import { wavedrom } from "@riebeckite/plugin-wavedrom";
 
export default defineConfig({
  // ...
  plugins: [
    wavedrom({
      skin: "default",
      caption: true,
    }),
  ],
});

Writing a diagram

The block body is a strict JSON WaveJSON object. Keys must be double-quoted, and trailing commas or comments are not allowed.

markdown
```wavedrom
{
  "signal": [
    { "name": "clk", "wave": "p......" },
    { "name": "bus", "wave": "x.34.5x", "data": "head body tail" },
    { "name": "wire", "wave": "0.1..0." }
  ]
}
```

Top-level keys other than signal, assign, and reg — such as WaveDrom's head, config, and foot — are passed through unchanged.

WaveJSON source
text
{
  "head": { "text": "handshake" },
  "signal": [
    { "name": "req", "wave": "01..0" },
    { "name": "ack", "wave": "0.1.0" }
  ]
}

Captions

A caption is taken from the code block's title.

markdown
```wavedrom title="Read cycle"
{ "signal": [{ "name": "clk", "wave": "p..." }] }
```

You can also use a top-level "caption" key in the JSON. It is removed before the diagram is rendered, so it never reaches WaveDrom.

markdown
```wavedrom
{
  "caption": "Read cycle",
  "signal": [{ "name": "clk", "wave": "p..." }]
}
```

Output

html
<figure class="rb-wavedrom" data-wavedrom="pending" data-wavedrom-spec="{&quot;signal&quot;:[...]}" data-wavedrom-skin="default">
  <figcaption id="rb-wavedrom-xxxx-caption" class="rb-wavedrom__caption">Read cycle</figcaption>
  <div class="rb-wavedrom__canvas" data-wavedrom-canvas="true" role="img" aria-labelledby="rb-wavedrom-xxxx-caption"></div>
  <details class="rb-wavedrom__fallback">
    <summary>WaveJSON source</summary>
    <pre><code>{ ... }</code></pre>
  </details>
</figure>
  • .rb-wavedrom — the figure wrapper; inherits --rb-color-* for theming
  • .rb-wavedrom__canvas — where WaveDrom draws the SVG; marked with data-wavedrom-canvas="true"
  • .rb-wavedrom__caption — the <figcaption> when a caption is present
  • .rb-wavedrom__fallback — a <details> holding the WaveJSON source

The data-wavedrom attribute reports render state: pending initially, rendered on success, and error on failure. On failure the fallback <details> is opened.

Options

Name Type Default Description
skin "default" | "narrow" | "lowkey" "default" WaveDrom skin used by the browser renderer
caption boolean true Render the extracted caption as a <figcaption>
fallback boolean true Render the WaveJSON source in a <details> block
className string "rb-wavedrom" Base class applied to the figure

Diagnostics

If the body is not valid JSON, is not an object, or has no signal / assign / reg, the original code block is left in place and a diagnostic is emitted with source: "@riebeckite/plugin-wavedrom" and ruleId: "invalid-config".

Client rendering

wavedrom is not bundled at build time. The site's client bundle must call initWaveDrom, which wavedrom() wires up via createClientEntry. The initializer finds figure[data-wavedrom="pending"], JSON.parses each data-wavedrom-spec, dynamically imports wavedrom, and draws the SVG into <div class="rb-wavedrom__canvas"> with WaveDrom.RenderWaveForm. When data-wavedrom-skin is present, the matching skin is loaded. A broken payload or a rendering error only marks that figure as data-wavedrom="error" and opens its fallback.

Limitations

  • Rendering is client-only. Without JavaScript the SVG is never produced and only the WaveJSON source remains
  • The E2E build checks the emitted markup only; actual rendering requires a browser
  • The body must be strict JSON. The JSON5 form accepted by the WaveDrom editor (unquoted keys, single quotes, comments) is not supported
  • The WaveJSON is embedded directly in an HTML attribute, so keep diagrams reasonably small
  • Only the wavedrom and wavejson info strings are recognized; other languages are unaffected

See also

History

1 changesCollapseExpand
1 + <!-- Generated from packages/plugins/wavedrom/README.md. Do not edit this page directly; edit the package README and run `pnpm docs:sync`. -->
2 +
3 + # WaveDrom
4 +
5 + Renders ` ```wavedrom ` code blocks as [WaveDrom](https://wavedrom.com/) timing diagrams.
6 +
7 + [日本語](./wavedrom.md)
8 +
9 + ## Overview
10 +
11 + `wavedrom()` replaces ` ```wavedrom ` (and ` ```wavejson `) code blocks with a `<figure>` that carries the normalized WaveJSON in a `data-wavedrom-spec` attribute. The diagram itself is drawn in the browser by `initWaveDrom`, which dynamically imports `wavedrom`. The build only emits markup. Execution order is `order: -10`.
12 +
13 + ## Configuration
14 +
15 + ```ts
16 + import { defineConfig } from "@riebeckite/core";
17 + import { wavedrom } from "@riebeckite/plugin-wavedrom";
18 +
19 + export default defineConfig({
20 + // ...
21 + plugins: [
22 + wavedrom({
23 + skin: "default",
24 + caption: true,
25 + }),
26 + ],
27 + });
28 + ```
29 +
30 + ## Writing a diagram
31 +
32 + The block body is a **strict JSON** WaveJSON object. Keys must be double-quoted, and trailing commas or comments are not allowed.
33 +
34 + ````markdown
35 + ```wavedrom
36 + {
37 + "signal": [
38 + { "name": "clk", "wave": "p......" },
39 + { "name": "bus", "wave": "x.34.5x", "data": "head body tail" },
40 + { "name": "wire", "wave": "0.1..0." }
41 + ]
42 + }
43 + ```
44 + ````
45 +
46 + Top-level keys other than `signal`, `assign`, and `reg` — such as WaveDrom's `head`, `config`, and `foot` — are passed through unchanged.
47 +
48 + ```wavedrom
49 + {
50 + "head": { "text": "handshake" },
51 + "signal": [
52 + { "name": "req", "wave": "01..0" },
53 + { "name": "ack", "wave": "0.1.0" }
54 + ]
55 + }
56 + ```
57 +
58 + ### Captions
59 +
60 + A caption is taken from the code block's `title`.
61 +
62 + ````markdown
63 + ```wavedrom title="Read cycle"
64 + { "signal": [{ "name": "clk", "wave": "p..." }] }
65 + ```
66 + ````
67 +
68 + You can also use a top-level `"caption"` key in the JSON. It is removed before the diagram is rendered, so it never reaches WaveDrom.
69 +
70 + ````markdown
71 + ```wavedrom
72 + {
73 + "caption": "Read cycle",
74 + "signal": [{ "name": "clk", "wave": "p..." }]
75 + }
76 + ```
77 + ````
78 +
79 + ## Output
80 +
81 + ```html
82 + <figure class="rb-wavedrom" data-wavedrom="pending" data-wavedrom-spec="{&quot;signal&quot;:[...]}" data-wavedrom-skin="default">
83 + <figcaption id="rb-wavedrom-xxxx-caption" class="rb-wavedrom__caption">Read cycle</figcaption>
84 + <div class="rb-wavedrom__canvas" data-wavedrom-canvas="true" role="img" aria-labelledby="rb-wavedrom-xxxx-caption"></div>
85 + <details class="rb-wavedrom__fallback">
86 + <summary>WaveJSON source</summary>
87 + <pre><code>{ ... }</code></pre>
88 + </details>
89 + </figure>
90 + ```
91 +
92 + - `.rb-wavedrom` — the figure wrapper; inherits `--rb-color-*` for theming
93 + - `.rb-wavedrom__canvas` — where WaveDrom draws the SVG; marked with `data-wavedrom-canvas="true"`
94 + - `.rb-wavedrom__caption` — the `<figcaption>` when a caption is present
95 + - `.rb-wavedrom__fallback` — a `<details>` holding the WaveJSON source
96 +
97 + The `data-wavedrom` attribute reports render state: `pending` initially, `rendered` on success, and `error` on failure. On failure the fallback `<details>` is opened.
98 +
99 + ## Options
100 +
101 + | Name | Type | Default | Description |
102 + | --- | --- | --- | --- |
103 + | `skin` | `"default" \| "narrow" \| "lowkey"` | `"default"` | WaveDrom skin used by the browser renderer |
104 + | `caption` | `boolean` | `true` | Render the extracted caption as a `<figcaption>` |
105 + | `fallback` | `boolean` | `true` | Render the WaveJSON source in a `<details>` block |
106 + | `className` | `string` | `"rb-wavedrom"` | Base class applied to the figure |
107 +
108 + ## Diagnostics
109 +
110 + If the body is not valid JSON, is not an object, or has no `signal` / `assign` / `reg`, the original code block is left in place and a diagnostic is emitted with `source: "@riebeckite/plugin-wavedrom"` and `ruleId: "invalid-config"`.
111 +
112 + ## Client rendering
113 +
114 + `wavedrom` is not bundled at build time. The site's client bundle must call `initWaveDrom`, which `wavedrom()` wires up via `createClientEntry`. The initializer finds `figure[data-wavedrom="pending"]`, `JSON.parse`s each `data-wavedrom-spec`, dynamically imports `wavedrom`, and draws the SVG into `<div class="rb-wavedrom__canvas">` with `WaveDrom.RenderWaveForm`. When `data-wavedrom-skin` is present, the matching skin is loaded. A broken payload or a rendering error only marks that figure as `data-wavedrom="error"` and opens its fallback.
115 +
116 + ## Limitations
117 +
118 + - Rendering is client-only. Without JavaScript the SVG is never produced and only the WaveJSON source remains
119 + - The E2E build checks the emitted markup only; actual rendering requires a browser
120 + - The body must be strict JSON. The JSON5 form accepted by the WaveDrom editor (unquoted keys, single quotes, comments) is not supported
121 + - The WaveJSON is embedded directly in an HTML attribute, so keep diagrams reasonably small
122 + - Only the `wavedrom` and `wavejson` info strings are recognized; other languages are unaffected
123 +
124 + ## See also
125 +
126 + - [Plugin system](../reference/plugin-api.en.md)
127 +