@promptctl/rich-js 0.27.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 -6
- package/THIRD-PARTY-NOTICES +42 -0
- package/dist/core/animation.d.ts +65 -46
- package/dist/core/animation.js +91 -67
- package/dist/core/ansi.d.ts +19 -12
- package/dist/core/ansi.js +114 -36
- package/dist/core/bidi-data.d.ts +14 -0
- package/dist/core/bidi-data.js +385 -0
- package/dist/core/bidi.d.ts +89 -0
- package/dist/core/bidi.js +615 -0
- package/dist/core/box.d.ts +9 -1
- package/dist/core/box.js +11 -0
- package/dist/core/cell-widths.d.ts +3 -2
- package/dist/core/cell-widths.js +93 -93
- package/dist/core/cells.d.ts +20 -0
- package/dist/core/cells.js +94 -6
- package/dist/core/clock.d.ts +1 -1
- package/dist/core/color.d.ts +56 -57
- package/dist/core/color.js +79 -81
- package/dist/core/console.d.ts +24 -7
- package/dist/core/console.js +27 -8
- package/dist/core/control-codes.d.ts +61 -0
- package/dist/core/control-codes.js +157 -0
- package/dist/core/easing.d.ts +40 -40
- package/dist/core/easing.js +40 -40
- package/dist/core/env.d.ts +6 -0
- package/dist/core/env.js +9 -1
- package/dist/core/export-html.js +5 -4
- package/dist/core/export-lines.d.ts +13 -11
- package/dist/core/export-lines.js +19 -15
- package/dist/core/export-svg.d.ts +3 -3
- package/dist/core/export-svg.js +10 -9
- package/dist/core/json.js +9 -2
- package/dist/core/markup.js +5 -4
- 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 +68 -0
- package/dist/core/orient.js +224 -0
- package/dist/core/osc8.d.ts +12 -5
- package/dist/core/osc8.js +14 -7
- 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 +23 -19
- package/dist/core/protocol.d.ts +47 -26
- package/dist/core/protocol.js +31 -23
- package/dist/core/render.d.ts +19 -14
- package/dist/core/render.js +30 -17
- package/dist/core/seal.d.ts +26 -0
- package/dist/core/seal.js +75 -0
- package/dist/core/segment.d.ts +12 -4
- package/dist/core/segment.js +16 -6
- package/dist/core/strip.d.ts +83 -83
- package/dist/core/strip.js +70 -70
- package/dist/core/style.d.ts +46 -18
- package/dist/core/style.js +92 -56
- package/dist/core/text-order.d.ts +51 -0
- package/dist/core/text-order.js +50 -0
- package/dist/core/text.d.ts +12 -2
- package/dist/core/text.js +136 -90
- package/dist/core/timeline.d.ts +5 -5
- package/dist/core/timeline.js +11 -11
- package/dist/core/tween.d.ts +6 -6
- package/dist/core/tween.js +10 -10
- package/dist/core/view.d.ts +5 -5
- package/dist/core/view.js +15 -14
- package/dist/core/wrap.d.ts +24 -6
- package/dist/core/wrap.js +82 -16
- package/dist/host/app.d.ts +50 -9
- package/dist/host/app.js +120 -15
- package/dist/host/host-environment.d.ts +2 -2
- package/dist/host/host-environment.js +2 -2
- package/dist/host/index.d.ts +3 -2
- package/dist/host/index.js +1 -0
- package/dist/host/input.d.ts +42 -9
- package/dist/host/input.js +91 -7
- package/dist/host/terminal-colors.d.ts +18 -0
- package/dist/host/terminal-colors.js +46 -0
- package/dist/host/terminal-host.d.ts +4 -3
- package/dist/host/terminal-host.js +1 -1
- package/dist/index.d.ts +17 -16
- package/dist/index.js +11 -11
- 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.d.ts +1 -3
- package/dist/renderables/change.js +6 -8
- package/dist/renderables/effect.d.ts +88 -87
- package/dist/renderables/effect.js +124 -114
- package/dist/renderables/effects.d.ts +105 -76
- package/dist/renderables/effects.js +309 -176
- 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 +7 -16
- package/dist/renderables/frames.js +12 -27
- package/dist/renderables/glyph-effect.d.ts +22 -23
- package/dist/renderables/glyph-effect.js +43 -41
- package/dist/renderables/glyph-effects.d.ts +33 -14
- package/dist/renderables/glyph-effects.js +90 -22
- package/dist/renderables/html-entities.d.ts +1 -1
- package/dist/renderables/html-entities.js +1 -1
- package/dist/renderables/lifecycle.d.ts +8 -10
- package/dist/renderables/lifecycle.js +17 -18
- 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/markdown.js +4 -2
- package/dist/renderables/panel.js +7 -5
- package/dist/renderables/progress.d.ts +1 -1
- package/dist/renderables/progress.js +1 -1
- package/dist/renderables/progressBar.d.ts +3 -3
- package/dist/renderables/progressBar.js +21 -18
- 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 +9 -4
- package/dist/renderables/table.js +5 -4
- 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 +60 -29
- package/dist/template-bindings/animation-funcs.js +126 -43
- 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 +16 -14
- package/dist/template-bindings/index.js +17 -14
- package/dist/template-bindings/palette-funcs.d.ts +2 -2
- package/dist/template-bindings/palette-funcs.js +4 -4
- 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 +6 -5
- package/dist/themes/buildPalette.js +22 -22
- 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/index.js +1 -4
- package/dist/themes/data/textual-ansi.js +0 -143
- 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.d.ts +6 -8
- package/dist/themes/registry.js +6 -8
- package/dist/themes/terminalThemes.d.ts +4 -11
- package/dist/themes/terminalThemes.js +31 -47
- package/dist/widgets/button.d.ts +3 -3
- package/dist/widgets/button.js +8 -8
- package/dist/widgets/checkbox.d.ts +2 -2
- package/dist/widgets/checkbox.js +4 -4
- package/dist/widgets/dropdown.d.ts +3 -3
- package/dist/widgets/dropdown.js +7 -5
- 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 +4 -4
- package/dist/widgets/toggle.d.ts +4 -4
- package/dist/widgets/toggle.js +6 -6
- 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 +5 -4
package/dist/core/export-html.js
CHANGED
|
@@ -37,7 +37,7 @@ const OUTLINE = {
|
|
|
37
37
|
encircle: [FRAME, "border-radius:0.5em"],
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
|
-
* The glyph
|
|
40
|
+
* The glyph color, and the background when one is painted.
|
|
41
41
|
*
|
|
42
42
|
* Dim arrives already blended into `foreground`. `opacity` is never written:
|
|
43
43
|
* it fades a painted background along with the glyph, which is the bug the
|
|
@@ -121,13 +121,14 @@ function onGrid(text, draw) {
|
|
|
121
121
|
* blinks with the glyph. A wide glyph's box sits between the two: it inherits
|
|
122
122
|
* the double underline, and the inner span inside it draws the other lines.
|
|
123
123
|
*/
|
|
124
|
-
function runHtml({ text, look }) {
|
|
124
|
+
function runHtml({ text, look, inVisualOrder }) {
|
|
125
125
|
const drawn = look.underline === "double"
|
|
126
126
|
? span([...paintCss(look), "text-decoration-line:underline", "text-decoration-style:double", ...BLINK[look.blink]], onGrid(text, (glyph) => span([`color:${look.foreground.hex}`, ...glyphCss(look)], glyph)))
|
|
127
127
|
: span([...paintCss(look), ...glyphCss(look)], onGrid(text, (glyph) => glyph));
|
|
128
|
+
const ordered = inVisualOrder ? span(["unicode-bidi:bidi-override"], drawn) : drawn;
|
|
128
129
|
return look.href === null
|
|
129
|
-
?
|
|
130
|
-
: `<a href="${escapeAttribute(look.href)}" style="${ANCHOR_CSS}">${
|
|
130
|
+
? ordered
|
|
131
|
+
: `<a href="${escapeAttribute(look.href)}" style="${ANCHOR_CSS}">${ordered}</a>`;
|
|
131
132
|
}
|
|
132
133
|
/**
|
|
133
134
|
* The CSS a page includes once, wherever fragments appear: what an inline
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
* lines every exporter draws.
|
|
4
4
|
*
|
|
5
5
|
* The HTML and SVG exporters are two encodings of one picture, and this module
|
|
6
|
-
* is the picture. What a styled cell *looks like* — which
|
|
6
|
+
* is the picture. What a styled cell *looks like* — which color its glyph is,
|
|
7
7
|
* whether its background is painted, which decorations it carries, where it
|
|
8
8
|
* links — is decided here, once, and an exporter decides only how to write
|
|
9
9
|
* that down. Before it existed the decision was made twice, by a CSS method
|
|
10
10
|
* on `Style` and by a private converter on `Console`, and the two had already
|
|
11
|
-
* disagreed: one honoured `
|
|
11
|
+
* disagreed: one honoured `doubleUnderline`, the other dropped it.
|
|
12
12
|
*
|
|
13
13
|
* [LAW:types-are-the-program] `ExportLook` has no `reverse`, `dim`, `conceal`
|
|
14
|
-
* or default
|
|
14
|
+
* or default color, because all four are consumed by `resolveLook` and turned
|
|
15
15
|
* into plain RGB. An exporter holding a look cannot forget to swap a reversed
|
|
16
16
|
* run or to fade a dim one: there is nothing left in its hands to forget. That
|
|
17
17
|
* is the whole reason the representation is resolved rather than a `Style`
|
|
@@ -44,7 +44,7 @@ export type Href = string & {
|
|
|
44
44
|
};
|
|
45
45
|
/**
|
|
46
46
|
* Where a run's background comes from. `"canvas"` is the theme background
|
|
47
|
-
* showing through — nothing painted — and is distinct from a painted
|
|
47
|
+
* showing through — nothing painted — and is distinct from a painted color
|
|
48
48
|
* that happens to equal it, because `on default` and `on #000000` are
|
|
49
49
|
* different requests even over a black theme.
|
|
50
50
|
*/
|
|
@@ -65,6 +65,8 @@ export interface ExportLook {
|
|
|
65
65
|
export interface ExportRun {
|
|
66
66
|
readonly text: string;
|
|
67
67
|
readonly look: ExportLook;
|
|
68
|
+
/** Its cells are in display order already, so a browser must not reorder them. */
|
|
69
|
+
readonly inVisualOrder: boolean;
|
|
68
70
|
}
|
|
69
71
|
/** One terminal row, left to right. An empty array is a blank row. */
|
|
70
72
|
export type ExportLine = readonly ExportRun[];
|
|
@@ -94,25 +96,25 @@ export interface ExportCanvas {
|
|
|
94
96
|
* The ground every export is drawn on under `theme`.
|
|
95
97
|
*
|
|
96
98
|
* An exporter paints its page or window with this, and a run with no
|
|
97
|
-
* background of its own resolves to `"canvas"` rather than a
|
|
98
|
-
* showing the canvas and the page around it cannot come out different
|
|
99
|
+
* background of its own resolves to `"canvas"` rather than a color, so a run
|
|
100
|
+
* showing the canvas and the page around it cannot come out different colors.
|
|
99
101
|
*/
|
|
100
102
|
export declare function exportCanvas(theme?: TerminalTheme): ExportCanvas;
|
|
101
103
|
/**
|
|
102
104
|
* A `Style` as it appears on screen under `theme`.
|
|
103
105
|
*
|
|
104
|
-
* The order is the terminal's: the
|
|
106
|
+
* The order is the terminal's: the colors are `Style.drawnColors`, the ones
|
|
105
107
|
* `toSgrCodes` writes, resolved through the theme — `reverse` swaps them,
|
|
106
108
|
* `dim` fades the glyph toward whatever background it ended up on, and
|
|
107
109
|
* `conceal` finally paints the glyph in that background. Every step works on
|
|
108
|
-
* opaque
|
|
110
|
+
* opaque color, so no exporter ever draws a translucent one. Text under
|
|
109
111
|
* `conceal` is still present, and still selectable, in both formats.
|
|
110
112
|
*
|
|
111
|
-
* A translucent
|
|
113
|
+
* A translucent color is flattened where the writer flattens it, over
|
|
112
114
|
* `SURFACE_BLACK`, not over this export's canvas. The writer's truecolor
|
|
113
115
|
* bytes are absolute — no terminal theme retints them — so a terminal under
|
|
114
|
-
* `theme` shows that
|
|
115
|
-
* would picture a
|
|
116
|
+
* `theme` shows that color, and an export that flattened over its own canvas
|
|
117
|
+
* would picture a color no terminal draws.
|
|
116
118
|
*
|
|
117
119
|
* `theme` omitted is `ColorSpec.getTruecolor`'s own fallback — black canvas,
|
|
118
120
|
* white ink, the standard ANSI table. Choosing it there rather than naming a
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
* lines every exporter draws.
|
|
4
4
|
*
|
|
5
5
|
* The HTML and SVG exporters are two encodings of one picture, and this module
|
|
6
|
-
* is the picture. What a styled cell *looks like* — which
|
|
6
|
+
* is the picture. What a styled cell *looks like* — which color its glyph is,
|
|
7
7
|
* whether its background is painted, which decorations it carries, where it
|
|
8
8
|
* links — is decided here, once, and an exporter decides only how to write
|
|
9
9
|
* that down. Before it existed the decision was made twice, by a CSS method
|
|
10
10
|
* on `Style` and by a private converter on `Console`, and the two had already
|
|
11
|
-
* disagreed: one honoured `
|
|
11
|
+
* disagreed: one honoured `doubleUnderline`, the other dropped it.
|
|
12
12
|
*
|
|
13
13
|
* [LAW:types-are-the-program] `ExportLook` has no `reverse`, `dim`, `conceal`
|
|
14
|
-
* or default
|
|
14
|
+
* or default color, because all four are consumed by `resolveLook` and turned
|
|
15
15
|
* into plain RGB. An exporter holding a look cannot forget to swap a reversed
|
|
16
16
|
* run or to fade a dim one: there is nothing left in its hands to forget. That
|
|
17
17
|
* is the whole reason the representation is resolved rather than a `Style`
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
import { blendRgb, ColorSpec } from "./color.js";
|
|
33
33
|
import { NULL_STYLE } from "./style.js";
|
|
34
|
+
import { sealed } from "./seal.js";
|
|
34
35
|
/**
|
|
35
36
|
* The URL schemes an export will link.
|
|
36
37
|
*
|
|
@@ -81,8 +82,8 @@ const DEFAULT_COLOR = ColorSpec.default();
|
|
|
81
82
|
* The ground every export is drawn on under `theme`.
|
|
82
83
|
*
|
|
83
84
|
* An exporter paints its page or window with this, and a run with no
|
|
84
|
-
* background of its own resolves to `"canvas"` rather than a
|
|
85
|
-
* showing the canvas and the page around it cannot come out different
|
|
85
|
+
* background of its own resolves to `"canvas"` rather than a color, so a run
|
|
86
|
+
* showing the canvas and the page around it cannot come out different colors.
|
|
86
87
|
*/
|
|
87
88
|
export function exportCanvas(theme) {
|
|
88
89
|
return {
|
|
@@ -93,18 +94,18 @@ export function exportCanvas(theme) {
|
|
|
93
94
|
/**
|
|
94
95
|
* A `Style` as it appears on screen under `theme`.
|
|
95
96
|
*
|
|
96
|
-
* The order is the terminal's: the
|
|
97
|
+
* The order is the terminal's: the colors are `Style.drawnColors`, the ones
|
|
97
98
|
* `toSgrCodes` writes, resolved through the theme — `reverse` swaps them,
|
|
98
99
|
* `dim` fades the glyph toward whatever background it ended up on, and
|
|
99
100
|
* `conceal` finally paints the glyph in that background. Every step works on
|
|
100
|
-
* opaque
|
|
101
|
+
* opaque color, so no exporter ever draws a translucent one. Text under
|
|
101
102
|
* `conceal` is still present, and still selectable, in both formats.
|
|
102
103
|
*
|
|
103
|
-
* A translucent
|
|
104
|
+
* A translucent color is flattened where the writer flattens it, over
|
|
104
105
|
* `SURFACE_BLACK`, not over this export's canvas. The writer's truecolor
|
|
105
106
|
* bytes are absolute — no terminal theme retints them — so a terminal under
|
|
106
|
-
* `theme` shows that
|
|
107
|
-
* would picture a
|
|
107
|
+
* `theme` shows that color, and an export that flattened over its own canvas
|
|
108
|
+
* would picture a color no terminal draws.
|
|
108
109
|
*
|
|
109
110
|
* `theme` omitted is `ColorSpec.getTruecolor`'s own fallback — black canvas,
|
|
110
111
|
* white ink, the standard ANSI table. Choosing it there rather than naming a
|
|
@@ -129,10 +130,10 @@ export function resolveLook(style, theme) {
|
|
|
129
130
|
background,
|
|
130
131
|
bold: style.bold === true,
|
|
131
132
|
italic: style.italic === true,
|
|
132
|
-
underline: style.
|
|
133
|
+
underline: style.doubleUnderline ? "double" : style.underline ? "single" : "none",
|
|
133
134
|
strike: style.strike === true,
|
|
134
135
|
overline: style.overline === true,
|
|
135
|
-
blink: style.
|
|
136
|
+
blink: style.rapidBlink ? "fast" : style.blink ? "slow" : "none",
|
|
136
137
|
outline: style.encircle ? "encircle" : style.frame ? "frame" : "none",
|
|
137
138
|
href: style.link === undefined ? null : parseHref(style.link),
|
|
138
139
|
};
|
|
@@ -146,13 +147,16 @@ export function resolveLook(style, theme) {
|
|
|
146
147
|
*/
|
|
147
148
|
export function exportLines(segments, theme) {
|
|
148
149
|
const rows = [[]];
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
// A browser is a display that reorders and holds the controls at zero width.
|
|
151
|
+
for (const segment of sealed(segments, "logical")) {
|
|
152
|
+
const style = segment.style ?? NULL_STYLE;
|
|
153
|
+
const look = resolveLook(style, theme);
|
|
154
|
+
const inVisualOrder = style.bidi?.order === "visual";
|
|
151
155
|
segment.text.split("\n").forEach((piece, index) => {
|
|
152
156
|
if (index > 0)
|
|
153
157
|
rows.push([]);
|
|
154
158
|
if (piece.length > 0)
|
|
155
|
-
rows[rows.length - 1].push({ text: piece, look });
|
|
159
|
+
rows[rows.length - 1].push({ text: piece, look, inVisualOrder });
|
|
156
160
|
});
|
|
157
161
|
}
|
|
158
162
|
return rows[rows.length - 1].length === 0 ? rows.slice(0, -1) : rows;
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* The geometry is Rich's — a 20px character, a cell 0.61 of that wide, a row
|
|
11
11
|
* 1.22 of it tall, the same margin and padding — so a screenshot of the same
|
|
12
|
-
* program matches the library this ports. The frame's
|
|
12
|
+
* program matches the library this ports. The frame's color is not Rich's:
|
|
13
13
|
* Rich strokes it white at 35% whatever the theme, which vanishes around a
|
|
14
14
|
* light canvas. Here it is the theme's ink blended 35% into the canvas — over
|
|
15
|
-
* a black canvas the
|
|
16
|
-
* lying outside the canvas does not take on the
|
|
15
|
+
* a black canvas the color Rich draws — and opaque, so the half of the stroke
|
|
16
|
+
* lying outside the canvas does not take on the color of the page around it.
|
|
17
17
|
*
|
|
18
18
|
* Nor is how a glyph lands on its cell. The exporter has no font engine and
|
|
19
19
|
* does not know which font the viewer will draw with, so no advance width can
|
package/dist/core/export-svg.js
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* The geometry is Rich's — a 20px character, a cell 0.61 of that wide, a row
|
|
11
11
|
* 1.22 of it tall, the same margin and padding — so a screenshot of the same
|
|
12
|
-
* program matches the library this ports. The frame's
|
|
12
|
+
* program matches the library this ports. The frame's color is not Rich's:
|
|
13
13
|
* Rich strokes it white at 35% whatever the theme, which vanishes around a
|
|
14
14
|
* light canvas. Here it is the theme's ink blended 35% into the canvas — over
|
|
15
|
-
* a black canvas the
|
|
16
|
-
* lying outside the canvas does not take on the
|
|
15
|
+
* a black canvas the color Rich draws — and opaque, so the half of the stroke
|
|
16
|
+
* lying outside the canvas does not take on the color of the page around it.
|
|
17
17
|
*
|
|
18
18
|
* Nor is how a glyph lands on its cell. The exporter has no font engine and
|
|
19
19
|
* does not know which font the viewer will draw with, so no advance width can
|
|
@@ -87,10 +87,10 @@ function chunk(text, column) {
|
|
|
87
87
|
function place(rows) {
|
|
88
88
|
return rows.flatMap((runs, row) => {
|
|
89
89
|
let column = 0;
|
|
90
|
-
return runs.map(({ text, look }) => {
|
|
90
|
+
return runs.map(({ text, look, inVisualOrder }) => {
|
|
91
91
|
const chunks = chunk(text, column);
|
|
92
92
|
const cells = chunks.reduce((sum, c) => sum + c.cells, 0);
|
|
93
|
-
const placed = { row, column, cells, look, chunks };
|
|
93
|
+
const placed = { row, column, cells, look, inVisualOrder, chunks };
|
|
94
94
|
column += cells;
|
|
95
95
|
return placed;
|
|
96
96
|
});
|
|
@@ -132,15 +132,16 @@ function backgroundSvg(run) {
|
|
|
132
132
|
? []
|
|
133
133
|
: [`<rect fill="${run.look.background.hex}" ${cellBox(run)} shape-rendering="crispEdges"/>`];
|
|
134
134
|
}
|
|
135
|
-
function textSvg({ text, column, cells }, baseline) {
|
|
135
|
+
function textSvg({ text, column, cells }, baseline, inVisualOrder) {
|
|
136
136
|
// A chunk of no cells has no length to stretch to; it takes the font's.
|
|
137
137
|
const length = cells === 0 ? "" : ` textLength="${n(cells * CELL_WIDTH)}" lengthAdjust="spacingAndGlyphs"`;
|
|
138
|
-
|
|
138
|
+
const order = inVisualOrder ? ` unicode-bidi="bidi-override"` : "";
|
|
139
|
+
return `<text x="${n(column * CELL_WIDTH)}" y="${n(baseline)}"${length}${order} xml:space="preserve">${escapeText(text)}</text>`;
|
|
139
140
|
}
|
|
140
141
|
/**
|
|
141
142
|
* One run: its glyphs, then its lines and outline over them, in a group whose
|
|
142
143
|
* class carries the look — so the lines take the glyph's `fill` and blink
|
|
143
|
-
* with it. The outline is a stroke, so it names its
|
|
144
|
+
* with it. The outline is a stroke, so it names its color itself.
|
|
144
145
|
*/
|
|
145
146
|
function runSvg(run, className) {
|
|
146
147
|
const { look } = run;
|
|
@@ -155,7 +156,7 @@ function runSvg(run, className) {
|
|
|
155
156
|
];
|
|
156
157
|
const radius = OUTLINE_RADIUS[look.outline];
|
|
157
158
|
const drawn = [
|
|
158
|
-
...run.chunks.map((c) => textSvg(c, baseline)),
|
|
159
|
+
...run.chunks.map((c) => textSvg(c, baseline, run.inVisualOrder)),
|
|
159
160
|
...lineYs.map((y) => `<rect x="${x}" y="${n(y)}" width="${width}" height="${LINE_THICKNESS}"/>`),
|
|
160
161
|
...(radius === null
|
|
161
162
|
? []
|
package/dist/core/json.js
CHANGED
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
* imports core primitives only. `Console.printJson` delegates here, so this is
|
|
7
7
|
* where the console can reach it without an upward edge. [LAW:one-way-deps]
|
|
8
8
|
*/
|
|
9
|
+
import { escaped } from "./bidi.js";
|
|
9
10
|
import { RichText } from "./text.js";
|
|
10
11
|
import { JSONHighlighter } from "./highlighter.js";
|
|
11
12
|
import { measure, render } from "./protocol.js";
|
|
12
13
|
const highlighter = new JSONHighlighter();
|
|
14
|
+
/** `character` as JSON escapes, a surrogate pair for one past the BMP. */
|
|
15
|
+
const jsonEscape = (character) => Array.from({ length: character.length }, (_, at) => `\\u${character.charCodeAt(at).toString(16).padStart(4, "0")}`).join("");
|
|
13
16
|
export class JSONRenderable {
|
|
14
17
|
text;
|
|
15
18
|
constructor(text) {
|
|
@@ -38,8 +41,12 @@ export class JSONRenderable {
|
|
|
38
41
|
return value;
|
|
39
42
|
}
|
|
40
43
|
: undefined;
|
|
41
|
-
|
|
42
|
-
const
|
|
44
|
+
// `undefined` for what JSON has no form of, a function or a symbol, whatever its type says.
|
|
45
|
+
const jsonStr = JSON.stringify(data, replacer, indent) ?? "";
|
|
46
|
+
// Data on show: one string holds every key and value, so a control left in
|
|
47
|
+
// one would act on the rest of its line, and what content deletes or the wire
|
|
48
|
+
// withholds would leave a document that no longer parses back to this data.
|
|
49
|
+
const text = new RichText(escaped(jsonStr, jsonEscape));
|
|
43
50
|
if (doHighlight) {
|
|
44
51
|
highlighter.highlight(text);
|
|
45
52
|
}
|
package/dist/core/markup.js
CHANGED
|
@@ -17,9 +17,10 @@
|
|
|
17
17
|
* and is rejected with a `MarkupSyntaxError`. For the same reason a style tag
|
|
18
18
|
* may not open on one side of a plugin tag and close on the other.
|
|
19
19
|
*/
|
|
20
|
+
import { closed } from "./bidi.js";
|
|
20
21
|
import { cellLen } from "./cells.js";
|
|
21
22
|
import { Style, StyleSyntaxError } from "./style.js";
|
|
22
|
-
import { RichText,
|
|
23
|
+
import { RichText, sanitized } from "./text.js";
|
|
23
24
|
import { emojiReplace } from "./emoji.js";
|
|
24
25
|
import { pattern } from "./pattern.js";
|
|
25
26
|
import { State } from "./state.js";
|
|
@@ -545,7 +546,7 @@ function walk(tokens, source, registry, emoji) {
|
|
|
545
546
|
// counted along the way — a span, a splice point — indexes the text it
|
|
546
547
|
// lands on. Stripped only by the constructor, a control character
|
|
547
548
|
// shifted every style after it one cell right.
|
|
548
|
-
write(out,
|
|
549
|
+
write(out, sanitized(emoji ? emojiReplace(text) : text));
|
|
549
550
|
continue;
|
|
550
551
|
}
|
|
551
552
|
const plugin = pluginOf(token, registry);
|
|
@@ -580,7 +581,7 @@ function walk(tokens, source, registry, emoji) {
|
|
|
580
581
|
const children = compose(takeFrom(out, target.mark));
|
|
581
582
|
const text = handler({ attrs, children, raw: source.slice(target.tag.end, token.start) });
|
|
582
583
|
out.spliced.push({ at: out.length, text });
|
|
583
|
-
write(out, text.plain);
|
|
584
|
+
write(out, closed(text.plain));
|
|
584
585
|
}
|
|
585
586
|
// Close what is still open, innermost first. The reference pops its stack
|
|
586
587
|
// here (`while style_stack: start, tag = style_stack.pop()`), and popping is
|
|
@@ -615,7 +616,7 @@ function compose(frame, baseStyle) {
|
|
|
615
616
|
// The reversal is the whole of the tie-break, not decoration.
|
|
616
617
|
// `[red][blue]x[/blue][/red]` yields two spans that both start at 0, and a
|
|
617
618
|
// stable sort leaves those in the order they arrived — closing order,
|
|
618
|
-
// innermost first — which is the outer
|
|
619
|
+
// innermost first — which is the outer color winning. Reversed first, the
|
|
619
620
|
// outer arrives first and the inner repaints it (rich-markup-krk).
|
|
620
621
|
const spans = [...frame.spans].reverse().sort((a, b) => a.start - b.start);
|
|
621
622
|
const result = new RichText(frame.plain);
|
package/dist/core/memo.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* memo — a string-keyed memo with a size bound: the one cache shape for a
|
|
3
3
|
* pure computation whose keys a long-running host derives without end. A
|
|
4
|
-
* statusline daemon redrawing a time-varying
|
|
4
|
+
* statusline daemon redrawing a time-varying color parses a new hex string,
|
|
5
5
|
* matches a new RGB triple, measures a new cell, on every frame; a memo that
|
|
6
6
|
* never evicts grows by one entry per frame for the life of the process.
|
|
7
7
|
*/
|
package/dist/core/memo.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* memo — a string-keyed memo with a size bound: the one cache shape for a
|
|
3
3
|
* pure computation whose keys a long-running host derives without end. A
|
|
4
|
-
* statusline daemon redrawing a time-varying
|
|
4
|
+
* statusline daemon redrawing a time-varying color parses a new hex string,
|
|
5
5
|
* matches a new RGB triple, measures a new cell, on every frame; a memo that
|
|
6
6
|
* never evicts grows by one entry per frame for the life of the process.
|
|
7
7
|
*/
|
package/dist/core/oklch.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* sRGB is the wire format terminals consume (what ANSI escape codes
|
|
15
15
|
* carry); OKLCH is the perceptual manipulation space (where equal
|
|
16
16
|
* numerical deltas mean equal perceptual deltas, which is the property
|
|
17
|
-
* "
|
|
17
|
+
* "adjustment" requires). Two types, mutual conversion, no hybrid.
|
|
18
18
|
*
|
|
19
19
|
* [LAW:one-way-deps] This module imports `ColorRgba` from core/color and
|
|
20
20
|
* nothing else from inside the project. Nothing in core/ depends back on
|
|
@@ -25,13 +25,13 @@ import { ColorRgba } from "./color.js";
|
|
|
25
25
|
* A perceptually-uniform color transform.
|
|
26
26
|
*
|
|
27
27
|
* [LAW:dataflow-not-control-flow] Identity is *data* (`IDENTITY`), not a
|
|
28
|
-
* special case. Every
|
|
28
|
+
* special case. Every adjustment runs the same code path — the values
|
|
29
29
|
* decide whether the operation is a no-op or a 180° rotation.
|
|
30
30
|
*
|
|
31
31
|
* Lightness is parameterized as `L' = clamp01(L * scale + shift)` to make
|
|
32
32
|
* "invert" expressible as `{scale: -1, shift: 1}` without a boolean knob.
|
|
33
33
|
*/
|
|
34
|
-
export interface
|
|
34
|
+
export interface ColorAdjustment {
|
|
35
35
|
/** Hue offset in degrees; positive rotates toward warmer→cooler→back. */
|
|
36
36
|
readonly hueShift: number;
|
|
37
37
|
/** Multiplier on chroma. 0 = grayscale, 1 = identity, >1 = more saturated. */
|
|
@@ -48,22 +48,22 @@ export interface OklchWeights {
|
|
|
48
48
|
readonly h: number;
|
|
49
49
|
readonly alpha: number;
|
|
50
50
|
}
|
|
51
|
-
export declare const IDENTITY:
|
|
51
|
+
export declare const IDENTITY: ColorAdjustment;
|
|
52
52
|
/**
|
|
53
53
|
* Flip lightness around the midpoint (`L' = 1 - L`) with hue and chroma
|
|
54
|
-
* untouched. Combined with the anchor logic in `
|
|
54
|
+
* untouched. Combined with the anchor logic in `adjustPalette`, this
|
|
55
55
|
* converts a dark theme to its light "octave": semantic anchors
|
|
56
56
|
* (error/success/warning) still lightness-invert — only their *hue* is
|
|
57
57
|
* preserved — so errors stay red and dark-on-light becomes light-on-dark.
|
|
58
58
|
*/
|
|
59
|
-
export declare const INVERT_LIGHTNESS:
|
|
59
|
+
export declare const INVERT_LIGHTNESS: ColorAdjustment;
|
|
60
60
|
/**
|
|
61
61
|
* Whether a key is the no-op transform. Exported so that callers
|
|
62
|
-
* (`
|
|
62
|
+
* (`adjustPalette`) can fast-path byte-exact identity without going
|
|
63
63
|
* through the lossy sRGB↔OKLCH round-trip. [LAW:one-source-of-truth] —
|
|
64
64
|
* the predicate lives once, here.
|
|
65
65
|
*/
|
|
66
|
-
export declare function isIdentityKey(k:
|
|
66
|
+
export declare function isIdentityKey(k: ColorAdjustment): boolean;
|
|
67
67
|
export declare function srgbToLinear(v: number): number;
|
|
68
68
|
export declare function linearToSrgb(v: number): number;
|
|
69
69
|
/**
|
|
@@ -96,13 +96,13 @@ export declare class Oklch {
|
|
|
96
96
|
*/
|
|
97
97
|
toRgba(): ColorRgba;
|
|
98
98
|
/**
|
|
99
|
-
* Apply a `
|
|
99
|
+
* Apply a `ColorAdjustment`. Returns a new `Oklch`; pure.
|
|
100
100
|
*
|
|
101
101
|
* [LAW:dataflow-not-control-flow] Identity short-circuits to `this` —
|
|
102
102
|
* same shape as `ColorRgba.compositeOver(bg)` returning `this` when
|
|
103
103
|
* `alpha === 1`. Callers invoke unconditionally; the data decides.
|
|
104
104
|
*/
|
|
105
|
-
applyKey(k:
|
|
105
|
+
applyKey(k: ColorAdjustment): Oklch;
|
|
106
106
|
/**
|
|
107
107
|
* The color `t` of the way from this one toward `toward`, in OKLCH.
|
|
108
108
|
* `t = 0` is this color, `t = 1` is `toward`; pure.
|
|
@@ -115,7 +115,7 @@ export declare class Oklch {
|
|
|
115
115
|
* that gains chroma, instead of rotating through the wheel from 0°.
|
|
116
116
|
*
|
|
117
117
|
* `t` must lie in [0, 1]: this is interpolation, not extrapolation, and a
|
|
118
|
-
* `t` outside it (NaN included) is a RangeError, never a
|
|
118
|
+
* `t` outside it (NaN included) is a RangeError, never a color off the
|
|
119
119
|
* far end of the segment. [LAW:no-silent-failure]
|
|
120
120
|
*
|
|
121
121
|
* [LAW:one-source-of-truth] Achromatic means the same `ACHROMATIC_EPS`
|
|
@@ -133,19 +133,19 @@ export declare class Oklch {
|
|
|
133
133
|
* whichever is called.
|
|
134
134
|
*
|
|
135
135
|
* It exists because perceptual axes are independent: a tint can take most of
|
|
136
|
-
* a hue's
|
|
136
|
+
* a hue's colorfulness while keeping close to the lightness it started at,
|
|
137
137
|
* which a single `t` cannot say — raising `t` for chroma drags lightness with
|
|
138
138
|
* it. Every weight is required: an axis left out would need a default, and
|
|
139
139
|
* "unchanged" (0) and "same as the others" are both plausible readings.
|
|
140
140
|
*
|
|
141
|
-
* A weak `h` beside a strong `c` shows the starting
|
|
141
|
+
* A weak `h` beside a strong `c` shows the starting color's hue at high
|
|
142
142
|
* chroma. The powerless rule covers only a truly achromatic start, so a
|
|
143
143
|
* near-grey whose hue is noise (a theme surface at c ≈ 0.004) keeps that
|
|
144
144
|
* noise in proportion. To land on the target's hue, pass `h: 1`.
|
|
145
145
|
*/
|
|
146
146
|
mixAxes(toward: Oklch, weights: OklchWeights): Oklch;
|
|
147
147
|
/**
|
|
148
|
-
* ΔE_OK — the Euclidean distance between this
|
|
148
|
+
* ΔE_OK — the Euclidean distance between this color and `other` in OKLab
|
|
149
149
|
* (CSS Color 4's `deltaEOK`), where ~0.02 is the smallest difference the eye
|
|
150
150
|
* resolves. Alpha is not a coordinate of the space and does not count.
|
|
151
151
|
* Symmetric and pure.
|
package/dist/core/oklch.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* sRGB is the wire format terminals consume (what ANSI escape codes
|
|
15
15
|
* carry); OKLCH is the perceptual manipulation space (where equal
|
|
16
16
|
* numerical deltas mean equal perceptual deltas, which is the property
|
|
17
|
-
* "
|
|
17
|
+
* "adjustment" requires). Two types, mutual conversion, no hybrid.
|
|
18
18
|
*
|
|
19
19
|
* [LAW:one-way-deps] This module imports `ColorRgba` from core/color and
|
|
20
20
|
* nothing else from inside the project. Nothing in core/ depends back on
|
|
@@ -33,7 +33,7 @@ export const IDENTITY = Object.freeze({
|
|
|
33
33
|
});
|
|
34
34
|
/**
|
|
35
35
|
* Flip lightness around the midpoint (`L' = 1 - L`) with hue and chroma
|
|
36
|
-
* untouched. Combined with the anchor logic in `
|
|
36
|
+
* untouched. Combined with the anchor logic in `adjustPalette`, this
|
|
37
37
|
* converts a dark theme to its light "octave": semantic anchors
|
|
38
38
|
* (error/success/warning) still lightness-invert — only their *hue* is
|
|
39
39
|
* preserved — so errors stay red and dark-on-light becomes light-on-dark.
|
|
@@ -46,7 +46,7 @@ export const INVERT_LIGHTNESS = Object.freeze({
|
|
|
46
46
|
});
|
|
47
47
|
/**
|
|
48
48
|
* Whether a key is the no-op transform. Exported so that callers
|
|
49
|
-
* (`
|
|
49
|
+
* (`adjustPalette`) can fast-path byte-exact identity without going
|
|
50
50
|
* through the lossy sRGB↔OKLCH round-trip. [LAW:one-source-of-truth] —
|
|
51
51
|
* the predicate lives once, here.
|
|
52
52
|
*/
|
|
@@ -179,7 +179,7 @@ export class Oklch {
|
|
|
179
179
|
return new ColorRgba(sR, sG, sB, this.alpha);
|
|
180
180
|
}
|
|
181
181
|
/**
|
|
182
|
-
* Apply a `
|
|
182
|
+
* Apply a `ColorAdjustment`. Returns a new `Oklch`; pure.
|
|
183
183
|
*
|
|
184
184
|
* [LAW:dataflow-not-control-flow] Identity short-circuits to `this` —
|
|
185
185
|
* same shape as `ColorRgba.compositeOver(bg)` returning `this` when
|
|
@@ -205,7 +205,7 @@ export class Oklch {
|
|
|
205
205
|
* that gains chroma, instead of rotating through the wheel from 0°.
|
|
206
206
|
*
|
|
207
207
|
* `t` must lie in [0, 1]: this is interpolation, not extrapolation, and a
|
|
208
|
-
* `t` outside it (NaN included) is a RangeError, never a
|
|
208
|
+
* `t` outside it (NaN included) is a RangeError, never a color off the
|
|
209
209
|
* far end of the segment. [LAW:no-silent-failure]
|
|
210
210
|
*
|
|
211
211
|
* [LAW:one-source-of-truth] Achromatic means the same `ACHROMATIC_EPS`
|
|
@@ -228,12 +228,12 @@ export class Oklch {
|
|
|
228
228
|
* whichever is called.
|
|
229
229
|
*
|
|
230
230
|
* It exists because perceptual axes are independent: a tint can take most of
|
|
231
|
-
* a hue's
|
|
231
|
+
* a hue's colorfulness while keeping close to the lightness it started at,
|
|
232
232
|
* which a single `t` cannot say — raising `t` for chroma drags lightness with
|
|
233
233
|
* it. Every weight is required: an axis left out would need a default, and
|
|
234
234
|
* "unchanged" (0) and "same as the others" are both plausible readings.
|
|
235
235
|
*
|
|
236
|
-
* A weak `h` beside a strong `c` shows the starting
|
|
236
|
+
* A weak `h` beside a strong `c` shows the starting color's hue at high
|
|
237
237
|
* chroma. The powerless rule covers only a truly achromatic start, so a
|
|
238
238
|
* near-grey whose hue is noise (a theme surface at c ≈ 0.004) keeps that
|
|
239
239
|
* noise in proportion. To land on the target's hue, pass `h: 1`.
|
|
@@ -265,7 +265,7 @@ export class Oklch {
|
|
|
265
265
|
return new _a(lerp(this.l, toward.l, wl), c, hueOf(c, wrapHue(lerp(fromU, toU, wh))), lerp(this.alpha, toward.alpha, walpha));
|
|
266
266
|
}
|
|
267
267
|
/**
|
|
268
|
-
* ΔE_OK — the Euclidean distance between this
|
|
268
|
+
* ΔE_OK — the Euclidean distance between this color and `other` in OKLab
|
|
269
269
|
* (CSS Color 4's `deltaEOK`), where ~0.02 is the smallest difference the eye
|
|
270
270
|
* resolves. Alpha is not a coordinate of the space and does not count.
|
|
271
271
|
* Symmetric and pure.
|
|
@@ -276,9 +276,9 @@ export class Oklch {
|
|
|
276
276
|
return Math.hypot(this.l - other.l, a - otherA, b - otherB);
|
|
277
277
|
}
|
|
278
278
|
/**
|
|
279
|
-
* This
|
|
279
|
+
* This color's OKLab a and b, kept with it: a color matched against a
|
|
280
280
|
* palette is measured against every entry, and each entry against every
|
|
281
|
-
*
|
|
281
|
+
* color it is matched with, so the trigonometry is paid once a color
|
|
282
282
|
* rather than once a comparison.
|
|
283
283
|
*/
|
|
284
284
|
#lab;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orienting a drawn line for its destination's `TextOrder`.
|
|
3
|
+
*
|
|
4
|
+
* Levels are resolved over the whole logical line and a row is ordered alone,
|
|
5
|
+
* because UAX #9 runs L1 and L2 after line breaking. So `directed` runs ahead of
|
|
6
|
+
* wrapping and each row's `orient` after it, and cuts fall on logical offsets in
|
|
7
|
+
* every order: what survives a cut is a logical prefix of the sentence, which is
|
|
8
|
+
* what a reader of either direction expects.
|
|
9
|
+
*
|
|
10
|
+
* [LAW:dataflow-not-control-flow] The order chooses values and never steps: a
|
|
11
|
+
* `plain` line passes through both.
|
|
12
|
+
*/
|
|
13
|
+
import { Segment } from "./segment.js";
|
|
14
|
+
import { type Style } from "./style.js";
|
|
15
|
+
import type { TextOrder } from "./text-order.js";
|
|
16
|
+
/**
|
|
17
|
+
* The cells that end `text` and are no content: its whitespace, once what draws no
|
|
18
|
+
* cell among it is gone. A mark drawn on a space is not in it, because that space
|
|
19
|
+
* is a cell with something on it.
|
|
20
|
+
*/
|
|
21
|
+
export declare function drawnTail(text: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* The cells of trailing whitespace on a wrapped line.
|
|
24
|
+
*
|
|
25
|
+
* A wrap cuts before a word, so the line it closes ends with the whitespace
|
|
26
|
+
* that followed *its* last word — padding the break created, not content the
|
|
27
|
+
* author wrote. Measuring it is what lets the overflow method tell "this line
|
|
28
|
+
* was cut" from "this line ends in spaces" and stamp an ellipsis only on the
|
|
29
|
+
* first, and what keeps a centred line from drifting half a space off true.
|
|
30
|
+
*
|
|
31
|
+
* Asked of the line's text rather than walked back through its segments,
|
|
32
|
+
* because where a line ends is a fact about the characters and not about how
|
|
33
|
+
* they were split. Walking the segments made it a fact about both: it read a
|
|
34
|
+
* segment with no trailing whitespace as content and stopped there, which an
|
|
35
|
+
* empty segment also looks like — and a crop leaves one behind. A styled line
|
|
36
|
+
* whose last cells were cropped therefore reported no hanging whitespace at
|
|
37
|
+
* all and was centred as though it were content to the edge, so a span landing
|
|
38
|
+
* anywhere in a wrap's whitespace un-centred the line it closed. What draws no
|
|
39
|
+
* cell after the whitespace is no content either: `closed` writes a bidi control
|
|
40
|
+
* exactly there, and a cut leaves a zero-width code point that opened the next
|
|
41
|
+
* word on the row before it.
|
|
42
|
+
*/
|
|
43
|
+
export declare function hangingWhitespace(line: Segment[]): number;
|
|
44
|
+
/** What a row of a directed line is, given the text it started as and its offset in the line. */
|
|
45
|
+
export interface ReorderedLine {
|
|
46
|
+
/** The line to cut: X9's removals gone where the terminal will not need them. */
|
|
47
|
+
readonly line: readonly Segment[];
|
|
48
|
+
/** Whether a row's cells may not be merged with the padding beside them. */
|
|
49
|
+
readonly oriented: boolean;
|
|
50
|
+
/** A row of `source` at `start`: the segments it became, ready for padding. */
|
|
51
|
+
orient(shown: readonly Segment[], start: number, source: string): Segment[];
|
|
52
|
+
}
|
|
53
|
+
/** What `order` does with `line`, one logical line of drawn segments. */
|
|
54
|
+
export declare function reorder(line: readonly Segment[], order: TextOrder): ReorderedLine;
|
|
55
|
+
/** `text` as `order` measures it: what `directed` removes ahead of wrapping is no word. */
|
|
56
|
+
export declare function measured(text: string, order: TextOrder): string;
|
|
57
|
+
/** The offsets in `text`, one row, of the characters `order` shows at its left and right edges. */
|
|
58
|
+
export declare function edges(text: string, order: TextOrder): {
|
|
59
|
+
readonly left: number;
|
|
60
|
+
readonly right: number;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* A label set between `before` and `after`, which are frame and stay where they
|
|
64
|
+
* are, for a row drawn with no `RichText`: only the label is oriented, or a
|
|
65
|
+
* button's brackets would be mirrored around it. A label `directed` leaves alone
|
|
66
|
+
* is one segment with its frame, as it always was.
|
|
67
|
+
*/
|
|
68
|
+
export declare function labeled(before: string, label: string, after: string, style: Style | undefined, order: TextOrder | undefined): Segment[];
|