@promptctl/rich-js 0.28.0 → 0.29.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 +7 -7
- package/dist/core/animation.d.ts +37 -37
- package/dist/core/animation.js +61 -61
- package/dist/core/ansi.d.ts +4 -4
- package/dist/core/ansi.js +9 -9
- package/dist/core/bidi.js +6 -6
- package/dist/core/cells.d.ts +1 -1
- package/dist/core/cells.js +5 -5
- package/dist/core/clock.d.ts +1 -1
- package/dist/core/color.d.ts +50 -50
- package/dist/core/color.js +69 -69
- package/dist/core/console.d.ts +8 -8
- package/dist/core/console.js +5 -5
- package/dist/core/control-codes.d.ts +3 -3
- package/dist/core/control-codes.js +7 -7
- package/dist/core/easing.d.ts +40 -40
- package/dist/core/easing.js +40 -40
- package/dist/core/env.d.ts +1 -1
- package/dist/core/env.js +1 -1
- package/dist/core/export-html.js +1 -1
- package/dist/core/export-lines.d.ts +11 -11
- package/dist/core/export-lines.js +12 -12
- package/dist/core/export-svg.d.ts +3 -3
- package/dist/core/export-svg.js +4 -4
- package/dist/core/markup.js +1 -1
- package/dist/core/memo.d.ts +1 -1
- package/dist/core/memo.js +1 -1
- package/dist/core/oklch.d.ts +14 -14
- package/dist/core/oklch.js +10 -10
- package/dist/core/orient.d.ts +3 -3
- package/dist/core/orient.js +3 -3
- package/dist/core/paint.d.ts +9 -9
- package/dist/core/paint.js +3 -3
- package/dist/core/pretty.d.ts +1 -1
- package/dist/core/pretty.js +3 -3
- package/dist/core/protocol.d.ts +26 -26
- package/dist/core/protocol.js +22 -22
- package/dist/core/render.d.ts +11 -11
- package/dist/core/render.js +12 -12
- package/dist/core/segment.d.ts +3 -3
- package/dist/core/segment.js +5 -5
- package/dist/core/strip.d.ts +83 -83
- package/dist/core/strip.js +70 -70
- package/dist/core/style.d.ts +20 -20
- package/dist/core/style.js +55 -55
- package/dist/core/text.d.ts +2 -2
- package/dist/core/text.js +5 -5
- package/dist/core/timeline.d.ts +5 -5
- package/dist/core/timeline.js +9 -9
- package/dist/core/tween.d.ts +6 -6
- package/dist/core/tween.js +10 -10
- package/dist/core/view.d.ts +4 -4
- package/dist/core/view.js +12 -12
- package/dist/host/app.d.ts +9 -9
- package/dist/host/app.js +12 -12
- package/dist/host/host-environment.d.ts +2 -2
- package/dist/host/host-environment.js +2 -2
- package/dist/host/index.d.ts +2 -2
- package/dist/host/input.d.ts +7 -7
- package/dist/host/input.js +4 -4
- package/dist/host/terminal-colors.d.ts +2 -2
- package/dist/host/terminal-colors.js +4 -4
- package/dist/host/terminal-host.d.ts +2 -2
- package/dist/host/terminal-host.js +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.js +10 -10
- package/dist/node/prompt.d.ts +1 -1
- package/dist/node/prompt.js +1 -1
- package/dist/node/terminal-host.d.ts +1 -1
- package/dist/node/traceback.js +2 -2
- package/dist/renderables/change.js +2 -2
- package/dist/renderables/effect.d.ts +39 -39
- package/dist/renderables/effect.js +45 -45
- package/dist/renderables/effects.d.ts +81 -81
- package/dist/renderables/effects.js +157 -157
- package/dist/renderables/embed.d.ts +1 -1
- package/dist/renderables/embed.js +2 -2
- package/dist/renderables/flexStrip.d.ts +7 -7
- package/dist/renderables/flexStrip.js +15 -15
- package/dist/renderables/frames.d.ts +6 -6
- package/dist/renderables/frames.js +11 -11
- package/dist/renderables/glyph-effect.d.ts +15 -15
- package/dist/renderables/glyph-effect.js +17 -17
- package/dist/renderables/glyph-effects.d.ts +7 -7
- package/dist/renderables/glyph-effects.js +16 -16
- package/dist/renderables/html-entities.d.ts +1 -1
- package/dist/renderables/html-entities.js +1 -1
- package/dist/renderables/lifecycle.d.ts +4 -4
- package/dist/renderables/lifecycle.js +12 -12
- package/dist/renderables/live.d.ts +2 -2
- package/dist/renderables/live.js +7 -7
- package/dist/renderables/markdown-parse.js +3 -3
- package/dist/renderables/panel.js +3 -3
- package/dist/renderables/progress.d.ts +1 -1
- package/dist/renderables/progress.js +1 -1
- package/dist/renderables/progressBar.d.ts +1 -1
- package/dist/renderables/progressBar.js +6 -6
- package/dist/renderables/prompt.d.ts +1 -1
- package/dist/renderables/scroll.d.ts +1 -1
- package/dist/renderables/scroll.js +3 -3
- package/dist/renderables/spinner.d.ts +4 -4
- package/dist/renderables/spinner.js +10 -10
- package/dist/renderables/syntax.d.ts +2 -2
- package/dist/renderables/syntax.js +2 -2
- package/dist/renderables/table.js +3 -3
- package/dist/renderables/traceback.d.ts +1 -1
- package/dist/renderables/traceback.js +1 -1
- package/dist/renderables/tree.js +3 -3
- package/dist/template-bindings/animation-funcs.d.ts +14 -14
- package/dist/template-bindings/animation-funcs.js +27 -27
- package/dist/template-bindings/color-funcs.d.ts +14 -14
- package/dist/template-bindings/color-funcs.js +25 -25
- package/dist/template-bindings/index.d.ts +9 -9
- package/dist/template-bindings/index.js +9 -9
- package/dist/template-bindings/palette-funcs.d.ts +1 -1
- package/dist/template-bindings/palette-funcs.js +3 -3
- package/dist/template-bindings/style-funcs.d.ts +5 -5
- package/dist/template-bindings/style-funcs.js +16 -16
- package/dist/themes/{transpose.d.ts → adjust.d.ts} +23 -23
- package/dist/themes/{transpose.js → adjust.js} +28 -28
- package/dist/themes/buildPalette.d.ts +3 -3
- package/dist/themes/buildPalette.js +20 -20
- package/dist/themes/colorMath.d.ts +16 -16
- package/dist/themes/colorMath.js +32 -32
- package/dist/themes/data/ansi-tables.d.ts +2 -2
- package/dist/themes/data/ansi-tables.js +2 -2
- package/dist/themes/data/types.d.ts +4 -4
- package/dist/themes/data/types.js +2 -2
- package/dist/themes/palette.d.ts +12 -12
- package/dist/themes/palette.js +16 -16
- package/dist/themes/ramp.d.ts +17 -17
- package/dist/themes/ramp.js +12 -12
- package/dist/themes/registry.js +4 -4
- package/dist/themes/terminalThemes.d.ts +1 -1
- package/dist/themes/terminalThemes.js +1 -1
- package/dist/widgets/button.d.ts +2 -2
- package/dist/widgets/button.js +4 -4
- package/dist/widgets/checkbox.d.ts +2 -2
- package/dist/widgets/checkbox.js +2 -2
- package/dist/widgets/dropdown.d.ts +2 -2
- package/dist/widgets/dropdown.js +3 -3
- package/dist/widgets/event-router.d.ts +6 -6
- package/dist/widgets/event-router.js +2 -2
- package/dist/widgets/focus-manager.d.ts +3 -3
- package/dist/widgets/focus-manager.js +3 -3
- package/dist/widgets/index.d.ts +2 -2
- package/dist/widgets/index.js +1 -1
- package/dist/widgets/ink.d.ts +3 -3
- package/dist/widgets/ink.js +4 -4
- package/dist/widgets/slider.d.ts +2 -2
- package/dist/widgets/static-item.d.ts +2 -2
- package/dist/widgets/text-input.d.ts +2 -2
- package/dist/widgets/text-input.js +5 -5
- package/dist/widgets/themed-widget.js +1 -1
- package/dist/widgets/toggle.d.ts +3 -3
- package/dist/widgets/toggle.js +3 -3
- package/dist/widgets/types.d.ts +6 -6
- package/dist/widgets/types.js +2 -2
- package/dist/widgets/widget-app.d.ts +10 -10
- package/dist/widgets/widget-app.js +8 -8
- package/dist/widgets/widget-base.d.ts +2 -2
- package/package.json +1 -1
package/dist/core/strip.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Strip +
|
|
2
|
+
* Strip + Separator — edge-aware horizontal layout primitive.
|
|
3
3
|
*
|
|
4
|
-
* A `Strip` renders a horizontal sequence of styled items with a `
|
|
4
|
+
* A `Strip` renders a horizontal sequence of styled items with a `Separator`
|
|
5
5
|
* deciding how each transition between adjacent items looks. The joiner is
|
|
6
6
|
* a pure function of `(leftItem | null, rightItem | null) -> Renderable`,
|
|
7
7
|
* so endpoint joins (the start and end of the strip) are explicit positions
|
|
@@ -34,22 +34,22 @@ import { fnv1a } from "./fnv1a.js";
|
|
|
34
34
|
import { drawable, getStyle, isAscii, render } from "./protocol.js";
|
|
35
35
|
/**
|
|
36
36
|
* The owner every cell a strip's joiner draws is stamped with
|
|
37
|
-
* (`Segment.anchorLines`), whatever the
|
|
37
|
+
* (`Segment.anchorLines`), whatever the separator: a seam is told by what drew
|
|
38
38
|
* it, never by its glyph, which an ASCII joiner draws otherwise and a lead may
|
|
39
39
|
* not draw at all. An effect reads it to leave a seam out of the words it
|
|
40
40
|
* keeps legible (`drawnOf`, `../renderables/effect.ts`).
|
|
41
41
|
*
|
|
42
|
-
* Inside it, every cell a `
|
|
42
|
+
* Inside it, every cell a `CellSeparator` draws is stamped with what it was
|
|
43
43
|
* resolved from (`JoinedCell`), so a cell whose neighbours an effect moves is
|
|
44
44
|
* resolved again from where they moved to.
|
|
45
45
|
*/
|
|
46
46
|
export const JOIN = Object.freeze({ name: "join" });
|
|
47
47
|
/**
|
|
48
|
-
* [LAW:single-enforcer] What `
|
|
48
|
+
* [LAW:single-enforcer] What `separator` draws at one join, every cell stamped
|
|
49
49
|
* as `JOIN`'s: the one way `Strip` and `FlexStrip` draw a join.
|
|
50
50
|
*/
|
|
51
|
-
export function drawJoin(
|
|
52
|
-
const join =
|
|
51
|
+
export function drawJoin(separator, left, right, context) {
|
|
52
|
+
const join = separator.join(left, right, context);
|
|
53
53
|
return { render: (options) => Segment.anchorLines([[...render(join, options)]], JOIN)[0] };
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
@@ -64,10 +64,10 @@ export function drawItem(item) {
|
|
|
64
64
|
// --- Strip ---
|
|
65
65
|
export class Strip {
|
|
66
66
|
items;
|
|
67
|
-
|
|
68
|
-
constructor(items,
|
|
67
|
+
separator;
|
|
68
|
+
constructor(items, separator) {
|
|
69
69
|
this.items = items;
|
|
70
|
-
this.
|
|
70
|
+
this.separator = separator;
|
|
71
71
|
}
|
|
72
72
|
*render(options) {
|
|
73
73
|
const items = this.items;
|
|
@@ -82,12 +82,12 @@ export class Strip {
|
|
|
82
82
|
// `left` fills the canvas, and the first item would pad over the rest of
|
|
83
83
|
// the row. Where the row sits in the width is its container's to say.
|
|
84
84
|
const row = { ...options, justify: undefined };
|
|
85
|
-
yield* render(drawJoin(this.
|
|
85
|
+
yield* render(drawJoin(this.separator, null, items[0], { index: 0 }), row);
|
|
86
86
|
for (let i = 0; i < items.length; i++) {
|
|
87
87
|
const item = items[i];
|
|
88
88
|
yield* render(drawItem(item), row);
|
|
89
89
|
const next = i + 1 < items.length ? items[i + 1] : null;
|
|
90
|
-
yield* render(drawJoin(this.
|
|
90
|
+
yield* render(drawJoin(this.separator, item, next, { index: i + 1 }), row);
|
|
91
91
|
}
|
|
92
92
|
// [LAW:one-source-of-truth] `Strip`'s sibling `FlexStrip` ends every line
|
|
93
93
|
// it emits, including the last, and the other block-level renderables
|
|
@@ -144,7 +144,7 @@ const cellWidth = (cell) => cellLen(glyphsOf(cell)[0] ?? "");
|
|
|
144
144
|
// name, because the part is also drawn where that neighbour does not exist.
|
|
145
145
|
function parsePaint(raw, absent, refuse) {
|
|
146
146
|
if (raw === "ground")
|
|
147
|
-
return refuse("mixes ground, whose
|
|
147
|
+
return refuse("mixes ground, whose color is unknown");
|
|
148
148
|
const p = (typeof raw === "object" && raw !== null ? raw : {});
|
|
149
149
|
if ((p.edge === "left" || p.edge === "right") && (p.part === "bg" || p.part === "fg")) {
|
|
150
150
|
if (p.edge === absent)
|
|
@@ -159,7 +159,7 @@ function parsePaint(raw, absent, refuse) {
|
|
|
159
159
|
refuse(`mixes at ${String(t)}, outside 0..1`);
|
|
160
160
|
return Object.freeze({ mix: Object.freeze([parsePaint(from, absent, refuse), parsePaint(to, absent, refuse), t]) });
|
|
161
161
|
}
|
|
162
|
-
return refuse(`has a
|
|
162
|
+
return refuse(`has a color that is not a Paint: ${JSON.stringify(raw)}`);
|
|
163
163
|
}
|
|
164
164
|
const parseColor = (raw, absent, refuse) => raw === "ground" ? raw : parsePaint(raw, absent, refuse);
|
|
165
165
|
const ABSENT = { seam: undefined, lead: "left", tail: "right" };
|
|
@@ -248,8 +248,8 @@ function formOf(shape) {
|
|
|
248
248
|
cells: { seam: cells("seam"), lead: cells("lead"), tail: cells("tail") },
|
|
249
249
|
};
|
|
250
250
|
}
|
|
251
|
-
// A bg with a real
|
|
252
|
-
// DEFAULT
|
|
251
|
+
// A bg with a real color to paint. `undefined` (no bg) and the terminal
|
|
252
|
+
// DEFAULT color (transparent — identical to the terminal background) are the
|
|
253
253
|
// two representations of "nothing to paint", so an explicit `… on default`
|
|
254
254
|
// cannot smuggle a seam.
|
|
255
255
|
function paintableBg(bg) {
|
|
@@ -262,13 +262,13 @@ function drawnGround(bg) {
|
|
|
262
262
|
return bg.flattenAlpha(SURFACE_BLACK);
|
|
263
263
|
}
|
|
264
264
|
// Whether ink stands off its ground, both as a depth draws them, by the floor a
|
|
265
|
-
// seam is seen at. A
|
|
265
|
+
// seam is seen at. A color whose RGB is the terminal theme's own (ANSI 0–15, a
|
|
266
266
|
// blend reaching one) has no value here, so two of them stand apart unless they
|
|
267
267
|
// are one expression: the same palette slot — its `number`, never the name or
|
|
268
268
|
// the depth that spells it ("red", "color(1)", an EIGHT_BIT spec on 0–15 are
|
|
269
269
|
// one slot) — or the same blend, whose name spells each end by its slot for the
|
|
270
|
-
// same reason. At sixteen
|
|
271
|
-
// terminal's default
|
|
270
|
+
// same reason. At sixteen colors, then, the floor is a different slot. The
|
|
271
|
+
// terminal's default color is nobody's to measure, and stands apart.
|
|
272
272
|
function standsOff(ink, ground) {
|
|
273
273
|
if (ink.isDefault || ground.isDefault)
|
|
274
274
|
return true;
|
|
@@ -277,7 +277,7 @@ function standsOff(ink, ground) {
|
|
|
277
277
|
? Oklch.fromRgba(a).deltaE(Oklch.fromRgba(b)) >= SEAM_MIN_DELTA_E
|
|
278
278
|
: ink.number !== undefined ? ink.number !== ground.number : ink.name !== ground.name;
|
|
279
279
|
}
|
|
280
|
-
// A step along a lightness ray: finer than the steps between the
|
|
280
|
+
// A step along a lightness ray: finer than the steps between the colors a
|
|
281
281
|
// truecolor writer draws, so the walk passes over none of them.
|
|
282
282
|
const LIFT_STEP = 0.001;
|
|
283
283
|
// The steps along `origin`'s lightness ray, its chroma and hue held, in the
|
|
@@ -292,21 +292,21 @@ function* lightnessRay(origin) {
|
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
/**
|
|
295
|
-
* `ink`, a glyph's
|
|
295
|
+
* `ink`, a glyph's color on `ground`, held at least `SEAM_MIN_DELTA_E` off it
|
|
296
296
|
* as `depth` draws both (`Style.drawnColors`). Ink that already stands off is
|
|
297
297
|
* returned as it is. Ink that does not becomes the drawn form of the nearest
|
|
298
298
|
* step along its own OKLCH lightness ray, chroma and hue held, that stands off:
|
|
299
299
|
* the smaller step, toward white or toward black. Every step is measured as the
|
|
300
|
-
* depth draws it, so at 256
|
|
300
|
+
* depth draws it, so at 256 colors and at sixteen the candidates are the
|
|
301
301
|
* entries the depth draws, and the side the ink moves to can differ between
|
|
302
|
-
* depths. A floor measured on rounded
|
|
303
|
-
* the walk enumerates and never bisects. A side with no
|
|
302
|
+
* depths. A floor measured on rounded colors is not monotone along a ray, so
|
|
303
|
+
* the walk enumerates and never bisects. A side with no color to measure is
|
|
304
304
|
* left alone.
|
|
305
305
|
*
|
|
306
|
-
* [LAW:one-source-of-truth] The
|
|
306
|
+
* [LAW:one-source-of-truth] The color returned is the one measured — the
|
|
307
307
|
* entry the depth draws, not the step that rounds to it — so a reader of the
|
|
308
308
|
* cell at another depth (an export reads a recording in truecolor) sees the
|
|
309
|
-
*
|
|
309
|
+
* color that cleared the floor, never a step one unit off its ground.
|
|
310
310
|
*
|
|
311
311
|
* [LAW:single-enforcer] The one place a join cell's visibility is decided:
|
|
312
312
|
* nothing outside the joiner predicts whether a seam will show.
|
|
@@ -319,14 +319,14 @@ function standOff(ink, ground, depth) {
|
|
|
319
319
|
if (standsOff(shown, under))
|
|
320
320
|
return ink;
|
|
321
321
|
// The ray starts from the ink as it is laid on its ground, before a depth
|
|
322
|
-
// rounds it; ink the terminal's theme draws starts from the
|
|
322
|
+
// rounds it; ink the terminal's theme draws starts from the color the
|
|
323
323
|
// default terminal theme gives it. Ink that vanishes is drawn in the same
|
|
324
324
|
// kind as its ground — both fixed, or both the theme's — and every step is
|
|
325
325
|
// drawn in that kind too, so it is measured as the ink was. Ink the depth
|
|
326
326
|
// draws as the theme's (a slot, or a mix reaching one at truecolor) steps
|
|
327
|
-
// between slots: an RGB beside a
|
|
328
|
-
// that very
|
|
329
|
-
// 256) steps between fixed
|
|
327
|
+
// between slots: an RGB beside a color only the terminal knows could be
|
|
328
|
+
// that very color. Ink the depth fixes (that same mix is a cube entry at
|
|
329
|
+
// 256) steps between fixed colors, for the same reason turned round.
|
|
330
330
|
const laid = drawn(ink).color;
|
|
331
331
|
const kind = shown.fixedValue === undefined ? ColorDepth.STANDARD : ColorDepth.TRUECOLOR;
|
|
332
332
|
for (const step of lightnessRay(Oklch.fromRgba(laid.getTruecolor()))) {
|
|
@@ -336,7 +336,7 @@ function standOff(ink, ground, depth) {
|
|
|
336
336
|
}
|
|
337
337
|
// [LAW:no-silent-failure] Unreachable: the ray runs out to black and to
|
|
338
338
|
// white, and no ground lies within the floor of both, nor is one slot both.
|
|
339
|
-
throw new Error(`no
|
|
339
|
+
throw new Error(`no color on the lightness ray of ${ink.name} stands off ${ground.name} at depth ${ColorDepth[depth]}`);
|
|
340
340
|
}
|
|
341
341
|
function resolvePaint(paint, edges, options) {
|
|
342
342
|
if ("edge" in paint) {
|
|
@@ -351,15 +351,15 @@ function resolvePaint(paint, edges, options) {
|
|
|
351
351
|
const [from, to, t] = paint.mix;
|
|
352
352
|
const a = resolvePaint(from, edges, options);
|
|
353
353
|
const b = resolvePaint(to, edges, options);
|
|
354
|
-
// A mix with no
|
|
354
|
+
// A mix with no color at one end has nothing to blend toward.
|
|
355
355
|
return a && b && ColorSpec.blend(a, b, t);
|
|
356
356
|
}
|
|
357
357
|
// [LAW:single-enforcer] The one resolution of a join cell's paints: at join
|
|
358
358
|
// time, and again whenever an effect moves the neighbours it reads
|
|
359
359
|
// (`JoinedCell`).
|
|
360
360
|
function cellStyle(cell, edges, options) {
|
|
361
|
-
// [LAW:dataflow-not-control-flow] "ground" is the absence of a
|
|
362
|
-
// side; as the fg it is reverse video over the bg
|
|
361
|
+
// [LAW:dataflow-not-control-flow] "ground" is the absence of a color on its
|
|
362
|
+
// side; as the fg it is reverse video over the bg color, so the glyph's ink
|
|
363
363
|
// is the terminal's own background.
|
|
364
364
|
if (cell.fg === "ground")
|
|
365
365
|
return new Style({ color: cell.bg === "ground" ? undefined : resolvePaint(cell.bg, edges, options), reverse: true });
|
|
@@ -369,19 +369,19 @@ function cellStyle(cell, edges, options) {
|
|
|
369
369
|
return new Style({ color: standOff(resolvePaint(cell.fg, edges, options), bgcolor, options.colorSystem ?? ColorDepth.TRUECOLOR), bgcolor });
|
|
370
370
|
}
|
|
371
371
|
/**
|
|
372
|
-
* A cell a `
|
|
372
|
+
* A cell a `CellSeparator` drew, as what it is: one function of its two
|
|
373
373
|
* neighbours' edges. It holds the cell's paints, the neighbour each side of
|
|
374
374
|
* them reads, and the edges and render it was resolved from, and it is stamped
|
|
375
375
|
* on the cell as the owner of its innermost anchor level.
|
|
376
376
|
*
|
|
377
|
-
* [LAW:one-source-of-truth] A seam's
|
|
377
|
+
* [LAW:one-source-of-truth] A seam's colors are its neighbours', so nothing
|
|
378
378
|
* paints them but this resolution. An effect paints a strip's items and never
|
|
379
379
|
* a join cell that `follows` them; once the items are painted, each such cell
|
|
380
380
|
* is handed what moved at the item cells beside it and resolved again through
|
|
381
381
|
* `cellStyle`, the path the join was drawn by, lift included
|
|
382
382
|
* (`../renderables/effect.ts`). A seam then follows its neighbours wherever an
|
|
383
383
|
* effect takes them, a mix of the two included, and an effect that paints
|
|
384
|
-
* both one
|
|
384
|
+
* both one color leaves the seam's ink lifted off it. A cell painted from
|
|
385
385
|
* roles and the terminal's ground alone, as `plain`'s separator is, follows
|
|
386
386
|
* nobody, and an effect paints it as it paints any cell.
|
|
387
387
|
*/
|
|
@@ -439,7 +439,7 @@ export class JoinedCell {
|
|
|
439
439
|
return { colors: next.style, style: style.withAnchor(style.anchor && restamp(style.anchor)) };
|
|
440
440
|
}
|
|
441
441
|
}
|
|
442
|
-
/** The record a `
|
|
442
|
+
/** The record a `CellSeparator` stamped on the cell `anchor` names, or none for a cell no `CellSeparator` drew. */
|
|
443
443
|
export function joinedCell(anchor) {
|
|
444
444
|
for (let level = anchor; level; level = level.inner)
|
|
445
445
|
if (level.owner instanceof JoinedCell)
|
|
@@ -448,8 +448,8 @@ export function joinedCell(anchor) {
|
|
|
448
448
|
}
|
|
449
449
|
const shapeGlyphs = (shape) => PARTS.flatMap((part) => shape[part].flatMap(glyphsOf)).join("");
|
|
450
450
|
/**
|
|
451
|
-
* The one
|
|
452
|
-
* `
|
|
451
|
+
* The one separator: what it draws is a `SeparatorSeam` between neighbours and a
|
|
452
|
+
* `EndCaps` at the ends of each run, picked independently, so a new joiner is
|
|
453
453
|
* a pair of values, never a class.
|
|
454
454
|
*
|
|
455
455
|
* Which part a join draws is read off its two neighbours. A neighbour is
|
|
@@ -464,7 +464,7 @@ const shapeGlyphs = (shape) => PARTS.flatMap((part) => shape[part].flatMap(glyph
|
|
|
464
464
|
*
|
|
465
465
|
* An ASCII-only output draws the `ascii` form of both, whole.
|
|
466
466
|
*/
|
|
467
|
-
export class
|
|
467
|
+
export class CellSeparator {
|
|
468
468
|
seam;
|
|
469
469
|
caps;
|
|
470
470
|
_forms;
|
|
@@ -545,7 +545,7 @@ const rail = (glyph) => ({ glyph, fg: { role: "strip.rail" }, bg: GROUND });
|
|
|
545
545
|
* What each draws is `docs/strip.md`'s "Seams"; any of them ends in any of
|
|
546
546
|
* `CAPS`.
|
|
547
547
|
*/
|
|
548
|
-
export const
|
|
548
|
+
export const SEPARATORS = Object.freeze({
|
|
549
549
|
powerline: parseSeam(arrowSeam(POWERLINE)),
|
|
550
550
|
prism: parseSeam(both(prism(POWERLINE.glyph), prism(POWERLINE.ascii))),
|
|
551
551
|
slant: parseSeam(arrowSeam(SLANT)),
|
|
@@ -575,9 +575,9 @@ const FLAT = { lead: [], tail: [] };
|
|
|
575
575
|
/**
|
|
576
576
|
* The bundled caps, by name: what a joiner draws where a run begins and ends.
|
|
577
577
|
* What each draws is `docs/strip.md`'s "Caps"; any of them ends any of
|
|
578
|
-
* `
|
|
578
|
+
* `SEPARATORS`.
|
|
579
579
|
*/
|
|
580
|
-
export const
|
|
580
|
+
export const END_CAPS = Object.freeze({
|
|
581
581
|
powerline: parseCaps(flowCaps(POWERLINE)),
|
|
582
582
|
slant: parseCaps(flowCaps(SLANT)),
|
|
583
583
|
backslant: parseCaps(flowCaps(BACKSLANT)),
|
|
@@ -590,37 +590,37 @@ export const CAPS = Object.freeze({
|
|
|
590
590
|
flat: parseCaps(both(FLAT, FLAT)),
|
|
591
591
|
});
|
|
592
592
|
/**
|
|
593
|
-
* The bundled joiners, by name: each a seam from `
|
|
593
|
+
* The bundled joiners, by name: each a seam from `SEPARATORS` ended in caps from
|
|
594
594
|
* `CAPS`. What each draws is `docs/strip.md`'s "Built-in joiners"; a name from
|
|
595
|
-
* config is read with `
|
|
595
|
+
* config is read with `separatorNamed`.
|
|
596
596
|
*/
|
|
597
|
-
export const
|
|
598
|
-
powerline: new
|
|
599
|
-
prism: new
|
|
600
|
-
slant: new
|
|
601
|
-
backslant: new
|
|
602
|
-
flame: new
|
|
603
|
-
pixel: new
|
|
604
|
-
ice: new
|
|
605
|
-
bubble: new
|
|
606
|
-
capsule: new
|
|
607
|
-
wrapper: new
|
|
608
|
-
metro: new
|
|
609
|
-
stitch: new
|
|
610
|
-
torn: new
|
|
611
|
-
plain: new
|
|
597
|
+
export const SEPARATOR_STYLES = Object.freeze({
|
|
598
|
+
powerline: new CellSeparator(SEPARATORS.powerline, END_CAPS.powerline),
|
|
599
|
+
prism: new CellSeparator(SEPARATORS.prism, END_CAPS.powerline),
|
|
600
|
+
slant: new CellSeparator(SEPARATORS.slant, END_CAPS.slant),
|
|
601
|
+
backslant: new CellSeparator(SEPARATORS.backslant, END_CAPS.backslant),
|
|
602
|
+
flame: new CellSeparator(SEPARATORS.flame, END_CAPS.flame),
|
|
603
|
+
pixel: new CellSeparator(SEPARATORS.pixel, END_CAPS.pixel),
|
|
604
|
+
ice: new CellSeparator(SEPARATORS.ice, END_CAPS.ice),
|
|
605
|
+
bubble: new CellSeparator(SEPARATORS.bubble, END_CAPS.bubble),
|
|
606
|
+
capsule: new CellSeparator(SEPARATORS.capsule, END_CAPS.capsule),
|
|
607
|
+
wrapper: new CellSeparator(SEPARATORS.wrapper, END_CAPS.wrapper),
|
|
608
|
+
metro: new CellSeparator(SEPARATORS.metro, END_CAPS.capsule),
|
|
609
|
+
stitch: new CellSeparator(SEPARATORS.stitch, END_CAPS.flat),
|
|
610
|
+
torn: new CellSeparator(SEPARATORS.torn, END_CAPS.flat),
|
|
611
|
+
plain: new CellSeparator(SEPARATORS.plain, END_CAPS.flat),
|
|
612
612
|
});
|
|
613
613
|
/**
|
|
614
614
|
* The joiner `spec` names — a joiner read from config, parsed. Throws on a
|
|
615
615
|
* name its table lacks, naming the ones there are; an own-key test, so
|
|
616
616
|
* `toString` and the rest of `Object.prototype` are no one's name.
|
|
617
617
|
*/
|
|
618
|
-
export function
|
|
618
|
+
export function separatorNamed(spec) {
|
|
619
619
|
if (typeof spec === "string")
|
|
620
|
-
return named(
|
|
620
|
+
return named(SEPARATOR_STYLES, "separator", "separators", spec);
|
|
621
621
|
if (typeof spec !== "object" || spec === null)
|
|
622
|
-
throw new Error(`a
|
|
623
|
-
return new
|
|
622
|
+
throw new Error(`a separator is a name or { seam, caps }, not ${JSON.stringify(spec)}`);
|
|
623
|
+
return new CellSeparator(named(SEPARATORS, "seam", "seams", spec.seam), named(END_CAPS, "caps", "caps", spec.caps));
|
|
624
624
|
}
|
|
625
625
|
function named(table, kind, kinds, name) {
|
|
626
626
|
if (!Object.hasOwn(table, name))
|
|
@@ -629,14 +629,14 @@ function named(table, kind, kinds, name) {
|
|
|
629
629
|
}
|
|
630
630
|
/**
|
|
631
631
|
* A ramp of `steps` cells from the left ground to the right, each cell filled
|
|
632
|
-
* with one
|
|
632
|
+
* with one color: cell `i` is the color `(i + 1/2) / steps` of the way
|
|
633
633
|
* across, so no cell is either neighbour's ground. A cell is a space whose ink
|
|
634
|
-
* is the terminal's ground, so its one
|
|
635
|
-
* Beside a neighbour with no ground there is no
|
|
634
|
+
* is the terminal's ground, so its one color is its fill, the same in ASCII.
|
|
635
|
+
* Beside a neighbour with no ground there is no color to ramp toward, so that
|
|
636
636
|
* join draws the caps the ramp is ended in.
|
|
637
637
|
*
|
|
638
638
|
* [LAW:dataflow-not-control-flow] A ramp cell is fill alone: a space has no
|
|
639
|
-
* ink, and `"ground"` as its `fg` is the absence of a
|
|
639
|
+
* ink, and `"ground"` as its `fg` is the absence of a color on that side
|
|
640
640
|
* (`cellStyle`). So the lift, the path every seam cell is drawn by, has no ink
|
|
641
641
|
* to hold off its ground, and the ramp is the blend, monotone however close
|
|
642
642
|
* its grounds or however many its steps. Two samples to a cell, ink over
|
|
@@ -647,7 +647,7 @@ function named(table, kind, kinds, name) {
|
|
|
647
647
|
export function gradientSeam(steps = 4) {
|
|
648
648
|
// [LAW:no-silent-failure] A count that is no whole number of cells would draw
|
|
649
649
|
// a lopsided ramp without a word, and no cells is no ramp: a seam that reads
|
|
650
|
-
// neither ground, joining a
|
|
650
|
+
// neither ground, joining a colorless neighbour where a ramp draws the caps.
|
|
651
651
|
if (!(Number.isInteger(steps) && steps > 0))
|
|
652
652
|
throw new RangeError(`gradientSeam steps must be a positive whole number of cells, got ${steps}`);
|
|
653
653
|
const ramp = {
|
package/dist/core/style.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type { BidiStamp } from "./text-order.js";
|
|
|
10
10
|
* attribute here propagates to every styling surface without a second
|
|
11
11
|
* list to keep in sync. [LAW:one-source-of-truth]
|
|
12
12
|
*/
|
|
13
|
-
export declare const ATTRIBUTE_NAMES: readonly ["bold", "dim", "italic", "underline", "blink", "
|
|
13
|
+
export declare const ATTRIBUTE_NAMES: readonly ["bold", "dim", "italic", "underline", "blink", "rapidBlink", "reverse", "conceal", "strike", "doubleUnderline", "frame", "encircle", "overline"];
|
|
14
14
|
export type AttributeName = (typeof ATTRIBUTE_NAMES)[number];
|
|
15
15
|
/**
|
|
16
16
|
* Each text attribute as a style sets it: on, off, or unset — and an unset
|
|
@@ -35,11 +35,11 @@ export interface StyleOptions {
|
|
|
35
35
|
italic?: boolean;
|
|
36
36
|
underline?: boolean;
|
|
37
37
|
blink?: boolean;
|
|
38
|
-
|
|
38
|
+
rapidBlink?: boolean;
|
|
39
39
|
reverse?: boolean;
|
|
40
40
|
conceal?: boolean;
|
|
41
41
|
strike?: boolean;
|
|
42
|
-
|
|
42
|
+
doubleUnderline?: boolean;
|
|
43
43
|
frame?: boolean;
|
|
44
44
|
encircle?: boolean;
|
|
45
45
|
overline?: boolean;
|
|
@@ -54,17 +54,17 @@ export interface StyleOptions {
|
|
|
54
54
|
* and a timeline run backwards past its change would never wake for it.
|
|
55
55
|
* [LAW:types-are-the-program] Absent, the cells never change.
|
|
56
56
|
*/
|
|
57
|
-
|
|
57
|
+
validity?: ValidityInterval;
|
|
58
58
|
}
|
|
59
59
|
/** A hold: since when a sample has been what it is, and until when it stays so, on one clock. */
|
|
60
|
-
export interface
|
|
61
|
-
readonly
|
|
62
|
-
readonly
|
|
60
|
+
export interface ValidityInterval {
|
|
61
|
+
readonly validFrom: number;
|
|
62
|
+
readonly validUntil: number;
|
|
63
63
|
}
|
|
64
64
|
/** The hold of a cell that never changes: always was, and always will be. */
|
|
65
|
-
export declare const NEVER_CHANGES:
|
|
66
|
-
/** The moments both `a` and `b` hold through: the later `
|
|
67
|
-
export declare function intersection(a:
|
|
65
|
+
export declare const NEVER_CHANGES: ValidityInterval;
|
|
66
|
+
/** The moments both `a` and `b` hold through: the later `validFrom` and the sooner `validUntil`. */
|
|
67
|
+
export declare function intersection(a: ValidityInterval, b: ValidityInterval): ValidityInterval;
|
|
68
68
|
export declare class StyleSyntaxError extends Error {
|
|
69
69
|
constructor(message: string, options?: ErrorOptions);
|
|
70
70
|
}
|
|
@@ -76,11 +76,11 @@ export declare class Style {
|
|
|
76
76
|
readonly italic: boolean | undefined;
|
|
77
77
|
readonly underline: boolean | undefined;
|
|
78
78
|
readonly blink: boolean | undefined;
|
|
79
|
-
readonly
|
|
79
|
+
readonly rapidBlink: boolean | undefined;
|
|
80
80
|
readonly reverse: boolean | undefined;
|
|
81
81
|
readonly conceal: boolean | undefined;
|
|
82
82
|
readonly strike: boolean | undefined;
|
|
83
|
-
readonly
|
|
83
|
+
readonly doubleUnderline: boolean | undefined;
|
|
84
84
|
readonly frame: boolean | undefined;
|
|
85
85
|
readonly encircle: boolean | undefined;
|
|
86
86
|
readonly overline: boolean | undefined;
|
|
@@ -111,18 +111,18 @@ export declare class Style {
|
|
|
111
111
|
readonly bidi: BidiStamp | undefined;
|
|
112
112
|
/**
|
|
113
113
|
* The hold this style's cells are in, on the timeline of whoever drew the
|
|
114
|
-
* frame: since when what they show has been what it is (`
|
|
115
|
-
* when it next changes (`
|
|
114
|
+
* frame: since when what they show has been what it is (`validFrom`), and
|
|
115
|
+
* when it next changes (`validUntil`) — both `t` for a cell drawn by
|
|
116
116
|
* something that moves every frame, and `-Infinity`/`Infinity` for one
|
|
117
117
|
* that never changes. It draws nothing. Whatever draws for a handed time
|
|
118
118
|
* stamps its cells with it (`placedRender`, `Effected`), the stamp rides up
|
|
119
119
|
* through every container as the anchor does (`./anchor.ts`), and whoever
|
|
120
|
-
* holds the composed frame reads it off (`Segment.
|
|
121
|
-
* `Segment.
|
|
120
|
+
* holds the composed frame reads it off (`Segment.validUntil`, and
|
|
121
|
+
* `Segment.validFrom` for a host running its timeline backwards), so a
|
|
122
122
|
* host knows when to draw again without asking each container. Two styles
|
|
123
123
|
* laid together are in the intersection of their holds.
|
|
124
124
|
*/
|
|
125
|
-
readonly
|
|
125
|
+
readonly validity: ValidityInterval;
|
|
126
126
|
constructor(options?: StyleOptions);
|
|
127
127
|
get isNull(): boolean;
|
|
128
128
|
get transparentBackground(): boolean;
|
|
@@ -154,7 +154,7 @@ export declare class Style {
|
|
|
154
154
|
withAttributes(attributes: Partial<Attributes>): Style;
|
|
155
155
|
/**
|
|
156
156
|
* This style with its motion taken out, what reduced motion draws: `blink`
|
|
157
|
-
* and `
|
|
157
|
+
* and `rapidBlink`, the motion a terminal makes on its own, unset, and every
|
|
158
158
|
* other field as it was. A style that does not blink is its own.
|
|
159
159
|
*/
|
|
160
160
|
reduced(): Style;
|
|
@@ -169,7 +169,7 @@ export declare class Style {
|
|
|
169
169
|
add(other: Style | undefined): Style;
|
|
170
170
|
equals(other: Style): boolean;
|
|
171
171
|
/**
|
|
172
|
-
* The
|
|
172
|
+
* The colors this style puts on screen at `colorSystem`: each flattened
|
|
173
173
|
* onto what lies beneath it — the background onto the terminal's black, the
|
|
174
174
|
* foreground onto that background — then downgraded to the depth. The one
|
|
175
175
|
* account of what a style draws: `toSgrCodes` encodes exactly these, and a
|
|
@@ -190,7 +190,7 @@ export declare class Style {
|
|
|
190
190
|
toSgrCodes(colorSystem: ColorDepth): string;
|
|
191
191
|
/**
|
|
192
192
|
* The look as a canonical string that round-trips through `Style.parse()`:
|
|
193
|
-
*
|
|
193
|
+
* colors, attributes and the link, which is all a style string can spell.
|
|
194
194
|
* What a style carries beyond its look — `meta`, `anchor`, `boxFrame`, `bidi`, `hold` —
|
|
195
195
|
* has no spelling and is not here, so two styles that differ only there
|
|
196
196
|
* read alike; `equals` tells them apart.
|