@zombie-mermaid/svg-renderer 4.2.3 → 5.0.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 (45) hide show
  1. package/README.md +15 -1
  2. package/dist/index.cjs +52 -52
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +23 -4
  5. package/dist/index.d.ts +23 -4
  6. package/dist/index.js +890 -850
  7. package/dist/index.js.map +1 -1
  8. package/package.json +14 -6
  9. package/src/c4/arial-widths.ts +0 -59
  10. package/src/c4/layout.ts +0 -680
  11. package/src/c4/metrics.ts +0 -261
  12. package/src/c4/renderer.ts +0 -366
  13. package/src/class/layout.ts +0 -525
  14. package/src/class/renderer.ts +0 -669
  15. package/src/edge-curves.ts +0 -205
  16. package/src/elk-instance.ts +0 -292
  17. package/src/er/layout.ts +0 -216
  18. package/src/er/renderer.ts +0 -516
  19. package/src/generated/mono-font-subset.ts +0 -32
  20. package/src/index.ts +0 -310
  21. package/src/layout-engine/back-edges.ts +0 -73
  22. package/src/layout-engine/compound-flat.ts +0 -916
  23. package/src/layout-engine/constants.ts +0 -19
  24. package/src/layout-engine/edge-bundling.ts +0 -458
  25. package/src/layout-engine/elk-adapter-utils.ts +0 -81
  26. package/src/layout-engine/elk-graph-builder.ts +0 -245
  27. package/src/layout-engine/from-elk.ts +0 -767
  28. package/src/layout-engine/inner-edges.ts +0 -329
  29. package/src/layout-engine/jog-straightening.ts +0 -52
  30. package/src/layout-engine/layer-alignment.ts +0 -174
  31. package/src/layout-engine/layout-hints.ts +0 -27
  32. package/src/layout-engine/to-elk.ts +0 -855
  33. package/src/layout-engine.ts +0 -115
  34. package/src/pie/layout.ts +0 -234
  35. package/src/pie/renderer.ts +0 -161
  36. package/src/registry.ts +0 -441
  37. package/src/renderer.ts +0 -1510
  38. package/src/resolve-colors.ts +0 -339
  39. package/src/sequence/layout.ts +0 -766
  40. package/src/sequence/renderer.ts +0 -687
  41. package/src/shape-clipping.ts +0 -197
  42. package/src/styles.ts +0 -145
  43. package/src/title-gaps.ts +0 -161
  44. package/src/xychart/layout.ts +0 -727
  45. package/src/xychart/renderer.ts +0 -676
package/src/registry.ts DELETED
@@ -1,441 +0,0 @@
1
- // ============================================================================
2
- // zombie-mermaid — SVG diagram-type registry
3
- //
4
- // A per-type registration table `renderMermaidSVG` (./index.ts) looks up
5
- // instead of hand-maintaining its own `switch (diagramType)` over the same
6
- // `DiagramType`. Moved here from the umbrella's `src/diagram-registry.ts`
7
- // under issue #1111, for parity with `@zombie-mermaid/ascii-renderer`'s own
8
- // `registry.ts` — see docs/decisions/diagram-type-registry-partial.md for
9
- // why the SVG and ASCII halves stayed two separate tables rather than one
10
- // shared `DiagramModule` with both a `renderSvg` and a `renderAscii` method
11
- // (short version: one table made this module import out of
12
- // `packages/ascii-renderer/`, while that package's `index.ts` imported this
13
- // one back, a cycle that blocked the monorepo split and dragged `elkjs`
14
- // into `dist/ascii.js`).
15
- //
16
- // Every diagram type is registered here, including 'flowchart' — see the
17
- // decision doc for why it was the last holdout (its ASCII path had no
18
- // per-type wrapper function to slot in until #745 extracted
19
- // `renderFlowchartAscii`, and its SVG path carries `%%{init: ...}%%`
20
- // directive handling no other type has — see `flowchartModule.layoutForSvg`
21
- // below for how that's folded in without growing `SvgRenderContext`). The
22
- // front door (`renderMermaidSVG` in ./index.ts) has no fallback switch left;
23
- // every `DiagramType` is a hit here.
24
- //
25
- // `packages/core/src/diagram-type.ts` (the `DiagramType` union + `detectDiagramType`)
26
- // stays exactly as-is and is what the front door uses to key into this
27
- // table — this module doesn't touch detection.
28
- //
29
- // `parseMermaid` (flowchart/state parsing) reaches out to the umbrella's
30
- // `../../../src/parser.ts` rather than a `@zombie-mermaid/*` package
31
- // specifier — flowchart/state parsing was deliberately never extracted into
32
- // `@zombie-mermaid/mermaid-parser` (see that package's scoping doc), the same
33
- // pre-existing boundary call `packages/ascii-renderer/src/flowchart.ts`
34
- // already reaches across for the ASCII side. `vite.config.ts` bundles that
35
- // file straight into this package's own dist, exactly as it already does
36
- // for `ascii-renderer` — see that file's header comment.
37
- // ============================================================================
38
-
39
- import type {
40
- DiagramType,
41
- RenderOptions,
42
- DiagramColors,
43
- SvgEmitOptions,
44
- MermaidGraph,
45
- PositionedGraph,
46
- CurveStyle,
47
- Statement,
48
- } from '@zombie-mermaid/core'
49
- import type { FontSizes } from './styles.ts'
50
- import { withDirectionOverride } from '@zombie-mermaid/core'
51
-
52
- import {
53
- parseXYChart,
54
- parseErDiagram,
55
- parseSequenceDiagram,
56
- parseClassDiagram,
57
- parseArchitecture,
58
- architectureToGraph,
59
- parseC4Diagram,
60
- parsePieChart,
61
- } from '@zombie-mermaid/mermaid-parser'
62
- import type {
63
- XYChart,
64
- PositionedXYChart,
65
- ErDiagram,
66
- PositionedErDiagram,
67
- SequenceDiagram,
68
- PositionedSequenceDiagram,
69
- ClassDiagram,
70
- PositionedClassDiagram,
71
- ArchitectureDiagram,
72
- C4Diagram,
73
- PositionedC4Diagram,
74
- PieChart,
75
- PositionedPieChart,
76
- } from '@zombie-mermaid/mermaid-parser'
77
- import { layoutXYChart } from './xychart/layout.ts'
78
- import { renderXYChartSvg } from './xychart/renderer.ts'
79
- import { layoutErDiagramSync } from './er/layout.ts'
80
- import { renderErSvg } from './er/renderer.ts'
81
- import { layoutSequenceDiagram } from './sequence/layout.ts'
82
- import { renderSequenceSvg } from './sequence/renderer.ts'
83
- import { layoutClassDiagramSync } from './class/layout.ts'
84
- import { renderClassSvg } from './class/renderer.ts'
85
- import { layoutC4DiagramSync } from './c4/layout.ts'
86
- import { renderC4Svg } from './c4/renderer.ts'
87
- import { layoutPieChart } from './pie/layout.ts'
88
- import { renderPieSvg } from './pie/renderer.ts'
89
- import { layoutFlowchartSync, layoutGraphSync } from './layout-engine.ts'
90
- import { renderSvg as renderFlowchartSvg } from './renderer.ts'
91
- import { parseMermaid } from '@zombie-mermaid/mermaid-parser'
92
-
93
- /**
94
- * Parameters shared by every per-type SVG renderer today, factored out of
95
- * the positional-argument lists that otherwise differ type to type (the
96
- * inconsistency issue #533 flags — confirmed by reading all five renderer
97
- * signatures: `embedSource`/`title`/`decorative`/`emit` shift position
98
- * across `renderSvg`, `renderSequenceSvg`, `renderClassSvg`, `renderErSvg`,
99
- * `renderXYChartSvg`, and `renderErSvg` drops `linksEnabled` entirely).
100
- *
101
- * Fields only one or two types need (`curve`, `animationEnabled`,
102
- * `linksEnabled`, `interactive`) are deliberately left OUT of this shared
103
- * shape rather than grown in for every exception — each type's own
104
- * `renderSvg` adapter below derives those straight from `options`, exactly
105
- * as each existing `renderMermaidSVGRaw` switch case already did.
106
- */
107
- export interface SvgRenderContext {
108
- colors: DiagramColors
109
- font: string
110
- transparent: boolean
111
- fontSizes: FontSizes
112
- embedSource?: string
113
- title?: string
114
- decorative?: boolean
115
- emit: SvgEmitOptions
116
- }
117
-
118
- /**
119
- * One diagram type's full registration.
120
- *
121
- * `layoutForSvg` is deliberately SVG-only — it is NOT shared with the ASCII
122
- * side, unlike the issue's original `{ detect, parse, layout, renderSvg,
123
- * renderAscii }` sketch. Reading every ASCII per-type module confirmed why a
124
- * single shared `layout` step would be fiction, not simplification, for this
125
- * codebase: SVG layout produces pixel coordinates (`PositionedXYChart`,
126
- * `PositionedErDiagram`, …), while every ASCII renderer does its own,
127
- * unrelated grid/canvas layout internally — see e.g.
128
- * `packages/ascii-renderer/src/xychart.ts`'s file header: "Uses the parsed
129
- * XYChart type directly (not PositionedXYChart) since pixel coordinates
130
- * don't map to character grids." `parse` genuinely is shared in the sense
131
- * that both front doors call the same `parseXYChart`/`parseErDiagram`, but
132
- * each ASCII renderer reruns that parse itself from raw text — which is why
133
- * the ASCII entries live in `packages/ascii-renderer/src/registry.ts` as
134
- * plain `(text, …) => string` functions instead of a `renderAscii` method on
135
- * this interface.
136
- *
137
- * `parse` takes both `lines` (the pre-split statement list from
138
- * `splitStatements(decoded)`, computed once by the front door — what every
139
- * already-registered type's parser wants) and `text` (the raw, un-split
140
- * source `flowchartModule` below needs instead): `parseMermaid`'s
141
- * `%%{init: ...}%%` directive extraction reads raw, un-commented lines that
142
- * `splitStatements` has already discarded by the time `lines` exists, and
143
- * its multi-line-statement continuation merging needs each statement's
144
- * *originating physical line* grouping, which `splitStatements`'s flattened
145
- * array has already lost. `xychartModule`/`erModule`/`sequenceModule`/
146
- * `classModule` all ignore the second parameter — JS/TS functions may take
147
- * fewer parameters than their declared type allows, so `parse: parseXYChart`
148
- * (etc.) is unchanged from before this parameter was added.
149
- */
150
- export interface DiagramModule<TDiagram = unknown, TPositioned = unknown> {
151
- readonly type: DiagramType
152
- parse(lines: Statement[], text: string): TDiagram
153
- layoutForSvg(diagram: TDiagram, options: RenderOptions): TPositioned
154
- renderSvg(
155
- positioned: TPositioned,
156
- ctx: SvgRenderContext,
157
- options: RenderOptions,
158
- ): string
159
- }
160
-
161
- const xychartModule: DiagramModule<XYChart, PositionedXYChart> = {
162
- type: 'xychart',
163
- parse: parseXYChart,
164
- layoutForSvg: layoutXYChart,
165
- renderSvg(positioned, ctx, options) {
166
- // Mirrors resolveXYChartInteractive() in the umbrella's src/index.ts
167
- // exactly — `interactivity` wins when set, otherwise the deprecated
168
- // `interactive` boolean keeps controlling this as before.
169
- const interactive =
170
- options.interactivity !== undefined
171
- ? options.interactivity === 'full'
172
- : (options.interactive ?? false)
173
- return renderXYChartSvg(
174
- positioned,
175
- ctx.colors,
176
- ctx.font,
177
- ctx.transparent,
178
- interactive,
179
- ctx.embedSource,
180
- ctx.title,
181
- ctx.decorative,
182
- ctx.emit,
183
- )
184
- },
185
- }
186
-
187
- const sequenceModule: DiagramModule<
188
- SequenceDiagram,
189
- PositionedSequenceDiagram
190
- > = {
191
- type: 'sequence',
192
- parse: parseSequenceDiagram,
193
- layoutForSvg: layoutSequenceDiagram,
194
- renderSvg(positioned, ctx) {
195
- return renderSequenceSvg(
196
- positioned,
197
- ctx.colors,
198
- ctx.font,
199
- ctx.transparent,
200
- ctx.fontSizes,
201
- ctx.embedSource,
202
- ctx.title,
203
- ctx.decorative,
204
- ctx.emit,
205
- )
206
- },
207
- }
208
-
209
- /**
210
- * Mirrors `resolveLinksEnabled()` in the umbrella's src/index.ts exactly
211
- * (`interactivity` defaults unset to `'static'`; only `'none'` turns links
212
- * off) — duplicated here rather than imported since that helper is private
213
- * to src/index.ts, which now imports this module (importing it back would
214
- * cycle).
215
- */
216
- function resolveLinksEnabled(options: RenderOptions): boolean {
217
- const interactivity = options.interactivity ?? 'static'
218
- return interactivity !== 'none'
219
- }
220
-
221
- /**
222
- * Mirrors `resolveAnimationEnabled()` in the umbrella's src/index.ts exactly
223
- * (`interactivity` defaults unset to `'static'`; only `'full'` turns
224
- * animation on) — duplicated here for the same import-direction reason
225
- * `resolveLinksEnabled` above is.
226
- */
227
- function resolveAnimationEnabled(options: RenderOptions): boolean {
228
- const interactivity = options.interactivity ?? 'static'
229
- return interactivity === 'full'
230
- }
231
-
232
- const classModule: DiagramModule<ClassDiagram, PositionedClassDiagram> = {
233
- type: 'class',
234
- parse: parseClassDiagram,
235
- layoutForSvg: layoutClassDiagramSync,
236
- renderSvg(positioned, ctx, options) {
237
- return renderClassSvg(
238
- positioned,
239
- ctx.colors,
240
- ctx.font,
241
- ctx.transparent,
242
- ctx.fontSizes,
243
- ctx.embedSource,
244
- ctx.title,
245
- ctx.decorative,
246
- resolveLinksEnabled(options),
247
- ctx.emit,
248
- )
249
- },
250
- }
251
-
252
- const erModule: DiagramModule<ErDiagram, PositionedErDiagram> = {
253
- type: 'er',
254
- parse: parseErDiagram,
255
- // `options.direction` replaces the diagram's own top-level `direction`
256
- // line, if any, before layout — same order as the umbrella's original
257
- // 'er' case: parse, then withDirectionOverride, then layout.
258
- layoutForSvg(diagram, options) {
259
- return layoutErDiagramSync(
260
- withDirectionOverride(diagram, options.direction),
261
- options,
262
- )
263
- },
264
- renderSvg(positioned, ctx) {
265
- return renderErSvg(
266
- positioned,
267
- ctx.colors,
268
- ctx.font,
269
- ctx.transparent,
270
- ctx.fontSizes,
271
- ctx.embedSource,
272
- ctx.title,
273
- ctx.decorative,
274
- ctx.emit,
275
- )
276
- },
277
- }
278
-
279
- /**
280
- * `renderSvg`'s (the low-level flowchart/state SVG emitter, imported above
281
- * as `renderFlowchartSvg`) `curve` parameter is the one piece of
282
- * `SvgRenderContext`-adjacent state no other registered type needs: a
283
- * `%%{init: {"flowchart": {"curve": ...}}}%%` directive on the diagram
284
- * itself can supply a default, and `options.curve` always wins when set —
285
- * see `applyInitConfig()` in `packages/core/src/init-directive.ts`, which
286
- * the umbrella's pre-registry flowchart path used to call directly.
287
- *
288
- * That resolution needs the parsed diagram (for `initConfig`) AND the
289
- * caller's `options` together, and the *result* is only needed later, by
290
- * `renderSvg` — so rather than teach `SvgRenderContext` a diagram-specific
291
- * `curve` field (every other field there is genuinely shared across types),
292
- * `layoutForSvg` below resolves it once and carries it forward on
293
- * `PositionedFlowchart`, right next to the `PositionedGraph` it was
294
- * resolved alongside. `animationEnabled`/`linksEnabled` need no such
295
- * carry-through: both derive from `options` alone via the
296
- * `resolveAnimationEnabled`/`resolveLinksEnabled` helpers above, exactly
297
- * like `class`'s `linksEnabled` already does, so `flowchartModule.renderSvg`
298
- * just calls them directly.
299
- */
300
- export interface PositionedFlowchart {
301
- graph: PositionedGraph
302
- curve: CurveStyle
303
- }
304
-
305
- const flowchartModule: DiagramModule<MermaidGraph, PositionedFlowchart> = {
306
- type: 'flowchart',
307
- // Ignores `lines` — see the `parse` doc comment on `DiagramModule` above
308
- // for why flowchart/state needs the raw `text` instead.
309
- parse: (_lines, text) => parseMermaid(text),
310
- layoutForSvg(diagram, options) {
311
- // Same order as the umbrella's original fallback: direction override,
312
- // then layout. `options.curve` wins over the diagram's own
313
- // `%%{init: ...}%%` directive, which wins over the 'linear' default —
314
- // see the doc comment on `PositionedFlowchart` above.
315
- const graph = withDirectionOverride(diagram, options.direction)
316
- return {
317
- graph: layoutFlowchartSync(graph, options),
318
- curve: options.curve ?? diagram.initConfig?.curve ?? 'linear',
319
- }
320
- },
321
- renderSvg(positioned, ctx, options) {
322
- return renderFlowchartSvg(
323
- positioned.graph,
324
- ctx.colors,
325
- ctx.font,
326
- ctx.transparent,
327
- ctx.fontSizes,
328
- positioned.curve,
329
- ctx.embedSource,
330
- resolveAnimationEnabled(options),
331
- resolveLinksEnabled(options),
332
- ctx.title,
333
- ctx.decorative,
334
- ctx.emit,
335
- )
336
- },
337
- }
338
-
339
- const c4Module: DiagramModule<C4Diagram, PositionedC4Diagram> = {
340
- type: 'c4',
341
- parse: parseC4Diagram,
342
- // Mermaid's C4 renderer has no direction: shapes are placed in rows in
343
- // declaration order, so `options.direction` does not apply to the SVG.
344
- layoutForSvg(diagram, options) {
345
- return layoutC4DiagramSync(diagram, options)
346
- },
347
- renderSvg(positioned, ctx) {
348
- return renderC4Svg(
349
- positioned,
350
- ctx.colors,
351
- ctx.font,
352
- ctx.transparent,
353
- ctx.fontSizes,
354
- ctx.embedSource,
355
- ctx.title,
356
- ctx.decorative,
357
- ctx.emit,
358
- )
359
- },
360
- }
361
-
362
- /**
363
- * Architecture diagrams are lowered to the flowchart model
364
- * (`architectureToGraph` in `@zombie-mermaid/mermaid-parser`) and ride the
365
- * flowchart layout + renderer, so this module is `flowchartModule` with a
366
- * different `parse`. The lowered graph carries no `%%{init}%%` config, so
367
- * `curve` is `options.curve` or 'linear'.
368
- */
369
- const architectureModule: DiagramModule<
370
- ArchitectureDiagram,
371
- PositionedFlowchart
372
- > = {
373
- type: 'architecture',
374
- parse: parseArchitecture,
375
- layoutForSvg(diagram, options) {
376
- const graph = withDirectionOverride(
377
- architectureToGraph(diagram),
378
- options.direction,
379
- )
380
- return {
381
- graph: layoutGraphSync(graph, options),
382
- curve: options.curve ?? 'linear',
383
- }
384
- },
385
- renderSvg: flowchartModule.renderSvg,
386
- }
387
-
388
- /**
389
- * Pie charts parse from the raw `text` rather than `lines` (see
390
- * `parsePieChart`'s doc: `splitStatements` would split `title A; B` and
391
- * treat `'` as a quote), then lay out and render to Mermaid's geometry —
392
- * see ./pie/layout.ts. No direction or interactivity applies.
393
- */
394
- const pieModule: DiagramModule<PieChart, PositionedPieChart> = {
395
- type: 'pie',
396
- parse: (_lines, text) => parsePieChart(text),
397
- layoutForSvg: layoutPieChart,
398
- renderSvg(positioned, ctx) {
399
- return renderPieSvg(
400
- positioned,
401
- ctx.colors,
402
- ctx.font,
403
- ctx.transparent,
404
- ctx.embedSource,
405
- ctx.title,
406
- ctx.decorative,
407
- ctx.emit,
408
- )
409
- },
410
- }
411
-
412
- /**
413
- * The registry proper — every `DiagramType` is looked up here by the SVG
414
- * front door (`renderMermaidSVG` in ./index.ts), which has no fallback
415
- * switch left. The ASCII front door's equivalent table is `asciiRegistry`
416
- * in `packages/ascii-renderer/src/registry.ts`.
417
- *
418
- * Typed with `any` type parameters at the map level: each entry's own
419
- * `TDiagram`/`TPositioned` are only known inside that entry's own closure
420
- * (see `xychartModule`/`erModule`/`flowchartModule` above, which are fully
421
- * typed); the map just needs one consistent shape to hold heterogeneous
422
- * entries in.
423
- */
424
- type AnyDiagramModule = DiagramModule<
425
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- see comment above; each entry is fully typed at its own definition site.
426
- any,
427
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- see comment above; each entry is fully typed at its own definition site.
428
- any
429
- >
430
-
431
- export const diagramRegistry: Record<DiagramType, AnyDiagramModule> = {
432
- xychart: xychartModule,
433
- er: erModule,
434
- sequence: sequenceModule,
435
- class: classModule,
436
- flowchart: flowchartModule,
437
- architecture: architectureModule,
438
-
439
- c4: c4Module,
440
- pie: pieModule,
441
- }