reladraw 0.15.1 → 0.17.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/dist/model.d.ts CHANGED
@@ -1,23 +1,13 @@
1
- import type { Attrs, Axis, Direction, Kind, Mark, Placement } from './ast.js';
1
+ import type { Attrs, EdgeTextPlace, Kind, Mark, NodeCorners, Placement, PlacementTarget, ViaEntry, Way } from './ast.js';
2
+ /** A rectangle on the page; a side or a point has no size on one axis or both. */
3
+ export interface Rect {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ }
2
9
  import type { Line } from './text.js';
3
10
  import type { Body } from './icons.js';
4
- /** A `between` clause with its targets resolved. Mirrors `Passage` in `ast.ts`. */
5
- export interface LayoutPassage {
6
- nodes: [LayoutNode, LayoutNode];
7
- /** Which gap, where the pair has two. Absent when the pair leaves no doubt. */
8
- axis?: Axis;
9
- }
10
- /**
11
- * `below resolver` on an edge with its targets resolved: the line is on that
12
- * side of the box bounding `nodes`, where it passes them. Mirrors the edge's
13
- * `passes` in `ast.ts`.
14
- */
15
- export interface LayoutPass {
16
- direction: Direction;
17
- nodes: LayoutNode[];
18
- /** As the author wrote it, for error messages. */
19
- written: string;
20
- }
21
11
  /** A node with its geometry solved. Coordinates are absolute, origin top-left. */
22
12
  /** A distance past each side of a box. */
23
13
  export interface Reach {
@@ -35,23 +25,40 @@ export interface LayoutNode {
35
25
  * resolver, which sizes it, and the renderer, which draws it, cannot disagree.
36
26
  */
37
27
  body: Body;
28
+ /**
29
+ * How an outline's corners are drawn, from `corners:`. Only a rectangle's and
30
+ * a document's are read; drawing alone depends on it, never placement.
31
+ */
32
+ corners: NodeCorners;
38
33
  /** The text as written, before line splitting. */
39
34
  text: string;
40
35
  /** The text split into the lines that will be drawn, each as its runs. */
41
36
  lines: Line[];
42
37
  parent?: LayoutNode;
43
38
  children: LayoutNode[];
39
+ /**
40
+ * The child that is this box's heading (`heading:`): it sits where the title
41
+ * would, and the other children are arranged under it. It does not make the
42
+ * box a container to look at.
43
+ */
44
+ heading?: LayoutNode;
45
+ /**
46
+ * What this node moves with (`join-with:`, or the child `badge:` writes
47
+ * out): its container's text, or a sibling. Those joined to the text,
48
+ * directly or through each other, are one unit with it, placed by the text's
49
+ * position words (design.org 5.6).
50
+ */
51
+ joinWith?: LayoutNode | 'text';
52
+ /**
53
+ * Placements in the title's bracket, against the box's own children: what
54
+ * places the title on the axes they state, in place of its side words
55
+ * (design.org 7.2).
56
+ */
57
+ titlePlacements?: Placement[];
44
58
  x: number;
45
59
  y: number;
46
60
  width: number;
47
61
  height: number;
48
- /**
49
- * Distance from the node's outer box to its drawn face. Zero for everything
50
- * except a deck, where the offset copies sit in that margin.
51
- */
52
- inset: number;
53
- /** One text per copy behind this node, back to front. Empty for most nodes. */
54
- deckTexts: string[];
55
62
  /**
56
63
  * Vertical space this node's own text and icon occupy, at whichever end of
57
64
  * the box `text.at` puts them. Zero for leaves.
@@ -110,8 +117,82 @@ export interface LayoutNode {
110
117
  appearance: Attrs;
111
118
  /** What the author said about where it goes, kept so diagnostics can quote the source back. */
112
119
  placements: Placement[];
120
+ /** `guide node`: placed, holding and placed against as any node, drawn only when guides are shown. */
121
+ guide?: boolean;
113
122
  line: number;
114
123
  }
124
+ /**
125
+ * A named point or region, worked out on the page (design.org 4.5, 8.3). A
126
+ * point is a dot; a region a tinted rectangle, drawn behind what it names.
127
+ */
128
+ export interface LayoutMark {
129
+ kind: 'point' | 'region';
130
+ name: string;
131
+ x: number;
132
+ y: number;
133
+ width: number;
134
+ height: number;
135
+ /** The things its definition names, directly or through other points and regions. */
136
+ names: string[];
137
+ appearance: Attrs;
138
+ guide: boolean;
139
+ /** Its text, if it has one, and where that sits on the page (design.org 7.4). */
140
+ text?: MarkTextBox;
141
+ line: number;
142
+ }
143
+ /** A point's or a region's text, measured and placed. `box` is the turned ink when it reads up or down. */
144
+ export interface MarkTextBox {
145
+ lines: Line[];
146
+ textAttrs: Attrs;
147
+ size: number;
148
+ lineHeight: number;
149
+ box: Rect;
150
+ }
151
+ /** `depth: behind b, in front of c` on one thing, read into its clauses (design.org 8.4). */
152
+ export interface DepthStatement {
153
+ /** What moves: a node's or a mark's name, or `edge <n>` for the nth edge. */
154
+ subject: string;
155
+ /** The subject as written, for quoting back. */
156
+ written: string;
157
+ clauses: {
158
+ way: 'behind' | 'in front of';
159
+ /** What it moves against, as drawing-order keys: a name, or `edge <n>` for a named line. */
160
+ names: string[];
161
+ /** The same, as written, for quoting back. */
162
+ shown: string[];
163
+ /**
164
+ * Legs named, each with the key of the line it belongs to. A leg moves
165
+ * nothing in the sequence: it says which of two lines is on top where
166
+ * they cross on that leg, and nowhere else.
167
+ */
168
+ legs: {
169
+ leg: string;
170
+ line: string;
171
+ }[];
172
+ }[];
173
+ line: number;
174
+ }
175
+ /** One text on a line, measured, with what its bracket says about where it sits. */
176
+ export interface LayoutEdgeText {
177
+ text: string;
178
+ /** The text split into the lines that will be drawn, each as its runs. */
179
+ lines: Line[];
180
+ /** Its bracket's look, with a style's `text: (…)` underneath. */
181
+ textAttrs: Attrs;
182
+ place: EdgeTextPlace;
183
+ /** Its font size, and the size of its lines unturned. */
184
+ size: number;
185
+ width: number;
186
+ height: number;
187
+ /** Where the box a `straight … from` or a box relation names is, once placed. */
188
+ target?: Rect;
189
+ /** Where each `even with` in its bracket lines up, once placed: the axis, which part of the text, and what it lines up with. */
190
+ evenAt?: {
191
+ axis: 'x' | 'y';
192
+ side: 'start' | 'center' | 'end';
193
+ rect: Rect;
194
+ }[];
195
+ }
115
196
  export interface LayoutEdge {
116
197
  from: LayoutNode;
117
198
  to: LayoutNode;
@@ -120,23 +201,67 @@ export interface LayoutEdge {
120
201
  from: Mark;
121
202
  to: Mark;
122
203
  };
123
- text?: string;
124
- /** The text split into the lines that will be drawn, each as its runs. */
125
- lines?: Line[];
126
- /** The text's bracketed modifiers, with a style's `text: (…)` underneath. */
127
- textAttrs: Attrs;
204
+ /** Its texts in written order, measured; where each goes is worked out once the line is drawn (`linetexts.ts`). */
205
+ texts: LayoutEdgeText[];
206
+ /** The arrow as written, for quoting the edge back: `a -> b`. */
207
+ arrow: string;
208
+ /** `edge req client -> api`: the line's own name, for other statements to refer to. */
209
+ name?: string;
210
+ /** The places the line passes, as written (design.org 6.4). */
211
+ via?: ViaEntry[];
212
+ /**
213
+ * Where each `via:` stop that names something placed is on the page, worked
214
+ * out by the placer once everything is placed: a box, a side, a point or a
215
+ * region. Absent for a stop on a line or beside a leg, which `lines.ts`
216
+ * works out from the lines themselves. Same order as `via`.
217
+ */
218
+ viaAt?: (Rect | undefined)[];
219
+ /** `straight down`: leaving its start that way from the center, and ending where that meets the far end (6.2). */
220
+ straight?: Way;
221
+ /** `to: left, even with cat1`: what each end is even with, as written (6.2). */
222
+ evenWith?: {
223
+ from?: PlacementTarget[];
224
+ to?: PlacementTarget[];
225
+ };
128
226
  /**
129
- * The gap a `between` clause named, with its two nodes resolved. Nothing in
130
- * the resolver uses this — a corridor is measured off the solved layout
131
- * rather than solved for, so edges stay out of the constraint system entirely.
227
+ * Where each end's `even with` thing is on the page, worked out by the
228
+ * placer: a box, a side, a point or the region round several. Its center
229
+ * gives the end's height, or its place across.
132
230
  */
133
- between?: LayoutPassage;
134
- /** Which side of which nodes the line passes. Measured in the renderer, like `between`. */
135
- passes?: LayoutPass[];
231
+ evenAt?: {
232
+ from?: Rect;
233
+ to?: Rect;
234
+ };
235
+ /** An end on another line (`edge log audit -> req`): the line it is on, for that end. */
236
+ onLine?: {
237
+ from?: LayoutEdge;
238
+ to?: LayoutEdge;
239
+ };
240
+ /** An end at a named point or region (`edge a -> b` between two points): which kind, for that end. */
241
+ onMark?: {
242
+ from?: 'point' | 'region';
243
+ to?: 'point' | 'region';
244
+ };
136
245
  /** What the line's bracket says, checked and with every default filled in. */
137
246
  look: LineLook;
138
247
  attrs: Attrs;
139
248
  appearance: Attrs;
249
+ /** `guide edge`: drawn only when guides are shown. */
250
+ guide?: boolean;
251
+ /**
252
+ * A `bundle` statement: a line with no ends, whose path is its `via:` list
253
+ * alone, and which other lines travel along (design.org 6.6). Its `from` and
254
+ * `to` are placeholders named after it. A parallel bundle is drawn only with
255
+ * the guides; a collapsed one is drawn, as the bus. A bundle written
256
+ * `a -> b` has no path: `between` holds its two boxes, and its members are
257
+ * drawn straight from one to the other.
258
+ */
259
+ bundle?: {
260
+ arrangement: 'parallel' | 'collapsed' | 'fan';
261
+ gap: number;
262
+ order?: string[];
263
+ between?: [LayoutNode, LayoutNode];
264
+ };
140
265
  line: number;
141
266
  }
142
267
  /**
@@ -150,6 +275,18 @@ export interface LineLook {
150
275
  pattern: 'solid' | 'dashed' | 'dotted' | 'dash-dot';
151
276
  /** In pixels. */
152
277
  thickness: number;
278
+ /** How widely a curved line swings between its points. */
279
+ curve: 'normal' | 'strong' | 'subtle';
280
+ /**
281
+ * Where the free leg sits, a fraction of the way from the start's box (6.3).
282
+ * Undefined where nothing says: a square line's leg sits halfway, and a
283
+ * curved line takes one free sweep.
284
+ */
285
+ turn: number | undefined;
286
+ /** `turn:` as written on the edge itself, refused where it places nothing; from a style or a default it is undefined. */
287
+ turnWritten: string | undefined;
288
+ /** The short first and last leg of a square or curved line, in pixels. */
289
+ stepOut: number;
153
290
  }
154
291
  export interface Layout {
155
292
  /** Every node, containers and children alike, in declaration order. */
@@ -177,4 +314,18 @@ export interface Layout {
177
314
  * a `top` side does exactly that, and the canvas has to grow to hold it.
178
315
  */
179
316
  margin: number;
317
+ /** Named points and regions, in the order written. */
318
+ marks: LayoutMark[];
319
+ /** Every `depth:`, in the order written. */
320
+ depths: DepthStatement[];
321
+ /** How a shown guide of each kind looks: `default guide node` and the rest. */
322
+ guideLooks: Record<'node' | 'edge' | 'point' | 'region', Attrs>;
180
323
  }
324
+ /**
325
+ * Whether a node is joined to its container's text, directly or through
326
+ * siblings joined to it: one unit with the text, placed by the text's position
327
+ * words (design.org 5.6).
328
+ */
329
+ export declare function joinedToText(node: LayoutNode): boolean;
330
+ /** Whether a node is inside another, at any depth. */
331
+ export declare function isWithin(node: LayoutNode, ancestor: LayoutNode): boolean;
package/dist/model.js CHANGED
@@ -1 +1,23 @@
1
- export {};
1
+ /**
2
+ * Whether a node is joined to its container's text, directly or through
3
+ * siblings joined to it: one unit with the text, placed by the text's position
4
+ * words (design.org 5.6).
5
+ */
6
+ export function joinedToText(node) {
7
+ const seen = new Set();
8
+ for (let at = node; at && !seen.has(at);) {
9
+ seen.add(at);
10
+ const target = at.joinWith;
11
+ if (target === 'text')
12
+ return true;
13
+ at = target;
14
+ }
15
+ return false;
16
+ }
17
+ /** Whether a node is inside another, at any depth. */
18
+ export function isWithin(node, ancestor) {
19
+ for (let at = node.parent; at; at = at.parent)
20
+ if (at === ancestor)
21
+ return true;
22
+ return false;
23
+ }