@weasel-js/diagram-formats 0.0.0-stage → 1.12.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.
- package/LICENSE +21 -0
- package/README.md +237 -2
- package/dist/index.d.ts +246 -0
- package/dist/index.js +3136 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 orochi235
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,238 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @weasel-js/diagram-formats
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Turns `@weasel-js/diagram` scenes into files and files into scenes. Every
|
|
4
|
+
format reads and writes one interchange document, built on the diagram
|
|
5
|
+
package's `DiagramData`. One page at a time exports as an SVG document or a
|
|
6
|
+
PNG image, and every page together as one PDF, each showing the page as the
|
|
7
|
+
canvas draws it.
|
|
8
|
+
|
|
9
|
+
Part of [weasel](https://github.com/orochi235/weasel), a domain-agnostic 2D
|
|
10
|
+
scene-graph canvas kit for React. See the
|
|
11
|
+
[API reference](https://orochi235.github.io/weasel/#pkg/diagram-formats).
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install @weasel-js/diagram-formats
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## The interchange document
|
|
18
|
+
|
|
19
|
+
A `DiagramDocument` is a diagram's pages and its theme. Each page has an id,
|
|
20
|
+
an optional name, a sheet size, and a `DiagramData` whose places, boxes,
|
|
21
|
+
waypoints, and label points run from the page's top-left corner. Ids share one
|
|
22
|
+
namespace across the document. Edges whose ends are on different pages sit in
|
|
23
|
+
`crossPageEdges`, with no waypoints, since they draw as two stubs and their
|
|
24
|
+
off-page tags.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { documentFromScene, documentSpecs } from '@weasel-js/diagram-formats';
|
|
28
|
+
|
|
29
|
+
const doc = documentFromScene(scene);
|
|
30
|
+
const { specs, doc: values } = documentSpecs(doc, { layer: 'shapes', measure });
|
|
31
|
+
// values holds `core:pages` and `diagram:theme`; replace the scene's nodes with specs.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`documentFromScene(scene, { theme })` puts each shape, container, pool, and
|
|
35
|
+
group on the page its outermost container overlaps most, or the first page
|
|
36
|
+
when it overlaps none; a scene with no pages gets one page around everything.
|
|
37
|
+
It keeps the colors the scene's theme would not give: those the author set by
|
|
38
|
+
hand (the trait's `ownStyle`) and any that differ from the theme, as `colors`.
|
|
39
|
+
A route or a port that layout chose, and an avoiding connector's computed
|
|
40
|
+
route, are read as `routed` and `routedPorts`, not as waypoints, so they stay
|
|
41
|
+
layout's. `theme` is what colors are compared against when the scene names
|
|
42
|
+
none.
|
|
43
|
+
|
|
44
|
+
`documentSpecs(doc, { layer, theme, measure })` is the way back. Pages are
|
|
45
|
+
placed with core's `layoutPages`, as `core:pages` places them. A page where a
|
|
46
|
+
node has no `at`, or a pool has no box, is laid out first with `layered`,
|
|
47
|
+
running the way its `direction` says, with whatever it places pinned; the
|
|
48
|
+
result is kept as places and routes, a page that placed nothing is moved to sit
|
|
49
|
+
40 inside its corner, and the page grows to hold it. Then one `diagramScene`
|
|
50
|
+
call with no layout draws every page and the edges between them, so no layout
|
|
51
|
+
runs again after an import.
|
|
52
|
+
|
|
53
|
+
## Formats
|
|
54
|
+
|
|
55
|
+
A `DiagramFormat` has an `id`, a `name`, its `extensions`, and `detect(text)`,
|
|
56
|
+
which judges by content alone. `read(text)` returns the document and the
|
|
57
|
+
warnings, one sentence each, for what the file had that a diagram cannot hold;
|
|
58
|
+
`write(doc, { page })` returns the text and the warnings for what the format
|
|
59
|
+
cannot carry. A format with `onePage` writes the page `page` names, else the
|
|
60
|
+
first (`writtenPage`).
|
|
61
|
+
|
|
62
|
+
`DIAGRAM_FORMATS` lists them. `detectFormat(text, fileName)` takes, of the
|
|
63
|
+
formats whose `detect` passes, the first claiming the file's extension, else the
|
|
64
|
+
first; an extension alone never picks one. `readDocument(text, fileName)` reads
|
|
65
|
+
with it and rejects on a file nothing reads.
|
|
66
|
+
|
|
67
|
+
| Format | Extensions | Reads | Writes |
|
|
68
|
+
| --- | --- | --- | --- |
|
|
69
|
+
| `DIAGRAM_JSON`, the document as JSON | `.diagram.json` | yes | the whole document |
|
|
70
|
+
| `DRAW_XML`, draw-style XML | `.xml` | yes, plain or compressed | every page, uncompressed |
|
|
71
|
+
| `DIAGRAM_MERMAID`, a Mermaid flowchart | `.mmd`, `.mermaid` | yes | one page |
|
|
72
|
+
| `DIAGRAM_DOT`, a Graphviz DOT graph | `.dot`, `.gv` | yes | one page |
|
|
73
|
+
|
|
74
|
+
Not read, by decision (2026-10-20): packaged office-suite drawing formats,
|
|
75
|
+
which are zip archives of many XML parts built on master shapes a scene has no
|
|
76
|
+
equivalent for; and SVG, which carries drawn paths rather than shapes and
|
|
77
|
+
connectors, so a connector would arrive as a path that follows nothing.
|
|
78
|
+
|
|
79
|
+
### Draw-style XML
|
|
80
|
+
|
|
81
|
+
The format that keeps a chart laid out. A file is an `<mxfile>` holding a
|
|
82
|
+
`<diagram name=…>` per page, each a graph model of cells; a bare
|
|
83
|
+
`<mxGraphModel>` reads as one page. A cell has a `key=value;` style string and
|
|
84
|
+
a geometry measured from the corner of the cell holding it. A compressed page
|
|
85
|
+
is base64 of raw deflate of the URI-encoded model, so `read` answers a promise.
|
|
86
|
+
The file is known by its root element, not its `.xml` extension.
|
|
87
|
+
|
|
88
|
+
| Diagram | Draw-style XML |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| Outline | `rhombus` diamond, `ellipse`, `hexagon`, `parallelogram`, `trapezoid`; `rounded=1` with `arcSize` 50 or more is a stadium; any other shape reads as a rect, with a warning |
|
|
91
|
+
| Colors and font | `fillColor` (`none` is transparent), `strokeColor`, `fontColor`, `strokeWidth`, `dashed`; `fontSize`, `fontFamily`, and bold in `fontStyle` as label rows' style |
|
|
92
|
+
| Text | `value`; with `html=1`, tags stripped and `<br>` and blocks kept as line breaks. Written plain. |
|
|
93
|
+
| Router | `edgeStyle=orthogonalEdgeStyle` orthogonal, `curved=1` bezier, else straight; `avoid` writes as orthogonal along its route |
|
|
94
|
+
| Route | the edge geometry's points: `waypoints`, else `routed`, read back as `waypoints` |
|
|
95
|
+
| Ports | `exitX`/`exitY` and `entryX`/`entryY`, read as the nearest compass port |
|
|
96
|
+
| Edge label | the edge's `value`, or a label cell on it; its geometry `x` (-1 to 1) is where along, `y` how far off the line |
|
|
97
|
+
| Arrowheads | `startArrow`/`endArrow` and their `Fill` |
|
|
98
|
+
| Container, pool, lane | `container=1` or a `swimlane` is a container; a swimlane whose swimlanes span its body is a pool of lanes, stacked in rows with `horizontal=0` |
|
|
99
|
+
| Group | a `group` cell around its members |
|
|
100
|
+
| Page | one `<diagram>` each, `pageWidth` and `pageHeight` its size |
|
|
101
|
+
|
|
102
|
+
Reading leaves a color the style does not name unset, so the chart's theme
|
|
103
|
+
draws it. A page grows to hold what is on it, and what sits left of or above it
|
|
104
|
+
moves onto it. An id an earlier page used is prefixed with its page's id.
|
|
105
|
+
Layers merge into one, and edges with a loose end are left out, each with a
|
|
106
|
+
warning.
|
|
107
|
+
|
|
108
|
+
Writing spells out every color as the document's theme draws it, so the file
|
|
109
|
+
looks the same anywhere. A node is written the size it states, which is its
|
|
110
|
+
drawn size in a document read from a scene; a page with unplaced nodes is laid
|
|
111
|
+
out first, as an import would. Edges between pages are left out, with a
|
|
112
|
+
warning, since a page's cells cannot reach another's; so are marks, port rows,
|
|
113
|
+
and outline paths, which become rects.
|
|
114
|
+
|
|
115
|
+
### Mermaid and Graphviz DOT
|
|
116
|
+
|
|
117
|
+
Both hold a graph's topology and text, not its places (DOT holds them when
|
|
118
|
+
every node has a `pos`), so a file reads into one page whose nodes have no
|
|
119
|
+
`at`, and `documentSpecs` lays it out the way the page's `direction` says.
|
|
120
|
+
Both readers are hand-written and throw an error naming the line on text they
|
|
121
|
+
cannot read.
|
|
122
|
+
|
|
123
|
+
| Diagram | Mermaid flowchart | Graphviz DOT |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| rect | `A[text]` | `shape=box` |
|
|
126
|
+
| stadium | `A([text])`, and `A(text)` | `shape=box, style=rounded` |
|
|
127
|
+
| diamond | `A{text}` | `shape=diamond` |
|
|
128
|
+
| ellipse | `A((text))` | `shape=ellipse`, the default, and `circle` |
|
|
129
|
+
| hexagon | `A{{text}}` | `shape=hexagon` |
|
|
130
|
+
| parallelogram | `A[/text/]` | `shape=parallelogram` |
|
|
131
|
+
| trapezoid | `A[/text\]` | `shape=trapezium` |
|
|
132
|
+
| edge and label | `A -->\|text\| B`, `A -- text --> B` | `A -> B [label=…]` |
|
|
133
|
+
| no arrowhead, dashed, thick | `---`, `-.->`, `==>` | `dir`, `arrowhead`, `style=dashed`, `penwidth` |
|
|
134
|
+
| container | `subgraph` | `subgraph cluster_*` |
|
|
135
|
+
| page name | front matter `title` | the graph's `label`, else its name |
|
|
136
|
+
| page `direction` | `flowchart TD/LR/BT/RL` | `rankdir` |
|
|
137
|
+
| colors | `classDef`, `class`, `:::`, `style`, `linkStyle` | `fillcolor` with `style=filled`, `color`, `fontcolor` |
|
|
138
|
+
| ports | — | `node:compass`, `n`, `e`, `s`, and `w` only |
|
|
139
|
+
|
|
140
|
+
A Mermaid shape with no outline here reads as a rect, with a warning; a
|
|
141
|
+
Mermaid diagram of another kind is refused with an error naming the kind. DOT
|
|
142
|
+
reads its whole grammar: `strict`, `graph` and `digraph`, attribute
|
|
143
|
+
statements and their scoping, edge chains, and subgraphs as edge ends. Its
|
|
144
|
+
HTML labels read as their text, and the attributes it does not read are
|
|
145
|
+
listed in one warning. A cluster's container drops its `cluster_` prefix when
|
|
146
|
+
that id is free.
|
|
147
|
+
|
|
148
|
+
Writing, each writes the theme's colors once (Mermaid's `classDef default`,
|
|
149
|
+
DOT's `node` and `edge` defaults) and each item's own where they differ. DOT
|
|
150
|
+
writes every node's `pos`, `width`, and `height` when each has a place and a
|
|
151
|
+
size, so a DOT file read back keeps the layout. Pools, lanes, and groups are
|
|
152
|
+
written as nested clusters or subgraphs and read back as containers. Mermaid
|
|
153
|
+
ids that are keywords or not plain names are renamed, keeping their text.
|
|
154
|
+
Bends, connectors to other pages, drawn outlines, and ports a format lacks
|
|
155
|
+
are dropped with a warning.
|
|
156
|
+
|
|
157
|
+
## Exporting a page
|
|
158
|
+
|
|
159
|
+
A page is a rect in world space; a `PlacedPage` from core's `placedPagesOf` is
|
|
160
|
+
one. Pages sit apart in one world, and a connector between two pages draws as
|
|
161
|
+
two stubs and their off-page tags, so cutting the scene to the page rect leaves
|
|
162
|
+
nothing from another page.
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { placedPagesOf } from '@weasel-js/core';
|
|
166
|
+
import { exportPagePng, exportPageSvg, exportPagesPdf } from '@weasel-js/diagram-formats';
|
|
167
|
+
|
|
168
|
+
const pages = placedPagesOf(scene);
|
|
169
|
+
const svg = await exportPageSvg(scene, pages[0], { title: 'Page 1' });
|
|
170
|
+
const png = await exportPagePng(scene, pages[0], { scale: 2 });
|
|
171
|
+
const { blob, skipped } = await exportPagesPdf(scene, pages, { title: 'Chart' });
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
None writes to the scene, so an export takes no undo entry. Each takes
|
|
175
|
+
`background`, the color painted under the page: by default the page color of
|
|
176
|
+
the scene's diagram theme (`diagram:theme`), and `null` for none.
|
|
177
|
+
|
|
178
|
+
### SVG
|
|
179
|
+
|
|
180
|
+
`exportPageSvg` returns the document as a string. Its `viewBox` is the page
|
|
181
|
+
rect and its `width` and `height` the page's size. Only nodes whose box meets
|
|
182
|
+
the page are written, in paint order, on the scene's visible layers;
|
|
183
|
+
annotation layers are left out.
|
|
184
|
+
|
|
185
|
+
| In the scene | In the SVG |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| A shape's outline (`diagram.outline`) | A path of that outline in the shape's box, with its fill and stroke; a container's divider under its header as a second path. A container's members follow inside its group. |
|
|
188
|
+
| A connector, or any node that derives its path | One path along the route, with its stroke and its `marker-start` and `marker-end`. A path made of parts writes one path per part. |
|
|
189
|
+
| A drawn mark | Its unit-square path stretched over its box. |
|
|
190
|
+
| Rows, labels, text marks, and off-page tags | Text, laid out in the lines the canvas lays it into; a tag's background is a rect behind it. |
|
|
191
|
+
| Anything else | What `@weasel-js/svg`'s `svgLeafFromKit` writes for it. |
|
|
192
|
+
|
|
193
|
+
It waits for the paint kinds and font faces the document uses before
|
|
194
|
+
writing it. A load that fails goes to `onWarn`, and so does anything SVG cannot
|
|
195
|
+
say the way weasel draws it. `title` and `pretty` are passed on to
|
|
196
|
+
`serializeSvg`.
|
|
197
|
+
|
|
198
|
+
`pageSvgNodes(scene, page)` is the walk on its own: the `SvgNode`s, with no
|
|
199
|
+
background, for a caller assembling its own document.
|
|
200
|
+
|
|
201
|
+
### PNG
|
|
202
|
+
|
|
203
|
+
`exportPagePng` draws the page with core's `renderSceneToPixels`, the renderer
|
|
204
|
+
the canvas uses, so its pixels are the canvas's. The image is the page's size
|
|
205
|
+
times `scale`, and the result is a `Blob` of type `image/png`. It needs WebGL2
|
|
206
|
+
and `OffscreenCanvas`.
|
|
207
|
+
|
|
208
|
+
Paint kinds and fonts that load on demand are waited for, but the painters are
|
|
209
|
+
the caller's to register, as they are to draw the scene at all:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import { registerDiagramShape, registerMarkShape } from '@weasel-js/diagram';
|
|
213
|
+
|
|
214
|
+
registerDiagramShape();
|
|
215
|
+
registerMarkShape();
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### PDF
|
|
219
|
+
|
|
220
|
+
`exportPagesPdf` writes each of `pages` as a page of one PDF, in the order
|
|
221
|
+
given, at 0.75 points per unit (96 units to the inch). It answers the `Blob`,
|
|
222
|
+
of type `application/pdf`, and `skipped`: what the PDF could not carry, each a
|
|
223
|
+
`{ kind, detail }` from `@weasel-js/pdf`. Annotation layers are left out.
|
|
224
|
+
|
|
225
|
+
Shapes and strokes are written as vectors and text as selectable text in its
|
|
226
|
+
embedded face, which needs the face's outlines registered from a TrueType file
|
|
227
|
+
(`registerFontOutlines` in `@weasel-js/font`). A face that cannot be embedded
|
|
228
|
+
is drawn as glyph outlines, so its text is not selectable; a glyph with no
|
|
229
|
+
outline at all is left out and listed in `skipped`.
|
|
230
|
+
|
|
231
|
+
Effects, custom shaders, and fills in a registered paint kind are drawn through
|
|
232
|
+
the renderer and placed as images, so the painters are the caller's to
|
|
233
|
+
register, as for the PNG, and this needs WebGL2 and `OffscreenCanvas`.
|
|
234
|
+
|
|
235
|
+
## Scenes it reads
|
|
236
|
+
|
|
237
|
+
Poses are read as world-space `RectPose`s, which is what a diagram scene
|
|
238
|
+
holds. A scene that composes child poses into a parent's frame is not one.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { DiagramData, LayoutDirection, DataEdge, DiagramTheme, DiagramSpec, MeasureRowText } from '@weasel-js/diagram';
|
|
2
|
+
import { Scene, SerializedDoc, RectPose } from '@weasel-js/core';
|
|
3
|
+
import { SvgNode, SerializeOptions } from '@weasel-js/svg';
|
|
4
|
+
import { PdfSkip } from '@weasel-js/pdf';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The interchange document every format reads and writes: a diagram's pages,
|
|
8
|
+
* each holding a `DiagramData`, and the theme it is drawn in. Only
|
|
9
|
+
* `documentFromScene` and `documentSpecs` know scenes, so a codec is written
|
|
10
|
+
* once for a chart and for a data-backed host alike.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* One page: its sheet size, and what is on it in coordinates from the page's
|
|
15
|
+
* top-left corner. Ids share one namespace across the whole document.
|
|
16
|
+
*/
|
|
17
|
+
interface DocumentPage {
|
|
18
|
+
id: string;
|
|
19
|
+
name?: string;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
data: DiagramData;
|
|
23
|
+
/** The way layout runs when the page is laid out on import, which it is when a node has no `at`. */
|
|
24
|
+
direction?: LayoutDirection;
|
|
25
|
+
}
|
|
26
|
+
/** A diagram as every format reads and writes it. */
|
|
27
|
+
interface DiagramDocument {
|
|
28
|
+
pages: readonly DocumentPage[];
|
|
29
|
+
/**
|
|
30
|
+
* Edges the scene splits off-page, and edges whose ends export to different pages: their ends, ports, router,
|
|
31
|
+
* label, and colors. One the scene splits off-page carries no waypoints,
|
|
32
|
+
* since it draws as two stubs ending at off-page tags; one it keeps whole
|
|
33
|
+
* (an end in the gap between pages) keeps them, in world coordinates.
|
|
34
|
+
*/
|
|
35
|
+
crossPageEdges?: readonly DataEdge[];
|
|
36
|
+
/** A shipped theme's id, or a whole theme. Unset, the host's own. */
|
|
37
|
+
theme?: string | DiagramTheme;
|
|
38
|
+
}
|
|
39
|
+
/** What a format read, and what it could not carry into a diagram, one sentence each. */
|
|
40
|
+
interface ImportResult {
|
|
41
|
+
document: DiagramDocument;
|
|
42
|
+
warnings: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
/** What a format wrote, and what it could not carry out of the diagram, one sentence each. */
|
|
45
|
+
interface ExportResult {
|
|
46
|
+
text: string;
|
|
47
|
+
warnings: readonly string[];
|
|
48
|
+
}
|
|
49
|
+
/** Options for {@link DiagramFormat.write}. */
|
|
50
|
+
interface WriteOptions {
|
|
51
|
+
/** The page a format with no pages writes. Default the first. */
|
|
52
|
+
page?: string;
|
|
53
|
+
}
|
|
54
|
+
/** A file format a diagram can be read from or written to. */
|
|
55
|
+
interface DiagramFormat {
|
|
56
|
+
id: string;
|
|
57
|
+
/** What a menu calls it. */
|
|
58
|
+
name: string;
|
|
59
|
+
/** With their dots, most usual first: `['.dot', '.gv']`. */
|
|
60
|
+
extensions: readonly string[];
|
|
61
|
+
/** Whether `text` looks like this format, from its content alone. */
|
|
62
|
+
detect(text: string): boolean;
|
|
63
|
+
/** Throws on text this format cannot read. */
|
|
64
|
+
read?(text: string): ImportResult | Promise<ImportResult>;
|
|
65
|
+
write?(doc: DiagramDocument, opts?: WriteOptions): ExportResult;
|
|
66
|
+
/** Whether {@link write} writes one page rather than the whole document. */
|
|
67
|
+
onePage?: boolean;
|
|
68
|
+
}
|
|
69
|
+
/** The page a one-page format writes: the one `opts.page` names, else the first. `null` for a document with none. */
|
|
70
|
+
declare function writtenPage(doc: DiagramDocument, opts?: WriteOptions): DocumentPage | null;
|
|
71
|
+
|
|
72
|
+
/** The formats a diagram reads from and writes to, and how a file finds its format. */
|
|
73
|
+
|
|
74
|
+
/** Every format this package reads or writes. */
|
|
75
|
+
declare const DIAGRAM_FORMATS: readonly DiagramFormat[];
|
|
76
|
+
/**
|
|
77
|
+
* The format `text` is in: among those whose content test passes, the first
|
|
78
|
+
* that claims `fileName`'s extension, else the first. `null` when none
|
|
79
|
+
* passes, whatever the extension says, since an extension such as `.xml` names
|
|
80
|
+
* many formats.
|
|
81
|
+
*/
|
|
82
|
+
declare function detectFormat(text: string, fileName?: string, formats?: readonly DiagramFormat[]): DiagramFormat | null;
|
|
83
|
+
/** Reads `text` with the format {@link detectFormat} picks. Rejects when none reads it. */
|
|
84
|
+
declare function readDocument(text: string, fileName?: string, formats?: readonly DiagramFormat[]): Promise<ImportResult>;
|
|
85
|
+
|
|
86
|
+
/** The native format: a {@link DiagramDocument} written out as JSON, which carries everything the model holds. */
|
|
87
|
+
|
|
88
|
+
/** A diagram document as JSON, every page in one file, recognized by its `format` field. */
|
|
89
|
+
declare const DIAGRAM_JSON: DiagramFormat;
|
|
90
|
+
|
|
91
|
+
/** Draw-style XML as a {@link DiagramFormat}. */
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Draw-style XML: a page per `<diagram>`, each a graph model of cells with
|
|
95
|
+
* geometry, written out or compressed. Recognized by its root element, since
|
|
96
|
+
* `.xml` names many formats.
|
|
97
|
+
*/
|
|
98
|
+
declare const DRAW_XML: DiagramFormat;
|
|
99
|
+
|
|
100
|
+
/** Mermaid as a {@link DiagramFormat}. */
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* A Mermaid flowchart, one page per file, laid out on import. Any Mermaid
|
|
104
|
+
* diagram is recognized, so reading another kind says which kind it is.
|
|
105
|
+
*/
|
|
106
|
+
declare const DIAGRAM_MERMAID: DiagramFormat;
|
|
107
|
+
|
|
108
|
+
/** Graphviz DOT as a {@link DiagramFormat}. */
|
|
109
|
+
|
|
110
|
+
/** A Graphviz DOT graph, one page per file, laid out on import unless every node has a `pos`. */
|
|
111
|
+
declare const DIAGRAM_DOT: DiagramFormat;
|
|
112
|
+
|
|
113
|
+
/** A diagram scene as a {@link DiagramDocument}: what every format writes from. */
|
|
114
|
+
|
|
115
|
+
/** Options for {@link documentFromScene}. */
|
|
116
|
+
interface DocumentFromSceneOptions {
|
|
117
|
+
/** The theme colors are read against when the scene's `diagram:theme` names none. Default the night theme. */
|
|
118
|
+
theme?: DiagramTheme;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Reads a diagram scene into a document: one page per page in its `core:pages`
|
|
122
|
+
* (one page around everything when it has none), each holding the shapes,
|
|
123
|
+
* connectors, containers and pools, and groups on it, in coordinates from the
|
|
124
|
+
* page's corner. A shape belongs to the page its outermost container does, and
|
|
125
|
+
* that is the one its box overlaps most, or the nearest one when it overlaps
|
|
126
|
+
* none. A connector the scene splits off-page, or whose ends export to
|
|
127
|
+
* different pages, goes in `crossPageEdges`: without waypoints when split,
|
|
128
|
+
* with them in world coordinates when not. Colors are kept
|
|
129
|
+
* where the scene's theme would not give them: the author's own, and any a
|
|
130
|
+
* theme never set.
|
|
131
|
+
*/
|
|
132
|
+
declare function documentFromScene<TData, TLayer extends string, TPose>(scene: Scene<TData, TLayer, TPose>, opts?: DocumentFromSceneOptions): DiagramDocument;
|
|
133
|
+
|
|
134
|
+
/** A {@link DiagramDocument} as scene specs and document values: what every import draws from. */
|
|
135
|
+
|
|
136
|
+
/** Options for {@link documentSpecs}. */
|
|
137
|
+
interface DocumentSpecsOptions<TLayer extends string = 'main'> {
|
|
138
|
+
/** The layer every spec goes on. Default `'main'`. */
|
|
139
|
+
layer?: TLayer;
|
|
140
|
+
/** The theme to draw in. Default the one the document names, else the night theme. */
|
|
141
|
+
theme?: DiagramTheme;
|
|
142
|
+
/** Measures text. Default an estimate from character count. */
|
|
143
|
+
measure?: MeasureRowText;
|
|
144
|
+
}
|
|
145
|
+
/** What {@link documentSpecs} returns: the nodes, and the `core:pages` and `diagram:theme` document values. */
|
|
146
|
+
interface DocumentScene<TLayer extends string = 'main'> {
|
|
147
|
+
specs: DiagramSpec<TLayer>[];
|
|
148
|
+
doc: SerializedDoc;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The scene a document draws as. Its pages are placed with core's
|
|
152
|
+
* `layoutPages`, as a scene's `core:pages` places them. A page whose nodes
|
|
153
|
+
* all have a place is drawn where they say; any other page is laid out first,
|
|
154
|
+
* with `layered`, its placed nodes pinned (and grows to hold the result). Then
|
|
155
|
+
* every page, moved to its place, and the edges between pages are drawn by one
|
|
156
|
+
* `diagramScene` call with no layout, so the scene holds places and routes and
|
|
157
|
+
* no layout runs again.
|
|
158
|
+
*/
|
|
159
|
+
declare function documentSpecs<TLayer extends string = 'main'>(document: DiagramDocument, opts?: DocumentSpecsOptions<TLayer>): DocumentScene<TLayer>;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* One page of a diagram scene as `SvgNode`s: the nodes whose box meets the
|
|
163
|
+
* page, each written the way the canvas paints it.
|
|
164
|
+
*/
|
|
165
|
+
|
|
166
|
+
/** A page's rect in world space. A `PlacedPage` is one. */
|
|
167
|
+
interface PageRect {
|
|
168
|
+
readonly x: number;
|
|
169
|
+
readonly y: number;
|
|
170
|
+
readonly width: number;
|
|
171
|
+
readonly height: number;
|
|
172
|
+
}
|
|
173
|
+
/** A diagram scene as the exports read it: world-space `RectPose`s. */
|
|
174
|
+
type PageExportScene = Scene<unknown, string, RectPose>;
|
|
175
|
+
/**
|
|
176
|
+
* The `SvgNode`s of everything on `page`, in paint order: every node on a
|
|
177
|
+
* visible content layer whose box meets the page, with what is under it.
|
|
178
|
+
* Diagram outlines and drawn marks go through the diagram painters, a node
|
|
179
|
+
* that derives its path (a connector) is drawn along that path, and anything
|
|
180
|
+
* else is written by `svgLeafFromKit`.
|
|
181
|
+
*/
|
|
182
|
+
declare function pageSvgNodes(scene: PageExportScene, page: PageRect): SvgNode[];
|
|
183
|
+
|
|
184
|
+
/** Options for {@link exportPageSvg}. */
|
|
185
|
+
interface ExportPageSvgOptions extends Pick<SerializeOptions, 'title' | 'onWarn' | 'pretty'> {
|
|
186
|
+
/** The color painted under the page. Default: the page color of the
|
|
187
|
+
* scene's diagram theme (`diagram:theme`). `null` paints none. */
|
|
188
|
+
background?: string | null;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Write `page` of `scene` as an SVG document: its `viewBox` is the page rect,
|
|
192
|
+
* its size the page's, the page color comes first, and the scene is drawn as
|
|
193
|
+
* the canvas draws it, cut to the page's edges. What lies wholly off the page
|
|
194
|
+
* is left out.
|
|
195
|
+
*
|
|
196
|
+
* It waits for the paint kinds and faces the document needs, so its text is
|
|
197
|
+
* written in the lines the canvas lays it out into. A load that fails goes to
|
|
198
|
+
* `onWarn`, and the export goes ahead without it.
|
|
199
|
+
*/
|
|
200
|
+
declare function exportPageSvg(scene: PageExportScene, page: PageRect, opts?: ExportPageSvgOptions): Promise<string>;
|
|
201
|
+
|
|
202
|
+
/** Options for {@link exportPagePng}. */
|
|
203
|
+
interface ExportPagePngOptions {
|
|
204
|
+
/** Output pixels per world unit: 2 makes an image twice the page's size. */
|
|
205
|
+
scale: number;
|
|
206
|
+
/** The color painted under the page. Default: the page color of the
|
|
207
|
+
* scene's diagram theme. `null` leaves it transparent. */
|
|
208
|
+
background?: string | null;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Draw `page` of `scene` into a PNG, `page × scale` pixels, through the
|
|
212
|
+
* renderer the canvas draws with, so it shows what the canvas shows, cut to
|
|
213
|
+
* the page's edges. Annotation layers are left out.
|
|
214
|
+
*
|
|
215
|
+
* The caller has registered whatever the scene needs painting with, as it
|
|
216
|
+
* must to draw it at all: the diagram painters (`registerDiagramShape`,
|
|
217
|
+
* `registerMarkShape`) and its fonts. Paint kinds and faces that load on
|
|
218
|
+
* demand are waited for. Needs WebGL2 and `OffscreenCanvas`.
|
|
219
|
+
*/
|
|
220
|
+
declare function exportPagePng(scene: PageExportScene, page: PageRect, opts: ExportPagePngOptions): Promise<Blob>;
|
|
221
|
+
|
|
222
|
+
/** Options for {@link exportPagesPdf}. */
|
|
223
|
+
interface ExportPagesPdfOptions {
|
|
224
|
+
/** The color painted under each page. Default: the page color of the
|
|
225
|
+
* scene's diagram theme. `null` leaves it unpainted. */
|
|
226
|
+
background?: string | null;
|
|
227
|
+
/** The document's title. */
|
|
228
|
+
title?: string;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Write each of `pages` of `scene` as a page of one PDF, `page × 0.75` points
|
|
232
|
+
* in size, in the order given. Shapes and strokes are vector; text is real,
|
|
233
|
+
* selectable text in its embedded face. What a PDF cannot draw is painted
|
|
234
|
+
* through the renderer and placed as an image, and anything it could not
|
|
235
|
+
* carry at all comes back in `skipped`. Annotation layers are left out.
|
|
236
|
+
*
|
|
237
|
+
* The caller has registered what the scene needs painting with, as for
|
|
238
|
+
* `exportPagePng`, including each font's outlines. Needs WebGL2 and
|
|
239
|
+
* `OffscreenCanvas`.
|
|
240
|
+
*/
|
|
241
|
+
declare function exportPagesPdf(scene: PageExportScene, pages: readonly PageRect[], opts?: ExportPagesPdfOptions): Promise<{
|
|
242
|
+
blob: Blob;
|
|
243
|
+
skipped: readonly PdfSkip[];
|
|
244
|
+
}>;
|
|
245
|
+
|
|
246
|
+
export { DIAGRAM_DOT, DIAGRAM_FORMATS, DIAGRAM_JSON, DIAGRAM_MERMAID, DRAW_XML, type DiagramDocument, type DiagramFormat, type DocumentFromSceneOptions, type DocumentPage, type DocumentScene, type DocumentSpecsOptions, type ExportPagePngOptions, type ExportPageSvgOptions, type ExportPagesPdfOptions, type ExportResult, type ImportResult, type PageExportScene, type PageRect, type WriteOptions, detectFormat, documentFromScene, documentSpecs, exportPagePng, exportPageSvg, exportPagesPdf, pageSvgNodes, readDocument, writtenPage };
|