@matfsw/docusaurus-plantuml-plugin 1.1.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +103 -1
  2. package/README.md +211 -32
  3. package/assets/stdlib/LICENSES.md +21 -0
  4. package/assets/stdlib/archimate.min.js +22 -0
  5. package/assets/stdlib/azure.min.js +305 -0
  6. package/assets/stdlib/c4.min.js +47 -0
  7. package/assets/stdlib/cloudinsight.min.js +93 -0
  8. package/assets/stdlib/eip.min.js +14 -0
  9. package/assets/stdlib/k8s.min.js +52 -0
  10. package/assets/stdlib/kubernetes.min.js +17 -0
  11. package/assets/stdlib/manifest.json +112 -0
  12. package/assets/stdlib/office.min.js +557 -0
  13. package/dist/constants.d.ts +2 -0
  14. package/dist/constants.js +2 -0
  15. package/dist/index.cjs +384 -8
  16. package/dist/index.d.cts +91 -3
  17. package/dist/index.d.ts +12 -2
  18. package/dist/index.js +20 -1
  19. package/dist/options.d.ts +57 -1
  20. package/dist/options.js +84 -0
  21. package/dist/runtime/assetLoader.d.ts +13 -1
  22. package/dist/runtime/assetLoader.js +36 -13
  23. package/dist/runtime/cache.d.ts +6 -1
  24. package/dist/runtime/cache.js +2 -2
  25. package/dist/runtime/errors.d.ts +3 -1
  26. package/dist/runtime/errors.js +27 -1
  27. package/dist/runtime/renderer.d.ts +3 -0
  28. package/dist/runtime/renderer.js +21 -7
  29. package/dist/runtime/stdlibLoader.d.ts +31 -0
  30. package/dist/runtime/stdlibLoader.js +99 -0
  31. package/dist/stdlib.d.ts +35 -0
  32. package/dist/stdlib.js +163 -0
  33. package/dist/stdlibBundle.d.ts +60 -0
  34. package/dist/stdlibBundle.js +218 -0
  35. package/dist/stdlibShared.d.ts +51 -0
  36. package/dist/stdlibShared.js +54 -0
  37. package/dist/theme/MDXComponents/Code/index.js +1 -1
  38. package/dist/theme/PlantUmlDiagram/index.d.ts +6 -1
  39. package/dist/theme/PlantUmlDiagram/index.js +53 -5
  40. package/dist/theme/PlantUmlDiagram/styles.module.css +117 -0
  41. package/dist/theme/usePlantUmlConfig.d.ts +8 -0
  42. package/dist/theme/usePlantUmlConfig.js +14 -8
  43. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,106 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.3.0]
11
+
12
+ ### Added
13
+
14
+ - **The PlantUML standard library.** `!include <C4/C4_Container>` now renders, with no
15
+ configuration and nothing to install. Eight namespaces ship with the plugin — `c4`,
16
+ `archimate`, `eip`, `k8s`, `kubernetes`, `azure`, `office` and `cloudinsight` — and a page
17
+ downloads only the ones its diagrams actually include. A C4 page costs 29 KB gzipped; a page
18
+ with no standard library include costs nothing.
19
+
20
+ Four details are worth knowing:
21
+ - **Bundles are served from your own `baseUrl`**, like every other asset. Left to itself the
22
+ engine resolves a namespace against the *current page* — `/docs/architecture/c4.min.js` —
23
+ which cannot exist, and pre-populating its global does not stop it. The plugin loads the
24
+ bundle from the assets directory and then tells the engine the work is done. See
25
+ [ADR 0005](docs/adr/0005-stdlib-bundles.md).
26
+ - **Includes the library makes of itself are resolved too**, from an index built when the
27
+ bundles are generated. `k8s/Common` needs `<c4/…>`, and the engine would only discover that
28
+ mid-render, with no chance to fetch it.
29
+ - **`!include <C4/C4_Container.puml>` works**, spelled with the extension. Upstream's own
30
+ bundles cannot resolve that spelling, even though C4-PlantUML's documentation uses it.
31
+ - **A missing namespace is explained, not dumped on the reader.** The panel names the
32
+ namespace and the option that adds it, instead of PlantUML's grey "Fatal parsing error".
33
+
34
+ - `stdlib` plugin option: `stdlib: false` switches the feature off entirely; `stdlib.include`
35
+ plus `stdlib.source` add namespaces from a `plantuml-stdlib` checkout — including the icon
36
+ libraries that are far too large to vendor, such as `aws`, `ibm` and `tupadr3` — and
37
+ `stdlib.namespaces` narrows what a build emits.
38
+ - `stdlib` error kind, for an include the site cannot resolve.
39
+ - `npm run stdlib:update`, which regenerates the vendored bundles from a pinned
40
+ plantuml-stdlib commit. It is maintainer-only and never part of `npm run build`, so site
41
+ builds stay offline and hermetic.
42
+ - `assets/stdlib/LICENSES.md`, recording the upstream project, version and licence of every
43
+ vendored namespace. Namespaces whose upstream declares no licence are deliberately not
44
+ vendored; `stdlib.include` remains available for anyone who wants them.
45
+
46
+ ### Fixed
47
+
48
+ - **PlantUML's preprocessor failures are now reported as errors** rather than passed through as
49
+ successfully rendered pictures. Calling a macro the included library does not define
50
+ (`Function not found RelIndex`), naming a file that is not in a namespace
51
+ (`cannot include <C4/C4_Nope>`) and an include that could not be resolved at all
52
+ (`Fatal parsing error`) all produce an error card with no `Syntax Error?` marker on it, so
53
+ the existing detection missed all three. They are the likeliest ways a standard library
54
+ diagram goes wrong, which is how this surfaced. The panel shows the failure alone rather
55
+ than the thousands of macro-expanded lines it is buried in.
56
+ - **Library files that are themselves whole `@startuml … @enduml` documents** are unwrapped when
57
+ the bundle is generated, the way PlantUML's file-based `!include` does. The standard library
58
+ lookup passes the markers through verbatim, and a nested `@startuml` fails the diagram — 81 of
59
+ `cloudinsight`'s 83 sprite files are written that way, so the namespace was unusable without
60
+ this. Files with more than one block are left alone.
61
+
62
+ ### Changed
63
+
64
+ - A script asset that fails to load is now replaced rather than reused when a later diagram
65
+ retries, so one flaky response no longer disables the engine — or a standard library
66
+ namespace — for the rest of the page.
67
+ - The render cache key includes the standard library revision, so refreshing it cannot serve a
68
+ picture rendered against the old one.
69
+ - The published package grows from 77 KB to ~776 KB packed (245 KB to ~3.2 MB unpacked); the
70
+ difference is the vendored bundles. `verify-package.mjs` budgets them separately from the
71
+ plugin's own code, which keeps its own 400 KB ceiling.
72
+
73
+ ## [1.2.0]
74
+
75
+ ### Added
76
+
77
+ - **A source view for every rendered diagram.** A `</>` control in the toolbar, beside the zoom
78
+ buttons, **flips the frame**: the source takes the diagram's place, in the same box. A
79
+ **Copy** button joins the same toolbar while the source is shown, so every control on a
80
+ diagram lives in one place. Enabled by default; turn it off with
81
+ `showSource: false`, or per fence with `showSource=false` in the metastring.
82
+
83
+ Four details are deliberate:
84
+ - **It shares the diagram's frame rather than sitting below it.** Below the diagram it had two
85
+ failure modes: a diagram taller than the window pushed it off-screen, and while maximized it
86
+ was painted behind the full-screen overlay. Sharing the frame removes both by construction.
87
+ - **The diagram is hidden, not unmounted**, so the frame keeps its height — nothing on the page
88
+ moves when you flip — and the reader's zoom and pan survive the round trip.
89
+ - The copy result is announced through a `role="status"` region rather than by renaming the
90
+ button, because a control whose accessible name changes is announced as a new control.
91
+ - A failed copy says so. `navigator.clipboard` is undefined outside a secure context, which a
92
+ docs site on plain HTTP genuinely is; the source is on screen either way, so the reader can
93
+ select the text.
94
+
95
+ - `showSource` plugin option and the matching `showSource` / `showSource=false` fence flag.
96
+ - `data-plantuml-source-open="true"` on the `<figure>` while the source is shown, part of the
97
+ documented `data-*` contract.
98
+
99
+ ### Changed
100
+
101
+ - The zoom controls are hidden while the source is shown — they would act on a picture nobody
102
+ can see. **Maximize stays**, because it sizes the frame the source is read in and removing it
103
+ while maximized would leave Escape as the only way back out.
104
+
105
+ - With `zoom: false` the source control gets its own row after the diagram, since there is no
106
+ zoom toolbar to join. `figure > div[role="img"]` remains the first child, so the shape the
107
+ pre-zoom markup has always had is unchanged. Setting both `zoom: false` and
108
+ `showSource: false` restores the bare markup exactly.
109
+
10
110
  ## [1.1.2]
11
111
 
12
112
  ### Fixed
@@ -247,7 +347,9 @@ Initial release.
247
347
  opt-out.
248
348
  - Plugin option validation that rejects unknown keys and out-of-range values at build time.
249
349
 
250
- [Unreleased]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.1.2...HEAD
350
+ [Unreleased]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.3.0...HEAD
351
+ [1.3.0]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.2.0...v1.3.0
352
+ [1.2.0]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.1.2...v1.2.0
251
353
  [1.1.2]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.1.1...v1.1.2
252
354
  [1.1.1]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.1.0...v1.1.1
253
355
  [1.1.0]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.0.3...v1.1.0
package/README.md CHANGED
@@ -231,21 +231,23 @@ props untouched. Existing code-block behaviour (highlighting, line numbers, titl
231
231
 
232
232
  ## Options
233
233
 
234
- | Option | Type | Default | Description |
235
- | ------------------- | --------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------- |
236
- | `languages` | `string[]` | `['plantuml', 'puml']` | Fence languages treated as PlantUML. Matched case-insensitively; must contain at least one non-empty, non-duplicate entry. |
237
- | `theme` | `'auto' \| 'light' \| 'dark'` | `'auto'` | Diagram colour scheme. `auto` follows the Docusaurus colour mode; `light`/`dark` pin it. |
238
- | `lazy` | `boolean` | `true` | Render a diagram only once it scrolls near the viewport (300 px root margin). |
239
- | `cache` | `'none' \| 'memory' \| 'session'` | `'memory'` | Where rendered SVG is cached. |
240
- | `sanitizeSvg` | `boolean` | `true` | Run rendered SVG through DOMPurify before inserting it. See [Security model](#svg-sanitization-and-security-model). |
241
- | `showSourceOnError` | `boolean` | `true` | Include the diagram source in a `<details>` block on the error panel. |
242
- | `renderTimeoutMs` | `number` | `20000` | Abort a single render (and the runtime load) after this many milliseconds. Integer, `100`–`600000`. |
243
- | `cacheMaxEntries` | `number` | `50` | Upper bound on cached SVG entries. Positive integer. |
244
- | `zoom` | `boolean` | `true` | Let readers zoom and pan diagrams. Adds a control toolbar and a focusable viewport. Override per fence with `zoom=false`. |
245
- | `graphviz` | `object` | see below | Graphviz/DOT support. See [Graphviz options](#graphviz-options). |
246
- | `id` | `string` | `'default'` | Docusaurus plugin instance id; only relevant if you register the plugin more than once. |
247
-
248
- Every option above except `graphviz` applies to **both** engines: `lazy`, `cache`,
234
+ | Option | Type | Default | Description |
235
+ | ------------------- | --------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
236
+ | `languages` | `string[]` | `['plantuml', 'puml']` | Fence languages treated as PlantUML. Matched case-insensitively; must contain at least one non-empty, non-duplicate entry. |
237
+ | `theme` | `'auto' \| 'light' \| 'dark'` | `'auto'` | Diagram colour scheme. `auto` follows the Docusaurus colour mode; `light`/`dark` pin it. |
238
+ | `lazy` | `boolean` | `true` | Render a diagram only once it scrolls near the viewport (300 px root margin). |
239
+ | `cache` | `'none' \| 'memory' \| 'session'` | `'memory'` | Where rendered SVG is cached. |
240
+ | `sanitizeSvg` | `boolean` | `true` | Run rendered SVG through DOMPurify before inserting it. See [Security model](#svg-sanitization-and-security-model). |
241
+ | `showSourceOnError` | `boolean` | `true` | Include the diagram source in a `<details>` block on the error panel. |
242
+ | `renderTimeoutMs` | `number` | `20000` | Abort a single render (and the runtime load) after this many milliseconds. Integer, `100`–`600000`. |
243
+ | `cacheMaxEntries` | `number` | `50` | Upper bound on cached SVG entries. Positive integer. |
244
+ | `zoom` | `boolean` | `true` | Let readers zoom and pan diagrams. Adds a control toolbar and a focusable viewport. Override per fence with `zoom=false`. |
245
+ | `showSource` | `boolean` | `true` | Offer a toolbar control that reveals the diagram source and copies it to the clipboard. Override per fence with `showSource=false`. |
246
+ | `graphviz` | `object` | see below | Graphviz/DOT support. See [Graphviz options](#graphviz-options). |
247
+ | `stdlib` | `object \| false` | see below | PlantUML standard library (`!include <C4/…>`). See [Standard library options](#standard-library-options). |
248
+ | `id` | `string` | `'default'` | Docusaurus plugin instance id; only relevant if you register the plugin more than once. |
249
+
250
+ Every option above except `graphviz` and `stdlib` applies to **both** engines: `lazy`, `cache`,
249
251
  `sanitizeSvg`, `showSourceOnError`, `renderTimeoutMs`, `cacheMaxEntries` and `zoom` behave
250
252
  identically for a `dot` fence and a `plantuml` fence. `theme` is the exception — see
251
253
  [Light and dark mode](#light-and-dark-mode).
@@ -257,16 +259,17 @@ would otherwise silently disable the option you meant to set:
257
259
  ```text
258
260
  [docusaurus-plugin-plantuml-client] Unknown option 'sanitiseSvg'. Supported options:
259
261
  'languages', 'theme', 'lazy', 'cache', 'sanitizeSvg', 'showSourceOnError',
260
- 'renderTimeoutMs', 'cacheMaxEntries', 'zoom', 'graphviz'.
262
+ 'renderTimeoutMs', 'cacheMaxEntries', 'zoom', 'showSource', 'graphviz', 'stdlib'.
261
263
  ```
262
264
 
263
265
  The same is true one level deeper, so `graphviz: {enigne: 'neato'}` fails the build rather than
264
266
  quietly doing nothing.
265
267
 
266
268
  `PlantUmlPluginOptions`, `ResolvedPlantUmlOptions`, `GraphvizOptions`,
267
- `ResolvedGraphvizOptions`, `GraphvizEngine`, `GRAPHVIZ_ENGINES`, `CacheMode`, `DiagramTheme`,
268
- `DEFAULT_OPTIONS`, `DEFAULT_GRAPHVIZ_OPTIONS`, `resolveOptions` and `PlantUmlOptionsError` are
269
- exported from the package root. The renderer, queue and cache internals are deliberately not
269
+ `ResolvedGraphvizOptions`, `GraphvizEngine`, `GRAPHVIZ_ENGINES`, `StdlibOptions`,
270
+ `ResolvedStdlibOptions`, `CacheMode`, `DiagramTheme`, `DEFAULT_OPTIONS`,
271
+ `DEFAULT_GRAPHVIZ_OPTIONS`, `resolveOptions` and `PlantUmlOptionsError` are exported from the
272
+ package root. The renderer, queue and cache internals are deliberately not
270
273
  exported.
271
274
 
272
275
  ## Graphviz (DOT) diagrams
@@ -377,6 +380,115 @@ large, and expect the page to stall while they render.
377
380
  The check happens **before** the engine is downloaded, so refusing an oversized diagram is
378
381
  free.
379
382
 
383
+ ## PlantUML standard library
384
+
385
+ `!include <C4/C4_Container>` works out of the box. Nothing to install, nothing to configure:
386
+
387
+ ````markdown
388
+ ```plantuml title="C4 container diagram"
389
+ @startuml
390
+ !include <C4/C4_Container>
391
+
392
+ Person(user, "Reader", "Reads the documentation")
393
+ Container(browser, "Browser", "JavaScript", "Renders diagrams locally")
394
+ Rel(user, browser, "Opens a page")
395
+ @enduml
396
+ ```
397
+ ````
398
+
399
+ Both spellings of the include resolve — `<C4/C4_Container>` and `<C4/C4_Container.puml>` —
400
+ and so do the includes the library makes of _itself_: `C4_Container` pulls in `C4_Context`,
401
+ `k8s/Common` pulls in `<c4/…>`, and none of that has to be written in the fence.
402
+
403
+ ### What is included, and what it costs
404
+
405
+ Namespaces are fetched **per page, on demand**. A page with a C4 diagram downloads 29 KB
406
+ gzipped; a page with no standard library include downloads nothing at all. The bundles are
407
+ served from your own `baseUrl` like every other asset — no CDN, no plantuml.com.
408
+
409
+ | Namespace | Library | Transfer | Licence |
410
+ | -------------- | -------------------- | -------- | ---------- |
411
+ | `c4` | C4-PlantUML | 29 KB | MIT |
412
+ | `archimate` | Archimate-PlantUML | 34 KB | MIT |
413
+ | `eip` | EIP-PlantUML | 21 KB | MIT |
414
+ | `k8s` | kubernetes-PlantUML | 23 KB | MIT |
415
+ | `kubernetes` | kubernetes sprites | 221 KB | Apache-2.0 |
416
+ | `azure` | Azure-PlantUML | 160 KB | MIT |
417
+ | `office` | plantuml-office | 160 KB | MIT |
418
+ | `cloudinsight` | cicon sprites | 24 KB | MIT |
419
+ | `domainstory` | DomainStory-PlantUML | 5 KB | MIT |
420
+
421
+ Transfer figures are gzipped, per namespace, once per browsing session.
422
+ [`assets/stdlib/LICENSES.md`](assets/stdlib/LICENSES.md) records the exact upstream version and
423
+ licence of each. The bundles are generated from a pinned
424
+ [plantuml-stdlib](https://github.com/plantuml/plantuml-stdlib) commit by
425
+ `npm run stdlib:update`.
426
+
427
+ ### Namespaces that are not included
428
+
429
+ The standard library in full is **265 MB** of source (28 MB gzipped), most of it icon sets:
430
+ `aws` alone is 114 MB, and `ibm`, `tupadr3`, `material7.4.47` and `awslib14`/`awslib20` account
431
+ for most of the rest. Shipping that in an npm package is not reasonable, and several other
432
+ namespaces — `classy`, `classy-c4`, `cloudogu`, `edgy`, `elastic`, `gcp`, `osa2` — declare no
433
+ licence at all upstream, which makes redistributing them your call rather than this package's.
434
+ `domainstory` is left out for a third reason: it is small and MIT licensed, but every element it
435
+ draws resolves an icon out of `material2.1.19`, so it cannot render without 6.8 MB of icons
436
+ beside it — use it with `include: ['domainstory', 'material2.1.19']`.
437
+
438
+ Any of them can be added from your own checkout:
439
+
440
+ ```bash
441
+ git clone --depth 1 https://github.com/plantuml/plantuml-stdlib vendor/plantuml-stdlib
442
+ ```
443
+
444
+ ```ts
445
+ {
446
+ stdlib: {
447
+ include: ['aws', 'tupadr3'],
448
+ source: 'vendor/plantuml-stdlib/stdlib',
449
+ },
450
+ }
451
+ ```
452
+
453
+ Bundles for those namespaces are generated during the build and cached under `.docusaurus`, so
454
+ only the first build pays for it. Naming a namespace that _is_ vendored replaces it with the
455
+ copy from your checkout, which is also how you pin a newer C4 than the one shipped here.
456
+
457
+ ### Standard library options
458
+
459
+ | Option | Type | Default | Description |
460
+ | ------------ | -------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- |
461
+ | `enabled` | `boolean` | `true` | Resolve `!include <namespace/…>` at all. `stdlib: false` is shorthand for `{enabled: false}`. |
462
+ | `include` | `string[]` | `[]` | Extra namespaces to make available. Each must be found in `source`, or the build fails naming it. |
463
+ | `source` | `string \| string[]` | `[]` | `stdlib` directories of plantuml-stdlib checkouts, relative to the site directory or absolute. Required whenever `include` is set. |
464
+ | `namespaces` | `string[]` | all | Narrow the vendored namespaces emitted into the build. Dependencies of the named ones are kept regardless. |
465
+
466
+ Namespaces are matched case-insensitively, because the engine lower-cases `<C4/…>` before it
467
+ looks anything up.
468
+
469
+ ### When a namespace is missing
470
+
471
+ A diagram that includes a namespace the site does not provide gets the plugin's error panel,
472
+ naming what is missing and how to add it — not PlantUML's grey "Fatal parsing error" picture:
473
+
474
+ ```text
475
+ This diagram includes <aws/…>, but the 'aws' standard library namespace is not available on
476
+ this site. Add it to the plugin's `stdlib.include` option and point `stdlib.source` at a
477
+ plantuml-stdlib checkout that contains it.
478
+ ```
479
+
480
+ ### Turning it off
481
+
482
+ ```ts
483
+ {
484
+ stdlib: false;
485
+ }
486
+ ```
487
+
488
+ Nothing is emitted into the build, and a diagram with a standard library include says so
489
+ instead of failing inside the engine. See
490
+ [ADR 0005](docs/adr/0005-stdlib-bundles.md) for why the bundles are loaded the way they are.
491
+
380
492
  ## Light and dark mode
381
493
 
382
494
  The two engines handle this differently, because PlantUML has a real dark theme and Graphviz
@@ -499,6 +611,58 @@ would mean most readers never discover it. The costs are real and worth knowing:
499
611
 
500
612
  Setting `zoom: false` restores the previous markup exactly.
501
613
 
614
+ ## Source view
615
+
616
+ Every rendered diagram offers its own source. The `</>` control in the toolbar **flips the
617
+ frame**: the source takes the diagram's place, in the same box. A **Copy** button appears beside
618
+ it in the same toolbar while the source is shown. Press `</>` again to flip back.
619
+
620
+ ````markdown
621
+ ```plantuml title="Readers can copy this"
622
+ @startuml
623
+ Alice -> Bob : Hello
624
+ @enduml
625
+ ```
626
+ ````
627
+
628
+ Details worth knowing:
629
+
630
+ - **The source shares the diagram's frame.** It was previously rendered _below_ the diagram,
631
+ which had two failure modes: a diagram taller than the window pushed it off-screen, so the
632
+ control looked broken; and while maximized it was painted behind the full-screen overlay, so
633
+ it was invisible however far you scrolled. In the frame it appears exactly where the picture
634
+ was.
635
+ - **The diagram is hidden, not unmounted.** The frame keeps its height, so nothing on the page
636
+ moves when you flip, and your zoom and pan survive the round trip.
637
+ - **The zoom controls step aside while the source is shown** — they would act on a picture
638
+ nobody can see. Maximize stays, because it sizes the frame the source is read in, and taking
639
+ it away while maximized would leave Escape as the only way out.
640
+ - The source stays outside the `role="img"` subtree, which is opaque to assistive technology —
641
+ content inside it would be unreachable for screen-reader users.
642
+ - **The copy result is announced through a `role="status"` region**, not by renaming the button.
643
+ A control whose accessible name changes is announced as a new control every time.
644
+ - **A failed copy says so.** `navigator.clipboard` is undefined outside a secure context, which
645
+ a docs site served over plain HTTP genuinely is. The panel is open either way, so the reader
646
+ can select the text; the control never silently does nothing.
647
+ - The panel shows the **authored source**, never the rendered SVG.
648
+
649
+ Turn it off for a whole site with `showSource: false`, or for one fence:
650
+
651
+ ````markdown
652
+ ```plantuml showSource=false
653
+ @startuml
654
+ Alice -> Bob : Hello
655
+ @enduml
656
+ ```
657
+ ````
658
+
659
+ With `zoom: false` there is no zoom toolbar, so the control gets its own row after the diagram.
660
+ Setting both `zoom: false` and `showSource: false` restores the bare markup the plugin produced
661
+ before either feature existed.
662
+
663
+ This is separate from `showSourceOnError`, which offers the source in the error panel when a
664
+ diagram _fails_ to render.
665
+
502
666
  ## Lazy loading
503
667
 
504
668
  With `lazy: true` (the default), a diagram is not rendered until it scrolls within 300 px of
@@ -675,16 +839,17 @@ wrapper carries `data-plantuml-status="error"`.
675
839
 
676
840
  Failures are classified internally as one of:
677
841
 
678
- | Kind | Cause |
679
- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
680
- | `load` | `viz-global.js` or `plantuml.js` could not be fetched, timed out, or was not the expected module (usually a proxy or service worker returning the wrong file). |
681
- | `engine` | The engine threw, or its output could not be used at all. |
682
- | `diagram` | The source is not valid PlantUML. |
683
- | `syntax` | The source is not valid DOT. Carries Graphviz's own diagnostic, including the line number. |
684
- | `too-large` | A DOT source exceeded `graphviz.maxSourceBytes`. |
685
- | `timeout` | One render exceeded `renderTimeoutMs`. |
686
- | `config` | The plugin's global data is missing, or a fence named a layout engine this Graphviz build does not have. |
687
- | `aborted` | The component unmounted or re-rendered; not surfaced to the reader. |
842
+ | Kind | Cause |
843
+ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
844
+ | `load` | `viz-global.js` or `plantuml.js` could not be fetched, timed out, or was not the expected module (usually a proxy or service worker returning the wrong file). |
845
+ | `engine` | The engine threw, or its output could not be used at all. |
846
+ | `diagram` | The source is not valid PlantUML. |
847
+ | `syntax` | The source is not valid DOT. Carries Graphviz's own diagnostic, including the line number. |
848
+ | `too-large` | A DOT source exceeded `graphviz.maxSourceBytes`. |
849
+ | `stdlib` | A `!include <namespace/…>` names a standard library namespace this site does not provide, or the standard library is switched off. See [Standard library](#plantuml-standard-library). |
850
+ | `timeout` | One render exceeded `renderTimeoutMs`. |
851
+ | `config` | The plugin's global data is missing, or a fence named a layout engine this Graphviz build does not have. |
852
+ | `aborted` | The component unmounted or re-rendered; not surfaced to the reader. |
688
853
 
689
854
  The two engines report invalid source very differently:
690
855
 
@@ -692,6 +857,10 @@ The two engines report invalid source very differently:
692
857
  an "error picture" and reports success, so the rendered SVG is inspected for error markers
693
858
  before it is trusted. See [ADR 0002](docs/adr/0002-render-to-string.md) for the exact
694
859
  detection rules.
860
+ - **Preprocessor failures carry no `Syntax Error?` marker at all** — `Function not found X`
861
+ after a macro that the included library version does not define, or `cannot include
862
+ <C4/C4_Nope>` for a file that is not in the namespace. Both are detected by their own
863
+ signature, and the panel shows the failure rather than the expanded source it sits in.
695
864
  - **Invalid DOT is reported as structured data**, so the panel shows Graphviz's own message
696
865
  verbatim — `syntax error in line 3 near '}'` — with no heuristics involved.
697
866
 
@@ -745,6 +914,10 @@ The runtimes are large:
745
914
  | `viz-global.js` | ≈ 1.4 MB | DOT fences, and PlantUML's own layout |
746
915
  | **Total** | **≈ 8.2 MB** | |
747
916
 
917
+ Standard library namespaces are separate again, and much smaller: one bundle per namespace, 5
918
+ to 220 KB gzipped, fetched only by the pages whose diagrams include them. A C4 page adds 29 KB
919
+ to the figures above; a page with no standard library include adds nothing.
920
+
748
921
  Crucially, **none of that is in your site's initial bundle**. The files are emitted as static
749
922
  assets, not imported into the webpack graph (the dynamic import is marked `webpackIgnore`), so:
750
923
 
@@ -760,9 +933,12 @@ assets, not imported into the webpack graph (the dynamic import is marked `webpa
760
933
  **Adding Graphviz support to a site that already renders PlantUML costs nothing**, because
761
934
  `viz-global.js` was already being emitted and loaded.
762
935
 
763
- The published npm package itself is small (the compiled plugin and theme components only);
764
- the 8 MB comes from the `@plantuml/core` dependency and lands in your build output, not in
765
- your JavaScript bundle. Budget for roughly 8 MB of extra static assets per deployed site.
936
+ The published npm package is the compiled plugin, its theme components, and ~3 MB of vendored
937
+ standard library bundles; the 8 MB engine comes from the `@plantuml/core` dependency. Both land
938
+ in your build output rather than in your JavaScript bundle, so budget for roughly 11 MB of
939
+ extra static assets per deployed site — of which a given reader downloads the 8 MB engine once
940
+ and only the standard library namespaces their pages actually use. `stdlib.namespaces` narrows
941
+ what is emitted if the build output size matters more to you than which diagrams keep working.
766
942
 
767
943
  Serve these assets with compression enabled — they are ordinary JavaScript and compress well.
768
944
 
@@ -1136,6 +1312,9 @@ Then rebuild. If it persists, remove `node_modules/.cache` and `.docusaurus/` by
1136
1312
  why zoom transforms a wrapper rather than the SVG.
1137
1313
  - [`docs/adr/0004-graphviz-engine-reuse.md`](docs/adr/0004-graphviz-engine-reuse.md) — why DOT
1138
1314
  is rendered with the Graphviz already inside `@plantuml/core`, and what that couples us to.
1315
+ - [`docs/adr/0005-stdlib-bundles.md`](docs/adr/0005-stdlib-bundles.md) — how `!include <C4/…>`
1316
+ is resolved, why the engine's own loader has to be short-circuited, and how the vendored set
1317
+ was chosen.
1139
1318
  - [`CONTRIBUTING.md`](CONTRIBUTING.md)
1140
1319
  - [`SECURITY.md`](SECURITY.md)
1141
1320
 
@@ -0,0 +1,21 @@
1
+ # Vendored PlantUML standard library namespaces
2
+
3
+ These bundles are generated from
4
+ [plantuml/plantuml-stdlib](https://github.com/plantuml/plantuml-stdlib) at commit
5
+ `bdbb819f76c75e7a23af582b2a63ea7dc43eed7c` by `npm run stdlib:update`. Each namespace keeps the licence of its
6
+ own upstream project, listed below. plantuml-stdlib leaves the `license:` field of most
7
+ namespace READMEs empty, so where that is the case the licence was read from the source
8
+ repository and recorded in `scripts/update-stdlib.mjs`. Namespaces whose upstream declares
9
+ no licence at all are not vendored. The MIT licence of this plugin covers the generator,
10
+ not the library content.
11
+
12
+ | Namespace | Library | Version | Licence | Upstream |
13
+ | --- | --- | --- | --- | --- |
14
+ | `c4` | C4 (C4-PlantUML) | 2.13.0 | MIT | <https://github.com/plantuml-stdlib/C4-PlantUML> |
15
+ | `archimate` | Archimate | 3.2.2 | MIT | <https://github.com/plantuml-stdlib/Archimate-PlantUML> |
16
+ | `azure` | Azure | 2.2.0 | MIT | <https://github.com/plantuml-stdlib/Azure-PlantUML> |
17
+ | `cloudinsight` | Cloudinsight | 1.0.0 | MIT | <https://github.com/plantuml-stdlib/cicon-plantuml-sprites> |
18
+ | `eip` | Eip | 1.0.0 | MIT | <https://github.com/plantuml-stdlib/EIP-PlantUML> |
19
+ | `k8s` | K8s | 1.0.0 | MIT | <https://github.com/dcasati/kubernetes-PlantUML> |
20
+ | `kubernetes` | Kubernetes | 5.3.45 | Apache-2.0 | <https://github.com/plantuml-stdlib/plantuml-kubernetes-sprites> |
21
+ | `office` | Office | 1.0.0 | MIT | <https://github.com/Roemer/plantuml-office> |