@draftably/markdown 0.0.0-stage → 0.2.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/README.md +24 -2
- package/dist/LICENSE +21 -0
- package/dist/chunks/core-D4HpamVq.js +323 -0
- package/dist/chunks/mermaid-facade-BoLWBerE.js +289 -0
- package/dist/chunks/mermaid-importer-IVovOQE9.js +3753 -0
- package/dist/chunks/metadata-Dx6T_2Zy.js +53 -0
- package/dist/client.js +153 -0
- package/dist/files.js +103 -0
- package/dist/index.js +8 -0
- package/dist/markdown-it.js +156 -0
- package/dist/mermaid.js +93 -0
- package/dist/remark.js +86 -0
- package/dist/types/packages/markdown/src/client-validation.d.ts +5 -0
- package/dist/types/packages/markdown/src/client.d.ts +12 -0
- package/dist/types/packages/markdown/src/core.d.ts +110 -0
- package/dist/types/packages/markdown/src/files.d.ts +12 -0
- package/dist/types/packages/markdown/src/index.d.ts +3 -0
- package/dist/types/packages/markdown/src/markdown-it-helpers.d.ts +9 -0
- package/dist/types/packages/markdown/src/markdown-it.d.ts +30 -0
- package/dist/types/packages/markdown/src/mermaid.d.ts +8 -0
- package/dist/types/packages/markdown/src/metadata.d.ts +9 -0
- package/dist/types/packages/markdown/src/remark.d.ts +21 -0
- package/dist/types/packages/markdown/src/source.d.ts +4 -0
- package/dist/types/src/dsl/cells.d.ts +91 -0
- package/dist/types/src/dsl/channels.d.ts +53 -0
- package/dist/types/src/dsl/compile.d.ts +162 -0
- package/dist/types/src/dsl/frame.d.ts +38 -0
- package/dist/types/src/dsl/lanes.d.ts +23 -0
- package/dist/types/src/dsl/legend-notes.d.ts +3 -0
- package/dist/types/src/dsl/project.d.ts +39 -0
- package/dist/types/src/dsl/syntax.d.ts +317 -0
- package/dist/types/src/import/import-core.d.ts +105 -0
- package/dist/types/src/import/mermaid-facade.d.ts +120 -0
- package/dist/types/src/import/mermaid-importer.d.ts +4 -0
- package/dist/types/src/import/mermaid-sequence.d.ts +8 -0
- package/dist/types/src/model/appearance.d.ts +209 -0
- package/dist/types/src/model/bounds.d.ts +19 -0
- package/dist/types/src/model/document.d.ts +24 -0
- package/dist/types/src/model/font-faces.d.ts +24 -0
- package/dist/types/src/model/fonts.d.ts +47 -0
- package/dist/types/src/model/footnote.d.ts +34 -0
- package/dist/types/src/model/geometry.d.ts +29 -0
- package/dist/types/src/model/graph.d.ts +53 -0
- package/dist/types/src/model/heading.d.ts +38 -0
- package/dist/types/src/model/icons.d.ts +2 -0
- package/dist/types/src/model/labels.d.ts +88 -0
- package/dist/types/src/model/link.d.ts +63 -0
- package/dist/types/src/model/markers.d.ts +47 -0
- package/dist/types/src/model/note.d.ts +75 -0
- package/dist/types/src/model/rich-text.d.ts +24 -0
- package/dist/types/src/model/routes.d.ts +170 -0
- package/dist/types/src/model/status.d.ts +84 -0
- package/dist/types/src/model/styles.d.ts +13 -0
- package/dist/types/src/model/types.d.ts +277 -0
- package/package.json +53 -3
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Diagnostic } from '@draftably/runtime';
|
|
2
|
+
import type { FenceOptions } from './metadata.js';
|
|
3
|
+
export { resolveSource } from './source.js';
|
|
4
|
+
export { parseFenceOptions } from './metadata.js';
|
|
5
|
+
export type { Diagnostic } from '@draftably/runtime';
|
|
6
|
+
export interface DraftDocument {
|
|
7
|
+
path?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DraftAsset {
|
|
10
|
+
fileName: string;
|
|
11
|
+
mediaType: 'image/svg+xml';
|
|
12
|
+
bytes: Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
export interface AssetReference {
|
|
15
|
+
fileName: string;
|
|
16
|
+
url: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DraftDocumentResult {
|
|
19
|
+
version: 1;
|
|
20
|
+
assets: readonly AssetReference[];
|
|
21
|
+
clientModules: readonly string[];
|
|
22
|
+
dependencies: readonly string[];
|
|
23
|
+
diagnostics: readonly Diagnostic[];
|
|
24
|
+
}
|
|
25
|
+
export interface SourceDependency {
|
|
26
|
+
documentPath: string;
|
|
27
|
+
dependencyPath: string;
|
|
28
|
+
missing: boolean;
|
|
29
|
+
watchPath?: string;
|
|
30
|
+
}
|
|
31
|
+
export type EmitAsset = (asset: DraftAsset, context: {
|
|
32
|
+
document: DraftDocument;
|
|
33
|
+
fenceIndex: number;
|
|
34
|
+
}) => Promise<{
|
|
35
|
+
url: string;
|
|
36
|
+
}>;
|
|
37
|
+
export interface DraftMarkdownOptions {
|
|
38
|
+
emitAsset: EmitAsset;
|
|
39
|
+
errors?: 'fail' | 'placeholder';
|
|
40
|
+
/**
|
|
41
|
+
* `convert` draws ```mermaid fences that hold a flowchart or sequence as Draftably images and
|
|
42
|
+
* leaves every other Mermaid family as a code block. `off` (default) leaves all of them.
|
|
43
|
+
*/
|
|
44
|
+
mermaid?: 'convert' | 'off';
|
|
45
|
+
interactive?: MarkdownInteractiveBridge;
|
|
46
|
+
render?: {
|
|
47
|
+
includeSource?: boolean;
|
|
48
|
+
links?: {
|
|
49
|
+
mode: 'none';
|
|
50
|
+
} | {
|
|
51
|
+
mode: 'safe';
|
|
52
|
+
baseUrl?: string;
|
|
53
|
+
target?: '_self' | '_blank';
|
|
54
|
+
cacheKey?: string;
|
|
55
|
+
resolve?: (request: {
|
|
56
|
+
itemId: string;
|
|
57
|
+
href: string;
|
|
58
|
+
}) => string | null;
|
|
59
|
+
};
|
|
60
|
+
limits?: {
|
|
61
|
+
maxSourceChars?: number;
|
|
62
|
+
maxSourceBytes?: number;
|
|
63
|
+
maxOutputBytes?: number;
|
|
64
|
+
maxObjects?: number;
|
|
65
|
+
maxEdges?: number;
|
|
66
|
+
maxDepth?: number;
|
|
67
|
+
};
|
|
68
|
+
signal?: AbortSignal;
|
|
69
|
+
};
|
|
70
|
+
sources?: {
|
|
71
|
+
rootDir: string;
|
|
72
|
+
onDependency?: (dependency: SourceDependency) => void;
|
|
73
|
+
};
|
|
74
|
+
onDiagnostic?: (diagnostic: Diagnostic) => void;
|
|
75
|
+
}
|
|
76
|
+
export interface DraftViewerInitV1 {
|
|
77
|
+
version: 1;
|
|
78
|
+
key: string;
|
|
79
|
+
source: string;
|
|
80
|
+
state: string | null;
|
|
81
|
+
label: string;
|
|
82
|
+
policyId: string;
|
|
83
|
+
}
|
|
84
|
+
export interface MarkdownInteractiveBridge {
|
|
85
|
+
clientModuleUrl: string;
|
|
86
|
+
policyId: string;
|
|
87
|
+
emitInit(data: DraftViewerInitV1): Promise<{
|
|
88
|
+
fileName: string;
|
|
89
|
+
url: string;
|
|
90
|
+
}>;
|
|
91
|
+
}
|
|
92
|
+
/** Native source for a Mermaid fence, or null when the fence stays as code. */
|
|
93
|
+
export declare function mermaidSource(text: string, location: Diagnostic['location'], options: DraftMarkdownOptions): Promise<{
|
|
94
|
+
source: string | null;
|
|
95
|
+
alt?: string;
|
|
96
|
+
diagnostics: Diagnostic[];
|
|
97
|
+
}>;
|
|
98
|
+
export declare function makeDiagnostic(code: string, message: string, location?: Diagnostic['location'], related?: Diagnostic['related']): Diagnostic;
|
|
99
|
+
export declare function contentHash(value: string | Uint8Array): string;
|
|
100
|
+
export declare function hostFailure(error: unknown, message?: string): Error;
|
|
101
|
+
export declare function isHostFailure(error: unknown): boolean;
|
|
102
|
+
export declare function isNoPlaceholder(error: unknown): boolean;
|
|
103
|
+
export declare function prepare(source: string, metadata: FenceOptions, location: Diagnostic['location'], document: DraftDocument, fenceIndex: number, options: DraftMarkdownOptions): Promise<{
|
|
104
|
+
node: Record<string, unknown>;
|
|
105
|
+
asset?: AssetReference;
|
|
106
|
+
diagnostics: Diagnostic[];
|
|
107
|
+
dependency?: string;
|
|
108
|
+
extraAssets?: AssetReference[];
|
|
109
|
+
clientModule?: string;
|
|
110
|
+
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EmitAsset, MarkdownInteractiveBridge } from './core.js';
|
|
2
|
+
export interface FileAssets {
|
|
3
|
+
directory: string;
|
|
4
|
+
emitAsset: EmitAsset;
|
|
5
|
+
emitInit: MarkdownInteractiveBridge['emitInit'];
|
|
6
|
+
copyTo(directory: string): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
/** Create a content-addressed Node file store for generated SVG and viewer JSON assets. */
|
|
9
|
+
export declare function createFileAssets(options: {
|
|
10
|
+
directory: string;
|
|
11
|
+
publicPath: string;
|
|
12
|
+
}): FileAssets;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { parseFenceOptions } from './core.js';
|
|
2
|
+
export type { FenceOptions } from './metadata.js';
|
|
3
|
+
export type { AssetReference, Diagnostic, DraftAsset, DraftDocument, DraftDocumentResult, DraftMarkdownOptions, DraftViewerInitV1, EmitAsset, MarkdownInteractiveBridge, SourceDependency, } from './core.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function isDraftFenceInfo(info: string): boolean;
|
|
2
|
+
export interface HtmlImage {
|
|
3
|
+
url: string;
|
|
4
|
+
alt: string;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function escapeHtml(value: string): string;
|
|
9
|
+
export declare function imageHtml(image: HtmlImage): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type DraftDocumentResult, type DraftMarkdownOptions } from './core.js';
|
|
2
|
+
export interface DraftMarkdownItEnvironment {
|
|
3
|
+
draftably?: {
|
|
4
|
+
documentPath?: string;
|
|
5
|
+
};
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
}
|
|
8
|
+
interface Token {
|
|
9
|
+
type: string;
|
|
10
|
+
info?: string;
|
|
11
|
+
content?: string;
|
|
12
|
+
map?: number[] | null;
|
|
13
|
+
children?: Token[] | null;
|
|
14
|
+
}
|
|
15
|
+
interface MarkdownItRenderHost<Tokens> {
|
|
16
|
+
parse(source: string, env?: unknown): Tokens[];
|
|
17
|
+
options: unknown;
|
|
18
|
+
renderer: {
|
|
19
|
+
render(tokens: Tokens[], options: unknown, env?: unknown): string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare function createMarkdownItDraft(options: DraftMarkdownOptions): {
|
|
23
|
+
plugin: (instance: unknown) => void;
|
|
24
|
+
prepare: (tokens: Token[], env?: DraftMarkdownItEnvironment) => Promise<DraftDocumentResult>;
|
|
25
|
+
render: (md: MarkdownItRenderHost<unknown>, source: string, env?: DraftMarkdownItEnvironment) => Promise<{
|
|
26
|
+
html: string;
|
|
27
|
+
manifest: DraftDocumentResult;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Diagnostic } from '@draftably/runtime';
|
|
2
|
+
export declare function isMermaidCandidate(text: string): boolean;
|
|
3
|
+
/** Native source for a Mermaid flowchart or sequence, or null to leave the fence to Mermaid. */
|
|
4
|
+
export declare function convertMermaid(text: string, location: Diagnostic['location']): Promise<{
|
|
5
|
+
source: string | null;
|
|
6
|
+
alt?: string;
|
|
7
|
+
diagnostics: Diagnostic[];
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type DraftMarkdownOptions } from './core.js';
|
|
2
|
+
interface Node {
|
|
3
|
+
type: string;
|
|
4
|
+
lang?: string | null;
|
|
5
|
+
meta?: string | null;
|
|
6
|
+
value?: string;
|
|
7
|
+
children?: Node[];
|
|
8
|
+
position?: {
|
|
9
|
+
start?: {
|
|
10
|
+
line?: number;
|
|
11
|
+
column?: number;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
interface FileLike {
|
|
16
|
+
path?: string;
|
|
17
|
+
data?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
/** Convert parser-recognized `draft` code nodes, and opted-in Mermaid ones, into static image nodes. */
|
|
20
|
+
export default function remarkDraft(options: DraftMarkdownOptions): (tree: Node, file: FileLike) => Promise<void>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ResolvedAppearance } from '../model/appearance';
|
|
2
|
+
/** Width of a marker's bar, centred on the seam it marks. */
|
|
3
|
+
export declare const MARKER_WIDTH = 8;
|
|
4
|
+
/** How far a marker's bar runs past the cells, so a line meets it clear of their corners. */
|
|
5
|
+
export declare const MARKER_TAIL = 16;
|
|
6
|
+
/** Height of a cells group's title band for a title type of this line height. */
|
|
7
|
+
export declare const cellsBandFor: (lineHeight: number) => number;
|
|
8
|
+
export interface CellInput {
|
|
9
|
+
id: string;
|
|
10
|
+
label: string;
|
|
11
|
+
marker: boolean;
|
|
12
|
+
/** Columns the cell covers in a grid. */
|
|
13
|
+
span?: number;
|
|
14
|
+
/** From a `size` line. */
|
|
15
|
+
size?: {
|
|
16
|
+
width: number;
|
|
17
|
+
height?: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface CellBox {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
w: number;
|
|
24
|
+
h: number;
|
|
25
|
+
}
|
|
26
|
+
/** A cell's own size: one line of title when it fits in `MAX_CELL`, wrapped when it does not. */
|
|
27
|
+
export declare function cellSize(c: CellInput, look: ResolvedAppearance): {
|
|
28
|
+
w: number;
|
|
29
|
+
h: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Cells edge to edge, in rows of `columns` columns filled in order; a cell's `span` covers that
|
|
33
|
+
* many columns, and a cell that does not fit the rest of a row starts the next one. Without
|
|
34
|
+
* `columns`, the cells form one row (`right`) or one column (`down`). Each column is as wide as
|
|
35
|
+
* its widest single cell, widened at its last column for a wider spanning cell, and each row is
|
|
36
|
+
* as tall as its tallest cell. Cells narrower than `minWidth` in all, the title band's width,
|
|
37
|
+
* widen the last column.
|
|
38
|
+
*
|
|
39
|
+
* A marker takes no room: in one row or column, its bar sits on the seam before the next cell
|
|
40
|
+
* and spans the band above as well, so it cuts the whole object, and runs a short tail past the
|
|
41
|
+
* cells where lines meet it.
|
|
42
|
+
*/
|
|
43
|
+
export declare function layoutCells(cells: CellInput[], shape: {
|
|
44
|
+
direction: 'right' | 'down';
|
|
45
|
+
columns?: number;
|
|
46
|
+
}, look: ResolvedAppearance, minWidth?: number): {
|
|
47
|
+
boxes: Map<string, CellBox>;
|
|
48
|
+
w: number;
|
|
49
|
+
h: number;
|
|
50
|
+
};
|
|
51
|
+
/** Width of one unit of a byte or bit layout, and the units in each row, unless the file says. */
|
|
52
|
+
export declare const UNIT_WIDTH: {
|
|
53
|
+
readonly bit: 24;
|
|
54
|
+
readonly byte: 48;
|
|
55
|
+
};
|
|
56
|
+
export declare const UNIT_COLUMNS: {
|
|
57
|
+
readonly bit: 32;
|
|
58
|
+
readonly byte: 16;
|
|
59
|
+
};
|
|
60
|
+
export interface UnitCells {
|
|
61
|
+
/** Each field's main box: the longest piece, which holds its title. */
|
|
62
|
+
boxes: Map<string, CellBox>;
|
|
63
|
+
/** The other pieces of a field that runs on past a row's end. */
|
|
64
|
+
pieces: Map<string, CellBox[]>;
|
|
65
|
+
/** Fields of variable length, drawn with broken ends. */
|
|
66
|
+
open: string[];
|
|
67
|
+
/** Unit numbers above the first row: their centres, and the room they take above the cells. */
|
|
68
|
+
ruler?: {
|
|
69
|
+
h: number;
|
|
70
|
+
ticks: Array<{
|
|
71
|
+
x: number;
|
|
72
|
+
label: string;
|
|
73
|
+
}>;
|
|
74
|
+
};
|
|
75
|
+
w: number;
|
|
76
|
+
h: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A byte or bit layout: every unit has one width, so a field's width is its size. Rows hold
|
|
80
|
+
* `columns` units. A field longer than the rest of its row runs on into the next rows; a field of
|
|
81
|
+
* variable length (`span: 'var'`) fills the rest of its row, or a whole row, with broken ends.
|
|
82
|
+
* Every row has the height of the tallest title.
|
|
83
|
+
*/
|
|
84
|
+
export declare function layoutUnits(cells: Array<CellInput & {
|
|
85
|
+
open?: boolean;
|
|
86
|
+
}>, shape: {
|
|
87
|
+
unit: 'bit' | 'byte';
|
|
88
|
+
columns?: number;
|
|
89
|
+
unitWidth?: number;
|
|
90
|
+
ruler: boolean;
|
|
91
|
+
}, look: ResolvedAppearance): UnitCells;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routing channels inside groups.
|
|
3
|
+
*
|
|
4
|
+
* A group leaves `GROUP_INSET` between its members and its border. That is padding, not room for
|
|
5
|
+
* a line: a line routed through it runs beside a member and along the border at once. When a
|
|
6
|
+
* connection has to travel inside a group (a member boxed in by its neighbours, or a link between
|
|
7
|
+
* two of the group's children that can't go straight across), the group grows a channel on one
|
|
8
|
+
* side, wide enough for each such line to run a full standoff from the members,
|
|
9
|
+
* the border and each other. A link between children takes the side of them both ends lean
|
|
10
|
+
* toward, and a return (up or left) takes the left or top when they lean neither way, so a
|
|
11
|
+
* forward line and its return don't cross. The compiler lays the scene out once, plans channels
|
|
12
|
+
* from that geometry, and lays it out again with them.
|
|
13
|
+
*/
|
|
14
|
+
import type { ModelEdge } from './syntax';
|
|
15
|
+
/**
|
|
16
|
+
* Room a group leaves round its content: the inset on the left, right and bottom (at least
|
|
17
|
+
* `GROUP_INSET`), and extra room under the title band on top (0 without a channel there).
|
|
18
|
+
*/
|
|
19
|
+
export interface Channel {
|
|
20
|
+
left: number;
|
|
21
|
+
right: number;
|
|
22
|
+
top: number;
|
|
23
|
+
bottom: number;
|
|
24
|
+
/** How many lines each side's channel was planned for. */
|
|
25
|
+
lines: Record<Side, number>;
|
|
26
|
+
}
|
|
27
|
+
/** Channels may grow the drawing's area by this much at most. */
|
|
28
|
+
export declare const CHANNEL_BUDGET = 1.1;
|
|
29
|
+
/**
|
|
30
|
+
* Drop the channels that carry fewest lines until the drawing laid out with the rest (`measure`)
|
|
31
|
+
* is within `CHANNEL_BUDGET` of its area without any (`plain`).
|
|
32
|
+
*/
|
|
33
|
+
export declare function trimChannels(plan: Map<string, Channel>, plain: number, measure: (channels: Map<string, Channel>) => number): Map<string, Channel>;
|
|
34
|
+
interface Box {
|
|
35
|
+
id: string;
|
|
36
|
+
type: string;
|
|
37
|
+
parent: string;
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
w: number;
|
|
41
|
+
h: number;
|
|
42
|
+
}
|
|
43
|
+
export type Side = 'left' | 'right' | 'top' | 'bottom';
|
|
44
|
+
/**
|
|
45
|
+
* Channels for the scene laid out as `objects`. A group is keyed by id; groups with no traffic
|
|
46
|
+
* are left out.
|
|
47
|
+
*/
|
|
48
|
+
export declare function planChannels(objects: Box[], edges: ModelEdge[], routing?: {
|
|
49
|
+
edgeGap?: number;
|
|
50
|
+
portGap?: number;
|
|
51
|
+
standoff?: number;
|
|
52
|
+
}): Map<string, Channel>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { type ResolvedAppearance } from '../model/appearance';
|
|
2
|
+
import type { CellsChrome, Lane, SequenceLayout } from '../model/types';
|
|
3
|
+
import { GROUP_HEADER, GROUP_INSET, contentOrigin } from './frame';
|
|
4
|
+
import { type Model, type ModelEdge, type ModelLayout, type ModelObject } from './syntax';
|
|
5
|
+
/** The single render context. Browser window size changes the camera, never the layout. */
|
|
6
|
+
export declare const RENDER_CONTEXT: {
|
|
7
|
+
readonly width: 1100;
|
|
8
|
+
readonly height: 720;
|
|
9
|
+
};
|
|
10
|
+
export { GROUP_HEADER, GROUP_INSET, contentOrigin };
|
|
11
|
+
export interface SceneObject extends ModelObject {
|
|
12
|
+
/** World (diagram) coordinates. */
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
w: number;
|
|
16
|
+
h: number;
|
|
17
|
+
/** Position relative to the parent's content origin; `pin` and `stay` use these. */
|
|
18
|
+
localX: number;
|
|
19
|
+
localY: number;
|
|
20
|
+
/** Local position from the automatic recipe alone, before refinements; `nudge` offsets this. */
|
|
21
|
+
baseX: number;
|
|
22
|
+
baseY: number;
|
|
23
|
+
depth: number;
|
|
24
|
+
/** Sequence participants: how far the dashed lifeline runs below the box. */
|
|
25
|
+
lifeline?: number;
|
|
26
|
+
/** Soft groups: the tint's rectangles, relative to the group's top left; the first holds the label. */
|
|
27
|
+
hull?: Array<{
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
w: number;
|
|
31
|
+
h: number;
|
|
32
|
+
}>;
|
|
33
|
+
/** Groups: lines the title wraps to, when more than one. */
|
|
34
|
+
titleLines?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface Diagnostic {
|
|
37
|
+
level: 'error' | 'warning' | 'info';
|
|
38
|
+
code: string;
|
|
39
|
+
message: string;
|
|
40
|
+
/** Source line of the rule involved, when there is one. */
|
|
41
|
+
line?: number;
|
|
42
|
+
ids: string[];
|
|
43
|
+
}
|
|
44
|
+
/** A connection as the file declares it, plus the lane a fold's wrap edge returns along. */
|
|
45
|
+
export interface SceneEdge extends ModelEdge {
|
|
46
|
+
lane?: Lane;
|
|
47
|
+
/** A sequence message: the height of its row; it is drawn straight between lifelines there. */
|
|
48
|
+
row?: number;
|
|
49
|
+
}
|
|
50
|
+
export interface Scene {
|
|
51
|
+
model: Model;
|
|
52
|
+
title: string;
|
|
53
|
+
objects: SceneObject[];
|
|
54
|
+
byId: Map<string, SceneObject>;
|
|
55
|
+
edges: SceneEdge[];
|
|
56
|
+
diagnostics: Diagnostic[];
|
|
57
|
+
/** The file's resolved appearance: the spacing and type every size above was computed with. */
|
|
58
|
+
look: ResolvedAppearance;
|
|
59
|
+
/** Rulers and run-on pieces of byte and bit layouts, by group. */
|
|
60
|
+
cells: Map<string, CellsChrome>;
|
|
61
|
+
/** Sequence diagrams: the panel they are drawn on and their phases' row bands. */
|
|
62
|
+
sequence?: SequenceLayout;
|
|
63
|
+
}
|
|
64
|
+
type Size = {
|
|
65
|
+
w: number;
|
|
66
|
+
h: number;
|
|
67
|
+
};
|
|
68
|
+
type Pos = {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
};
|
|
72
|
+
export declare function compile(source: string): Promise<Scene>;
|
|
73
|
+
/**
|
|
74
|
+
* Check source synchronously: every error `compile` can report, without running layout engines
|
|
75
|
+
* (they never add errors). Engine-governed scopes keep their built-in recipe in the result.
|
|
76
|
+
*/
|
|
77
|
+
export declare function checkSource(source: string): Scene;
|
|
78
|
+
/**
|
|
79
|
+
* The scene as layout sees it, for edits that write positions: soft and frameless groups left
|
|
80
|
+
* out, and each object under the container that lays it out, which its local position is
|
|
81
|
+
* relative to.
|
|
82
|
+
*/
|
|
83
|
+
export declare function layoutView(scene: Scene): Scene;
|
|
84
|
+
/** How far a soft refinement may give way before `check` warns that it no longer holds. */
|
|
85
|
+
export declare const RELAXED_WARNING = 16;
|
|
86
|
+
/** Solver budget for engine recipes; the same budget Compare and the timeline use. */
|
|
87
|
+
export declare const ENGINE_ITERATIONS = 640;
|
|
88
|
+
/** A labelled edge between two siblings, with the room its label needs across and down a gap. */
|
|
89
|
+
interface LabelRoom {
|
|
90
|
+
a: string;
|
|
91
|
+
b: string;
|
|
92
|
+
w: number;
|
|
93
|
+
h: number;
|
|
94
|
+
}
|
|
95
|
+
export declare function layoutFor(m: Model, scope: string): ModelLayout;
|
|
96
|
+
/**
|
|
97
|
+
* Size of a node: its requested size, or the default width with a height that fits the title in
|
|
98
|
+
* the theme's type and padding. A requested size is kept exactly; `overflow` reports a title that
|
|
99
|
+
* no longer fits in it.
|
|
100
|
+
*/
|
|
101
|
+
export declare function leafSize(o: ModelObject, size: {
|
|
102
|
+
width: number;
|
|
103
|
+
height?: number;
|
|
104
|
+
} | undefined, look: ResolvedAppearance): {
|
|
105
|
+
w: number;
|
|
106
|
+
h: number;
|
|
107
|
+
overflow: boolean;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Longest-path ranks, in declaration order. Cycles are broken first: a depth-first walk from the
|
|
111
|
+
* sources (then any node not yet reached), in declaration order, sets aside each edge that returns
|
|
112
|
+
* to a node still on the walk. A loop therefore keeps its path along the reading direction and
|
|
113
|
+
* only its return edge runs backwards.
|
|
114
|
+
*/
|
|
115
|
+
export declare function rankLayers(ids: string[], pairs: Array<[string, string]>): string[][];
|
|
116
|
+
/** A folded run: each band's ids in reading order, and the axis the bands read along. */
|
|
117
|
+
export interface Fold {
|
|
118
|
+
bands: string[][];
|
|
119
|
+
axis: 'right' | 'down';
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Fold a long run of ranks into bands, like lines of text: each band starts again at the
|
|
123
|
+
* beginning of the reading direction, and the bands stack across it. A run that is longer than
|
|
124
|
+
* the render context and more than `FOLD_ASPECT` times its depth is cut only between ranks (where
|
|
125
|
+
* no box spans the cut), into the fewest bands that bring it within both. Within a quarter of an
|
|
126
|
+
* even share, a cut is chosen for the fewest edges across it, keeping each decision with its
|
|
127
|
+
* branches and each loop whole, before an exact balance. Other runs are returned unchanged.
|
|
128
|
+
*
|
|
129
|
+
* `plan` is the same run laid out without its edge labels. Whether to fold, how many bands and
|
|
130
|
+
* where to cut are decided on it, so relabelling an edge never adds a band or moves a cut: the
|
|
131
|
+
* labels only widen the gaps they need inside their own band.
|
|
132
|
+
*/
|
|
133
|
+
export declare function foldRanks(items: Array<{
|
|
134
|
+
id: string;
|
|
135
|
+
w: number;
|
|
136
|
+
h: number;
|
|
137
|
+
}>, positions: Map<string, Pos>, axis: 'right' | 'down', gap: number, pairs: Array<[string, string]>, rooms?: LabelRoom[], decisions?: Set<string>, plan?: Map<string, Pos>, { aspect, fewest, room, }?: {
|
|
138
|
+
aspect?: number;
|
|
139
|
+
fewest?: number;
|
|
140
|
+
room?: number;
|
|
141
|
+
}): {
|
|
142
|
+
positions: Map<string, Pos>;
|
|
143
|
+
fold?: Fold;
|
|
144
|
+
};
|
|
145
|
+
/** How many times orthogonal paths, given as points along and across, cross one another. */
|
|
146
|
+
export declare function crossings(paths: Array<Array<{
|
|
147
|
+
u: number;
|
|
148
|
+
v: number;
|
|
149
|
+
}>>): number;
|
|
150
|
+
/** The order of up to six items that scores fewest crossings; the first such, from `items`. */
|
|
151
|
+
export declare function fewestCrossings<T>(items: T[], score: (order: T[]) => number): T[];
|
|
152
|
+
/**
|
|
153
|
+
* Lay out a model. `arranged` holds world positions from layout engines; scopes that an engine
|
|
154
|
+
* governs take their children's relative placement from it instead of their built-in recipe.
|
|
155
|
+
*
|
|
156
|
+
* Nodes are laid out on slots: their size in the reference appearance (the default theme, with
|
|
157
|
+
* the file's own overrides), so a theme switch keeps rows, order and positions. Each node is drawn
|
|
158
|
+
* at its theme's size in its slot. A slot grows only where the theme's size is larger
|
|
159
|
+
* than the scope's gap can absorb (`SLOT_SPILL`), or where spilling would bring two boxes closer
|
|
160
|
+
* than `MIN_GAP`. With `slots`, objects come out at their slot size (the engines' input).
|
|
161
|
+
*/
|
|
162
|
+
export declare function layoutModel(m: Model, arranged?: Map<string, Pos & Size>, slots?: boolean): Scene;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Group frame metrics shared by the compiler, the projection and the translator. */
|
|
2
|
+
/** Space between a group's frame and its content, on the sides and bottom. */
|
|
3
|
+
export declare const GROUP_INSET = 24;
|
|
4
|
+
/**
|
|
5
|
+
* Space between a group's top edge and its content in the default theme; the title sits in it.
|
|
6
|
+
* Themes with taller titles reserve more (`ResolvedAppearance.groupHeader`).
|
|
7
|
+
*/
|
|
8
|
+
export declare const GROUP_HEADER = 48;
|
|
9
|
+
/**
|
|
10
|
+
* Horizontal room a group title needs besides its text: the icon and gap before it (33) and the
|
|
11
|
+
* frame controls after it (64), as `GroupView` and the SVG export truncate titles.
|
|
12
|
+
*/
|
|
13
|
+
export declare const GROUP_TITLE_CHROME: number;
|
|
14
|
+
/** Room a soft group's tint leaves round its members, and above them for its label. */
|
|
15
|
+
export declare const SOFT_PAD = 10;
|
|
16
|
+
export declare const SOFT_LABEL = 18;
|
|
17
|
+
/** Where a soft group's label sits in its tint: in the annotation face, at the top left. */
|
|
18
|
+
export declare const SOFT_TITLE: {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
};
|
|
22
|
+
/** Corner radius of each rectangle of a tint; small, so joined rectangles read as one shape. */
|
|
23
|
+
export declare const SOFT_RADIUS = 6;
|
|
24
|
+
/** Dash of a sequence participant's lifeline; quieter than a message line. */
|
|
25
|
+
export declare const LIFELINE: {
|
|
26
|
+
dash: string;
|
|
27
|
+
width: number;
|
|
28
|
+
};
|
|
29
|
+
/** Top-left of a group's content area, which its children's local positions are relative to. */
|
|
30
|
+
export declare const contentOrigin: (group: {
|
|
31
|
+
x: number;
|
|
32
|
+
y: number;
|
|
33
|
+
}, header?: number) => {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
};
|
|
37
|
+
/** Horizontal room a `cells` group's title needs besides its text: padding and the collapse control. */
|
|
38
|
+
export declare const CELLS_TITLE_CHROME: number;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Lane } from '../model/types';
|
|
2
|
+
import type { ModelEdge } from './syntax';
|
|
3
|
+
interface Box {
|
|
4
|
+
id: string;
|
|
5
|
+
type: string;
|
|
6
|
+
shape?: string;
|
|
7
|
+
parent: string;
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
w: number;
|
|
11
|
+
h: number;
|
|
12
|
+
}
|
|
13
|
+
/** A scope arranged along a reading axis, with its fold's bands when it folded. */
|
|
14
|
+
export interface FlowScope {
|
|
15
|
+
scope: string;
|
|
16
|
+
axis: 'right' | 'down';
|
|
17
|
+
bands?: string[][];
|
|
18
|
+
}
|
|
19
|
+
export declare function returnLanes(flows: FlowScope[], edges: ModelEdge[], byId: Map<string, Box>, taken: Set<string>, labelSize?: (label: string) => {
|
|
20
|
+
w: number;
|
|
21
|
+
h: number;
|
|
22
|
+
}): Map<string, Lane>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Diagram, Rect } from '../model/types';
|
|
2
|
+
import type { Scene } from './compile';
|
|
3
|
+
/** Editor state that is not part of the source and survives a reprojection. */
|
|
4
|
+
export type ViewState = Partial<Pick<Diagram, 'settings' | 'camera' | 'theme' | 'collapsed'>>;
|
|
5
|
+
export declare function projectScene(scene: Scene, view?: ViewState): Diagram;
|
|
6
|
+
export interface CanonicalGeometry {
|
|
7
|
+
nodes: Array<{
|
|
8
|
+
id: string;
|
|
9
|
+
parent: string;
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
w: number;
|
|
13
|
+
h: number;
|
|
14
|
+
}>;
|
|
15
|
+
routes: Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
points: Array<{
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
}>;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
/** Rectangles for everything visible, as the canvas draws them. */
|
|
24
|
+
export declare function visibleRects(doc: Diagram): {
|
|
25
|
+
vg: import("../model/graph").VisibleGraph;
|
|
26
|
+
rects: Map<string, Rect>;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Node rectangles and route points for a projected document. Edge label positions are left out:
|
|
30
|
+
* the browser measures label text with real fonts, which Node cannot reproduce.
|
|
31
|
+
*/
|
|
32
|
+
export declare function canonicalGeometry(doc: Diagram): CanonicalGeometry;
|
|
33
|
+
export declare function measured(doc: Diagram, rects: Map<string, Rect>, routes: Array<{
|
|
34
|
+
id: string;
|
|
35
|
+
points: Array<{
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
}>;
|
|
39
|
+
}>): CanonicalGeometry;
|