@promptctl/rich-js 0.17.0 → 0.18.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 +13 -26
- package/package.json +7 -3
- package/dist/core/box.d.ts +0 -144
- package/dist/core/box.js +0 -391
- package/dist/core/cells.d.ts +0 -148
- package/dist/core/cells.js +0 -266
- package/dist/core/color.d.ts +0 -250
- package/dist/core/color.js +0 -1029
- package/dist/core/console.d.ts +0 -156
- package/dist/core/console.js +0 -472
- package/dist/core/emoji.d.ts +0 -24
- package/dist/core/emoji.js +0 -391
- package/dist/core/export-html.d.ts +0 -24
- package/dist/core/export-html.js +0 -106
- package/dist/core/export-lines.d.ts +0 -121
- package/dist/core/export-lines.js +0 -141
- package/dist/core/highlighter.d.ts +0 -33
- package/dist/core/highlighter.js +0 -124
- package/dist/core/json.d.ts +0 -27
- package/dist/core/json.js +0 -53
- package/dist/core/markup.d.ts +0 -97
- package/dist/core/markup.js +0 -619
- package/dist/core/measure.d.ts +0 -27
- package/dist/core/measure.js +0 -61
- package/dist/core/oklch.d.ts +0 -161
- package/dist/core/oklch.js +0 -312
- package/dist/core/osc8.d.ts +0 -68
- package/dist/core/osc8.js +0 -90
- package/dist/core/pretty.d.ts +0 -141
- package/dist/core/pretty.js +0 -472
- package/dist/core/protocol.d.ts +0 -137
- package/dist/core/protocol.js +0 -101
- package/dist/core/render.d.ts +0 -84
- package/dist/core/render.js +0 -145
- package/dist/core/segment.d.ts +0 -142
- package/dist/core/segment.js +0 -433
- package/dist/core/spinnerData.d.ts +0 -10
- package/dist/core/spinnerData.js +0 -115
- package/dist/core/strip.d.ts +0 -145
- package/dist/core/strip.js +0 -308
- package/dist/core/style.d.ts +0 -144
- package/dist/core/style.js +0 -723
- package/dist/core/subscription.d.ts +0 -12
- package/dist/core/subscription.js +0 -12
- package/dist/core/text.d.ts +0 -255
- package/dist/core/text.js +0 -990
- package/dist/core/wrap.d.ts +0 -41
- package/dist/core/wrap.js +0 -127
- package/dist/host/host-stream.d.ts +0 -30
- package/dist/host/host-stream.js +0 -35
- package/dist/host/index.d.ts +0 -3
- package/dist/host/index.js +0 -2
- package/dist/host/terminal-host.d.ts +0 -143
- package/dist/host/terminal-host.js +0 -132
- package/dist/index.d.ts +0 -87
- package/dist/index.js +0 -104
- package/dist/node/prompt.d.ts +0 -21
- package/dist/node/prompt.js +0 -30
- package/dist/node/save.d.ts +0 -17
- package/dist/node/save.js +0 -21
- package/dist/node/terminal-host.d.ts +0 -84
- package/dist/node/terminal-host.js +0 -160
- package/dist/node/traceback.d.ts +0 -27
- package/dist/node/traceback.js +0 -112
- package/dist/renderables/align.d.ts +0 -16
- package/dist/renderables/align.js +0 -46
- package/dist/renderables/columns.d.ts +0 -61
- package/dist/renderables/columns.js +0 -168
- package/dist/renderables/constrain.d.ts +0 -15
- package/dist/renderables/constrain.js +0 -37
- package/dist/renderables/flexStrip.d.ts +0 -41
- package/dist/renderables/flexStrip.js +0 -200
- package/dist/renderables/group.d.ts +0 -11
- package/dist/renderables/group.js +0 -15
- package/dist/renderables/layout.d.ts +0 -92
- package/dist/renderables/layout.js +0 -315
- package/dist/renderables/live.d.ts +0 -47
- package/dist/renderables/live.js +0 -131
- package/dist/renderables/markdown.d.ts +0 -24
- package/dist/renderables/markdown.js +0 -182
- package/dist/renderables/padding.d.ts +0 -38
- package/dist/renderables/padding.js +0 -140
- package/dist/renderables/panel.d.ts +0 -116
- package/dist/renderables/panel.js +0 -322
- package/dist/renderables/progress.d.ts +0 -90
- package/dist/renderables/progress.js +0 -241
- package/dist/renderables/progressBar.d.ts +0 -31
- package/dist/renderables/progressBar.js +0 -52
- package/dist/renderables/prompt.d.ts +0 -49
- package/dist/renderables/prompt.js +0 -125
- package/dist/renderables/rule.d.ts +0 -24
- package/dist/renderables/rule.js +0 -90
- package/dist/renderables/spinner.d.ts +0 -29
- package/dist/renderables/spinner.js +0 -64
- package/dist/renderables/status.d.ts +0 -23
- package/dist/renderables/status.js +0 -60
- package/dist/renderables/syntax.d.ts +0 -35
- package/dist/renderables/syntax.js +0 -114
- package/dist/renderables/table.d.ts +0 -182
- package/dist/renderables/table.js +0 -697
- package/dist/renderables/traceback.d.ts +0 -31
- package/dist/renderables/traceback.js +0 -109
- package/dist/renderables/tree.d.ts +0 -54
- package/dist/renderables/tree.js +0 -159
- package/dist/template-bindings/color-funcs.d.ts +0 -87
- package/dist/template-bindings/color-funcs.js +0 -219
- package/dist/template-bindings/helpers.d.ts +0 -24
- package/dist/template-bindings/helpers.js +0 -48
- package/dist/template-bindings/index.d.ts +0 -107
- package/dist/template-bindings/index.js +0 -144
- package/dist/template-bindings/palette-funcs.d.ts +0 -94
- package/dist/template-bindings/palette-funcs.js +0 -151
- package/dist/template-bindings/style-funcs.d.ts +0 -28
- package/dist/template-bindings/style-funcs.js +0 -151
- package/dist/themes/buildPalette.d.ts +0 -36
- package/dist/themes/buildPalette.js +0 -56
- package/dist/themes/colorMath.d.ts +0 -82
- package/dist/themes/colorMath.js +0 -254
- package/dist/themes/colorRef.d.ts +0 -51
- package/dist/themes/colorRef.js +0 -96
- package/dist/themes/data/atom-one-dark.d.ts +0 -3
- package/dist/themes/data/atom-one-dark.js +0 -158
- package/dist/themes/data/atom-one-light.d.ts +0 -3
- package/dist/themes/data/atom-one-light.js +0 -158
- package/dist/themes/data/catppuccin-frappe.d.ts +0 -3
- package/dist/themes/data/catppuccin-frappe.js +0 -158
- package/dist/themes/data/catppuccin-latte.d.ts +0 -3
- package/dist/themes/data/catppuccin-latte.js +0 -158
- package/dist/themes/data/catppuccin-macchiato.d.ts +0 -3
- package/dist/themes/data/catppuccin-macchiato.js +0 -158
- package/dist/themes/data/catppuccin-mocha.d.ts +0 -3
- package/dist/themes/data/catppuccin-mocha.js +0 -158
- package/dist/themes/data/cyberpunk.d.ts +0 -17
- package/dist/themes/data/cyberpunk.js +0 -191
- package/dist/themes/data/default.d.ts +0 -3
- package/dist/themes/data/default.js +0 -158
- package/dist/themes/data/dracula.d.ts +0 -3
- package/dist/themes/data/dracula.js +0 -158
- package/dist/themes/data/flexoki.d.ts +0 -3
- package/dist/themes/data/flexoki.js +0 -158
- package/dist/themes/data/gruvbox.d.ts +0 -3
- package/dist/themes/data/gruvbox.js +0 -158
- package/dist/themes/data/index.d.ts +0 -35
- package/dist/themes/data/index.js +0 -64
- package/dist/themes/data/monokai.d.ts +0 -3
- package/dist/themes/data/monokai.js +0 -158
- package/dist/themes/data/nord.d.ts +0 -3
- package/dist/themes/data/nord.js +0 -158
- package/dist/themes/data/rose-pine-dawn.d.ts +0 -3
- package/dist/themes/data/rose-pine-dawn.js +0 -158
- package/dist/themes/data/rose-pine-moon.d.ts +0 -3
- package/dist/themes/data/rose-pine-moon.js +0 -158
- package/dist/themes/data/rose-pine.d.ts +0 -3
- package/dist/themes/data/rose-pine.js +0 -158
- package/dist/themes/data/solarized-dark.d.ts +0 -3
- package/dist/themes/data/solarized-dark.js +0 -158
- package/dist/themes/data/solarized-light.d.ts +0 -3
- package/dist/themes/data/solarized-light.js +0 -158
- package/dist/themes/data/svg-export.d.ts +0 -3
- package/dist/themes/data/svg-export.js +0 -158
- package/dist/themes/data/textual-ansi.d.ts +0 -3
- package/dist/themes/data/textual-ansi.js +0 -158
- package/dist/themes/data/textual-dark.d.ts +0 -3
- package/dist/themes/data/textual-dark.js +0 -158
- package/dist/themes/data/textual-light.d.ts +0 -3
- package/dist/themes/data/textual-light.js +0 -158
- package/dist/themes/data/tokyo-night.d.ts +0 -3
- package/dist/themes/data/tokyo-night.js +0 -158
- package/dist/themes/data/types.d.ts +0 -15
- package/dist/themes/data/types.js +0 -1
- package/dist/themes/palette.d.ts +0 -21
- package/dist/themes/palette.js +0 -28
- package/dist/themes/ramp.d.ts +0 -83
- package/dist/themes/ramp.js +0 -122
- package/dist/themes/registry.d.ts +0 -43
- package/dist/themes/registry.js +0 -82
- package/dist/themes/terminalThemes.d.ts +0 -54
- package/dist/themes/terminalThemes.js +0 -68
- package/dist/themes/transpose.d.ts +0 -87
- package/dist/themes/transpose.js +0 -138
- package/dist/widgets/button.d.ts +0 -49
- package/dist/widgets/button.js +0 -206
- package/dist/widgets/checkbox.d.ts +0 -41
- package/dist/widgets/checkbox.js +0 -155
- package/dist/widgets/dropdown.d.ts +0 -67
- package/dist/widgets/dropdown.js +0 -453
- package/dist/widgets/event-router.d.ts +0 -78
- package/dist/widgets/event-router.js +0 -622
- package/dist/widgets/focus-manager.d.ts +0 -26
- package/dist/widgets/focus-manager.js +0 -193
- package/dist/widgets/index.d.ts +0 -22
- package/dist/widgets/index.js +0 -15
- package/dist/widgets/screen.d.ts +0 -98
- package/dist/widgets/screen.js +0 -530
- package/dist/widgets/slider.d.ts +0 -57
- package/dist/widgets/slider.js +0 -270
- package/dist/widgets/static-item.d.ts +0 -40
- package/dist/widgets/static-item.js +0 -60
- package/dist/widgets/text-input.d.ts +0 -274
- package/dist/widgets/text-input.js +0 -1162
- package/dist/widgets/toggle.d.ts +0 -44
- package/dist/widgets/toggle.js +0 -179
- package/dist/widgets/types.d.ts +0 -108
- package/dist/widgets/types.js +0 -31
- package/dist/widgets/widget-base.d.ts +0 -42
- package/dist/widgets/widget-base.js +0 -173
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared internal helpers for the rich-js template binding layer.
|
|
3
|
-
*
|
|
4
|
-
* [LAW:one-source-of-truth] `applyStyleToFragment` is the single implementation
|
|
5
|
-
* of "apply a Style to an existing RichText fragment." Both the style-function
|
|
6
|
-
* registrations and the palette-function registrations use this same operation;
|
|
7
|
-
* keeping one copy prevents the two from drifting.
|
|
8
|
-
*/
|
|
9
|
-
import { Style } from "../core/style.js";
|
|
10
|
-
import { RichText } from "../core/text.js";
|
|
11
|
-
/**
|
|
12
|
-
* Apply a style on top of an already-styled RichText fragment.
|
|
13
|
-
*
|
|
14
|
-
* [LAW:single-enforcer] Type validation lives here; callers trust the result.
|
|
15
|
-
* The `"liftable"` arg type lifts string literals to `RichText` via the
|
|
16
|
-
* engine's `fromString` before the body runs, so `child` is always a
|
|
17
|
-
* `RichText` by the time this runs. The instanceof check exists because
|
|
18
|
-
* `"liftable"` admits any non-primitive — the engine cannot prove the object
|
|
19
|
-
* is the binding's own `T`. Misuse (`{{ red someMap }}`) fails loudly here
|
|
20
|
-
* rather than producing a malformed fragment.
|
|
21
|
-
*
|
|
22
|
-
* Conflict resolution: `Style.add` — the outer (newly applied) style wins.
|
|
23
|
-
*/
|
|
24
|
-
export declare function applyStyleToFragment(child: unknown, style: Style): RichText;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared internal helpers for the rich-js template binding layer.
|
|
3
|
-
*
|
|
4
|
-
* [LAW:one-source-of-truth] `applyStyleToFragment` is the single implementation
|
|
5
|
-
* of "apply a Style to an existing RichText fragment." Both the style-function
|
|
6
|
-
* registrations and the palette-function registrations use this same operation;
|
|
7
|
-
* keeping one copy prevents the two from drifting.
|
|
8
|
-
*/
|
|
9
|
-
import { Style, StyleSyntaxError } from "../core/style.js";
|
|
10
|
-
import { RichText } from "../core/text.js";
|
|
11
|
-
/**
|
|
12
|
-
* Apply a style on top of an already-styled RichText fragment.
|
|
13
|
-
*
|
|
14
|
-
* [LAW:single-enforcer] Type validation lives here; callers trust the result.
|
|
15
|
-
* The `"liftable"` arg type lifts string literals to `RichText` via the
|
|
16
|
-
* engine's `fromString` before the body runs, so `child` is always a
|
|
17
|
-
* `RichText` by the time this runs. The instanceof check exists because
|
|
18
|
-
* `"liftable"` admits any non-primitive — the engine cannot prove the object
|
|
19
|
-
* is the binding's own `T`. Misuse (`{{ red someMap }}`) fails loudly here
|
|
20
|
-
* rather than producing a malformed fragment.
|
|
21
|
-
*
|
|
22
|
-
* Conflict resolution: `Style.add` — the outer (newly applied) style wins.
|
|
23
|
-
*/
|
|
24
|
-
export function applyStyleToFragment(child, style) {
|
|
25
|
-
if (!(child instanceof RichText)) {
|
|
26
|
-
throw new TypeError(`template function expected a RichText fragment, got ${typeof child === "object" ? Object.prototype.toString.call(child) : typeof child}`);
|
|
27
|
-
}
|
|
28
|
-
const result = child.copy();
|
|
29
|
-
result.style = baseStyleOf(child.style).add(style);
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* A fragment's base style as a `Style`. A string must parse as a definition: a
|
|
34
|
-
* name resolves only against the theme of the render that draws it, and a
|
|
35
|
-
* template runs before any render exists.
|
|
36
|
-
*/
|
|
37
|
-
function baseStyleOf(style) {
|
|
38
|
-
if (style instanceof Style)
|
|
39
|
-
return style;
|
|
40
|
-
try {
|
|
41
|
-
return Style.parse(style);
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
if (!(err instanceof StyleSyntaxError))
|
|
45
|
-
throw err;
|
|
46
|
-
throw new TypeError(`template function cannot style a fragment whose base style "${style}" is not a style definition: a style name resolves only against the theme of a render`, { cause: err });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* rich-js template bindings — public entry point.
|
|
3
|
-
*
|
|
4
|
-
* [LAW:one-source-of-truth] This module is the public entry point for
|
|
5
|
-
* rich-js's styling vocabulary as `@promptctl/go-template-js` template
|
|
6
|
-
* functions. The split between the two exported registrations is exactly the
|
|
7
|
-
* split between what needs a theme and what does not:
|
|
8
|
-
*
|
|
9
|
-
* - `richTextFuncs()` — the colour sinks (`fg`/`bg`), the palette-free colour
|
|
10
|
-
* math (`darken`, `mix`, `contrastOn`, the OKLCH axes …), text attributes,
|
|
11
|
-
* and `link`. Needs no configuration; safe to register unconditionally. A
|
|
12
|
-
* consumer with no theme system still gets the complete colour vocabulary by
|
|
13
|
-
* feeding it hex literals.
|
|
14
|
-
* - `paletteFuncs(getPalette)` — `color` and `ramp`, the two functions that
|
|
15
|
-
* resolve a palette name. This is the *only* registration that knows a
|
|
16
|
-
* palette exists, which is why it is the only one that takes an argument.
|
|
17
|
-
* [LAW:one-way-deps]
|
|
18
|
-
*
|
|
19
|
-
* `createRichTextEngine()` wires up `richTextFuncs()` only — it cannot supply a
|
|
20
|
-
* palette. Consumers that name theme colours call `paletteFuncs(getPalette)`
|
|
21
|
-
* and merge it into their own engine config.
|
|
22
|
-
*
|
|
23
|
-
* Colours compose by nesting, like every other function:
|
|
24
|
-
* `{{ fg (darken (color "primary") 2) (bold "x") }}`. There is no second
|
|
25
|
-
* markup grammar and no colour-spec mini-language — the template *is* the
|
|
26
|
-
* composition mechanism.
|
|
27
|
-
*
|
|
28
|
-
* Fragment type: `RichText`. Chosen because it is the library's primary
|
|
29
|
-
* text type (implements `Renderable` + `Measurable`), composes via
|
|
30
|
-
* `append`, and flows directly into the existing render pipeline with no
|
|
31
|
-
* adapter. Top-level template expressions emit as `RichText[]` — natural
|
|
32
|
-
* for cases where a single template produces multiple independently
|
|
33
|
-
* addressable fragments (e.g. multiple top-level `link` calls, each
|
|
34
|
-
* carrying its own URL).
|
|
35
|
-
*/
|
|
36
|
-
import { type Engine, type FuncMap } from "@promptctl/go-template-js";
|
|
37
|
-
import { RichText } from "../core/text.js";
|
|
38
|
-
import { Segment } from "../core/segment.js";
|
|
39
|
-
import { ColorDepth } from "../core/color.js";
|
|
40
|
-
export { paletteFuncs } from "./palette-funcs.js";
|
|
41
|
-
export { colorFuncs, readableOnFunc } from "./color-funcs.js";
|
|
42
|
-
/**
|
|
43
|
-
* Funcs registered by the rich-js binding — the colour sinks, the palette-free
|
|
44
|
-
* colour math, text attributes, and the `link` cell-splitter. Nothing here
|
|
45
|
-
* needs a theme; the two that do (`color`, `ramp`) ship separately via
|
|
46
|
-
* `paletteFuncs(getPalette)`, merged consumer-side. `drawnAt` is forwarded to
|
|
47
|
-
* `colorFuncs` — the depth `readableOn` measures at, truecolor when omitted.
|
|
48
|
-
*
|
|
49
|
-
* `FuncMap` is not parameterised over `T` in `@promptctl/go-template-js` — the engine's
|
|
50
|
-
* `T` lives on the `Engine`/`EngineConfig`, and per-function input/output
|
|
51
|
-
* types are carried as runtime `argTypes` on each `TemplateFunc`. The map
|
|
52
|
-
* therefore *type-checks* against any `EngineConfig<T>.funcs`, but the
|
|
53
|
-
* functions returned here are only *runtime-compatible* with
|
|
54
|
-
* `Engine<RichText>`: each style function returns a `RichText` and
|
|
55
|
-
* requires its lifted child to be a `RichText` (enforced by an
|
|
56
|
-
* `instanceof` check that throws on misuse). Consumers merging this map
|
|
57
|
-
* into a wider engine must keep `T = RichText`; merging into an engine
|
|
58
|
-
* whose `T` is something else will compile but fail at evaluation time.
|
|
59
|
-
*/
|
|
60
|
-
export declare function richTextFuncs(drawnAt?: () => ColorDepth): FuncMap;
|
|
61
|
-
/**
|
|
62
|
-
* Construct an `Engine<RichText>` with the rich-js style-function set
|
|
63
|
-
* registered. Consumers that already manage their own engine should call
|
|
64
|
-
* `richTextFuncs()` and merge the result into their own `createEngine`
|
|
65
|
-
* configuration; consumers that just want rich-js styling can use this
|
|
66
|
-
* factory directly.
|
|
67
|
-
*
|
|
68
|
-
* `fromString` lifts text literals into `RichText`. `toString` flattens a
|
|
69
|
-
* `RichText` to its plain text — the engine's no-silent-flatten guard uses
|
|
70
|
-
* this only for `printf "%s"` / `"%q"` and `print*` slots, where ANSI is
|
|
71
|
-
* not desired anyway.
|
|
72
|
-
*/
|
|
73
|
-
export declare function createRichTextEngine(): Engine<RichText>;
|
|
74
|
-
/**
|
|
75
|
-
* Compile a template source against `engine` and render the result to a
|
|
76
|
-
* flat `Segment[]`. The 90%-case convenience over chaining `engine.compile`,
|
|
77
|
-
* `RichText.fromFragments`, and `.render` by hand:
|
|
78
|
-
*
|
|
79
|
-
* - Runs `engine.compile(source)(scope)` to get the engine's `RichText[]`.
|
|
80
|
-
* - Flattens that fragment list into a single styled `RichText` via
|
|
81
|
-
* `RichText.fromFragments` so every fragment's wrapping style survives.
|
|
82
|
-
* - Renders to a `Segment[]` at the requested `maxWidth`.
|
|
83
|
-
* - Wraps the whole flow in a try/catch — on parse/evaluate failure,
|
|
84
|
-
* emits a single dim styled `[error: <message>]` segment the caller can
|
|
85
|
-
* drop into their layout. No bespoke fallback wiring required at every
|
|
86
|
-
* call site.
|
|
87
|
-
*
|
|
88
|
-
* [LAW:single-enforcer] One place owns "render a template to segments,
|
|
89
|
-
* degrade gracefully on errors" — every consumer that wants this exact
|
|
90
|
-
* shape reads from here rather than re-implementing the same try/catch +
|
|
91
|
-
* error-formatting glue.
|
|
92
|
-
*
|
|
93
|
-
* For the 10% — custom error UX, intermediate access to the `RichText`,
|
|
94
|
-
* pre-compiled templates re-used many times — call the engine directly
|
|
95
|
-
* and use `RichText.fromFragments` to flatten. This helper is sugar for
|
|
96
|
-
* the live-render case (e.g. a preview pane), not a replacement for the
|
|
97
|
-
* compile-once-evaluate-many pattern.
|
|
98
|
-
*
|
|
99
|
-
* @param maxWidth defaults to 400 — large enough that downstream `splitLines`
|
|
100
|
-
* / `adjustLineLength` clipping decides actual width, matching the typical
|
|
101
|
-
* "render wide, fit on output" pipeline.
|
|
102
|
-
* @param errorStyle is a `Style.parse` spec (default `"red dim"`).
|
|
103
|
-
*/
|
|
104
|
-
export declare function renderTemplate(engine: Engine<RichText>, source: string, scope?: unknown, options?: {
|
|
105
|
-
maxWidth?: number;
|
|
106
|
-
errorStyle?: string;
|
|
107
|
-
}): Segment[];
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* rich-js template bindings — public entry point.
|
|
3
|
-
*
|
|
4
|
-
* [LAW:one-source-of-truth] This module is the public entry point for
|
|
5
|
-
* rich-js's styling vocabulary as `@promptctl/go-template-js` template
|
|
6
|
-
* functions. The split between the two exported registrations is exactly the
|
|
7
|
-
* split between what needs a theme and what does not:
|
|
8
|
-
*
|
|
9
|
-
* - `richTextFuncs()` — the colour sinks (`fg`/`bg`), the palette-free colour
|
|
10
|
-
* math (`darken`, `mix`, `contrastOn`, the OKLCH axes …), text attributes,
|
|
11
|
-
* and `link`. Needs no configuration; safe to register unconditionally. A
|
|
12
|
-
* consumer with no theme system still gets the complete colour vocabulary by
|
|
13
|
-
* feeding it hex literals.
|
|
14
|
-
* - `paletteFuncs(getPalette)` — `color` and `ramp`, the two functions that
|
|
15
|
-
* resolve a palette name. This is the *only* registration that knows a
|
|
16
|
-
* palette exists, which is why it is the only one that takes an argument.
|
|
17
|
-
* [LAW:one-way-deps]
|
|
18
|
-
*
|
|
19
|
-
* `createRichTextEngine()` wires up `richTextFuncs()` only — it cannot supply a
|
|
20
|
-
* palette. Consumers that name theme colours call `paletteFuncs(getPalette)`
|
|
21
|
-
* and merge it into their own engine config.
|
|
22
|
-
*
|
|
23
|
-
* Colours compose by nesting, like every other function:
|
|
24
|
-
* `{{ fg (darken (color "primary") 2) (bold "x") }}`. There is no second
|
|
25
|
-
* markup grammar and no colour-spec mini-language — the template *is* the
|
|
26
|
-
* composition mechanism.
|
|
27
|
-
*
|
|
28
|
-
* Fragment type: `RichText`. Chosen because it is the library's primary
|
|
29
|
-
* text type (implements `Renderable` + `Measurable`), composes via
|
|
30
|
-
* `append`, and flows directly into the existing render pipeline with no
|
|
31
|
-
* adapter. Top-level template expressions emit as `RichText[]` — natural
|
|
32
|
-
* for cases where a single template produces multiple independently
|
|
33
|
-
* addressable fragments (e.g. multiple top-level `link` calls, each
|
|
34
|
-
* carrying its own URL).
|
|
35
|
-
*/
|
|
36
|
-
import { createEngine } from "@promptctl/go-template-js";
|
|
37
|
-
import { RichText } from "../core/text.js";
|
|
38
|
-
import { Style } from "../core/style.js";
|
|
39
|
-
import { Segment } from "../core/segment.js";
|
|
40
|
-
import { richTextStyleFuncs } from "./style-funcs.js";
|
|
41
|
-
import { colorFuncs } from "./color-funcs.js";
|
|
42
|
-
export { paletteFuncs } from "./palette-funcs.js";
|
|
43
|
-
export { colorFuncs, readableOnFunc } from "./color-funcs.js";
|
|
44
|
-
/**
|
|
45
|
-
* Funcs registered by the rich-js binding — the colour sinks, the palette-free
|
|
46
|
-
* colour math, text attributes, and the `link` cell-splitter. Nothing here
|
|
47
|
-
* needs a theme; the two that do (`color`, `ramp`) ship separately via
|
|
48
|
-
* `paletteFuncs(getPalette)`, merged consumer-side. `drawnAt` is forwarded to
|
|
49
|
-
* `colorFuncs` — the depth `readableOn` measures at, truecolor when omitted.
|
|
50
|
-
*
|
|
51
|
-
* `FuncMap` is not parameterised over `T` in `@promptctl/go-template-js` — the engine's
|
|
52
|
-
* `T` lives on the `Engine`/`EngineConfig`, and per-function input/output
|
|
53
|
-
* types are carried as runtime `argTypes` on each `TemplateFunc`. The map
|
|
54
|
-
* therefore *type-checks* against any `EngineConfig<T>.funcs`, but the
|
|
55
|
-
* functions returned here are only *runtime-compatible* with
|
|
56
|
-
* `Engine<RichText>`: each style function returns a `RichText` and
|
|
57
|
-
* requires its lifted child to be a `RichText` (enforced by an
|
|
58
|
-
* `instanceof` check that throws on misuse). Consumers merging this map
|
|
59
|
-
* into a wider engine must keep `T = RichText`; merging into an engine
|
|
60
|
-
* whose `T` is something else will compile but fail at evaluation time.
|
|
61
|
-
*/
|
|
62
|
-
// [LAW:one-source-of-truth] The truecolor default lives on `colorFuncs` alone;
|
|
63
|
-
// an omitted `drawnAt` is forwarded as omitted.
|
|
64
|
-
export function richTextFuncs(drawnAt) {
|
|
65
|
-
return { ...richTextStyleFuncs(), ...colorFuncs(drawnAt) };
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Construct an `Engine<RichText>` with the rich-js style-function set
|
|
69
|
-
* registered. Consumers that already manage their own engine should call
|
|
70
|
-
* `richTextFuncs()` and merge the result into their own `createEngine`
|
|
71
|
-
* configuration; consumers that just want rich-js styling can use this
|
|
72
|
-
* factory directly.
|
|
73
|
-
*
|
|
74
|
-
* `fromString` lifts text literals into `RichText`. `toString` flattens a
|
|
75
|
-
* `RichText` to its plain text — the engine's no-silent-flatten guard uses
|
|
76
|
-
* this only for `printf "%s"` / `"%q"` and `print*` slots, where ANSI is
|
|
77
|
-
* not desired anyway.
|
|
78
|
-
*/
|
|
79
|
-
export function createRichTextEngine() {
|
|
80
|
-
return createEngine({
|
|
81
|
-
fromString: (s) => new RichText(s),
|
|
82
|
-
toString: (rt) => rt.plain,
|
|
83
|
-
funcs: richTextFuncs(),
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Compile a template source against `engine` and render the result to a
|
|
88
|
-
* flat `Segment[]`. The 90%-case convenience over chaining `engine.compile`,
|
|
89
|
-
* `RichText.fromFragments`, and `.render` by hand:
|
|
90
|
-
*
|
|
91
|
-
* - Runs `engine.compile(source)(scope)` to get the engine's `RichText[]`.
|
|
92
|
-
* - Flattens that fragment list into a single styled `RichText` via
|
|
93
|
-
* `RichText.fromFragments` so every fragment's wrapping style survives.
|
|
94
|
-
* - Renders to a `Segment[]` at the requested `maxWidth`.
|
|
95
|
-
* - Wraps the whole flow in a try/catch — on parse/evaluate failure,
|
|
96
|
-
* emits a single dim styled `[error: <message>]` segment the caller can
|
|
97
|
-
* drop into their layout. No bespoke fallback wiring required at every
|
|
98
|
-
* call site.
|
|
99
|
-
*
|
|
100
|
-
* [LAW:single-enforcer] One place owns "render a template to segments,
|
|
101
|
-
* degrade gracefully on errors" — every consumer that wants this exact
|
|
102
|
-
* shape reads from here rather than re-implementing the same try/catch +
|
|
103
|
-
* error-formatting glue.
|
|
104
|
-
*
|
|
105
|
-
* For the 10% — custom error UX, intermediate access to the `RichText`,
|
|
106
|
-
* pre-compiled templates re-used many times — call the engine directly
|
|
107
|
-
* and use `RichText.fromFragments` to flatten. This helper is sugar for
|
|
108
|
-
* the live-render case (e.g. a preview pane), not a replacement for the
|
|
109
|
-
* compile-once-evaluate-many pattern.
|
|
110
|
-
*
|
|
111
|
-
* @param maxWidth defaults to 400 — large enough that downstream `splitLines`
|
|
112
|
-
* / `adjustLineLength` clipping decides actual width, matching the typical
|
|
113
|
-
* "render wide, fit on output" pipeline.
|
|
114
|
-
* @param errorStyle is a `Style.parse` spec (default `"red dim"`).
|
|
115
|
-
*/
|
|
116
|
-
export function renderTemplate(engine, source, scope = {}, options) {
|
|
117
|
-
try {
|
|
118
|
-
const frags = engine.compile(source)(scope);
|
|
119
|
-
const rt = RichText.fromFragments(frags);
|
|
120
|
-
return Array.from(rt.render({
|
|
121
|
-
maxWidth: options?.maxWidth ?? 400,
|
|
122
|
-
isTerminal: true,
|
|
123
|
-
encoding: "utf-8",
|
|
124
|
-
}));
|
|
125
|
-
}
|
|
126
|
-
catch (e) {
|
|
127
|
-
return [new Segment(`[error: ${String(e).slice(0, 80)}]`, safeErrorStyle(options?.errorStyle))];
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
// [LAW:single-enforcer] The error-path Style must not itself throw, or
|
|
131
|
-
// the whole "degrade gracefully" promise of renderTemplate is broken. A
|
|
132
|
-
// bogus user-supplied `errorStyle` spec falls back to a hard-coded safe
|
|
133
|
-
// Style — never propagates the parse failure to the caller.
|
|
134
|
-
const FALLBACK_ERROR_STYLE = new Style({ color: "red", dim: true });
|
|
135
|
-
function safeErrorStyle(spec) {
|
|
136
|
-
if (spec === undefined)
|
|
137
|
-
return FALLBACK_ERROR_STYLE;
|
|
138
|
-
try {
|
|
139
|
-
return Style.parse(spec);
|
|
140
|
-
}
|
|
141
|
-
catch {
|
|
142
|
-
return FALLBACK_ERROR_STYLE;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The palette-dependent template functions: `color`, and `ramp` whose stops
|
|
3
|
-
* are color references.
|
|
4
|
-
*
|
|
5
|
-
* ### Why `color` is the one name resolver
|
|
6
|
-
*
|
|
7
|
-
* This module used to register four kinds of thing: one function per
|
|
8
|
-
* identifier-safe palette variable (`{{ primary child }}`, `{{ accent child }}`,
|
|
9
|
-
* …), a general `palette "spec" child`, a `paletteOver "spec" "#bg" child` for
|
|
10
|
-
* specs needing a background, and an `auto "#bg" child` sugar. That surface had
|
|
11
|
-
* two defects worth recording, because both are easy to reintroduce.
|
|
12
|
-
*
|
|
13
|
-
* **The name family could not cover its own domain.** A themed palette carries
|
|
14
|
-
* ~150 variables; roughly 14 of them are legal Go-template identifiers. So the
|
|
15
|
-
* generated functions reached under a tenth of the palette, and the other nine
|
|
16
|
-
* tenths needed `palette "text-primary" child` — a *different expression shape*
|
|
17
|
-
* for the same intent. An author who learned `{{ primary x }}` and reasonably
|
|
18
|
-
* tried `{{ text_primary x }}` got a FuncNotFound. [LAW:composability] — the
|
|
19
|
-
* `filterByStatus`/`filterByOwner` shape: names cannot enumerate a domain, and
|
|
20
|
-
* the N+1 case always needs a form you have to learn separately.
|
|
21
|
-
*
|
|
22
|
-
* **Resolution and application were fused.** Every one of those functions
|
|
23
|
-
* consumed its color instantly into a styled fragment, so a color could never
|
|
24
|
-
* be held or passed. Composition therefore had to happen inside the spec
|
|
25
|
-
* *string* — hence the old `name-darken-N alpha%` grammar. See
|
|
26
|
-
* `color-funcs.ts` for the full argument; the short version is that a string
|
|
27
|
-
* grammar is function application with the function calls spelled as
|
|
28
|
-
* punctuation, and it grows a new production for every operation.
|
|
29
|
-
*
|
|
30
|
-
* What replaces all of it: `color "name-or-hex"` produces a color value, the
|
|
31
|
-
* functions in `color-funcs.ts` transform colors, and `fg`/`bg` in
|
|
32
|
-
* `style-funcs.ts` paint them. One shape, total over the palette, open to
|
|
33
|
-
* arbitrary composition. [LAW:one-type-per-behavior]
|
|
34
|
-
*
|
|
35
|
-
* ### Why `ramp` lives here and not with the color math
|
|
36
|
-
*
|
|
37
|
-
* `ramp` is the one function whose input is a *number*, and its stops are
|
|
38
|
-
* spelled as color references — `ramp .pct "step" 0 "panel" 50 "warning" 80
|
|
39
|
-
* "error"` — resolved through the same `resolveColorRef` that `color` crosses.
|
|
40
|
-
* Requiring `(color "panel")` around every stop would put the boilerplate
|
|
41
|
-
* back that this binding exists to remove, and an author who writes a hex
|
|
42
|
-
* literal loses nothing: the resolver is idempotent on hex. The arithmetic
|
|
43
|
-
* itself is `ColorRamp` in `themes/ramp.ts`, palette-free; only the
|
|
44
|
-
* reference resolution is here. [LAW:one-way-deps]
|
|
45
|
-
*
|
|
46
|
-
* ### Why a getter, not a palette
|
|
47
|
-
*
|
|
48
|
-
* `paletteFuncs` takes `() => Palette` rather than a `Palette`. A consumer
|
|
49
|
-
* whose theme can change at runtime (a live preview, a theme picker, a
|
|
50
|
-
* status-line that recolors on click) would otherwise be frozen to whichever
|
|
51
|
-
* palette happened to be current when the engine was constructed — and since
|
|
52
|
-
* templates are parsed once and evaluated many times, that freeze outlives
|
|
53
|
-
* every subsequent theme change while the *rest* of the consumer's colors move
|
|
54
|
-
* on. Two palettes, one render: [LAW:one-source-of-truth] violated by a
|
|
55
|
-
* captured reference.
|
|
56
|
-
*
|
|
57
|
-
* The getter costs nothing structurally. `FuncMap` entries are data in the
|
|
58
|
-
* engine and their bodies run at *evaluate* time, so reading the palette
|
|
59
|
-
* through a getter leaves parse-once/evaluate-many completely intact. What the
|
|
60
|
-
* getter must not change is *which functions exist* — and it cannot, because
|
|
61
|
-
* the two names here do not depend on the palette's contents. That was not
|
|
62
|
-
* true of the generated per-variable functions, which is the second reason
|
|
63
|
-
* they are gone.
|
|
64
|
-
*/
|
|
65
|
-
import type { FuncMap } from "@promptctl/go-template-js";
|
|
66
|
-
import type { Palette } from "../themes/palette.js";
|
|
67
|
-
/**
|
|
68
|
-
* Register `color "name-or-hex"` against a live palette.
|
|
69
|
-
*
|
|
70
|
-
* `color` resolves a palette variable name to a `#RRGGBB` string, and passes
|
|
71
|
-
* an already-literal color through unchanged. That second half is not a
|
|
72
|
-
* convenience — it makes `color` **idempotent**, which is what lets consumers
|
|
73
|
-
* apply it unconditionally to any author-written color string without first
|
|
74
|
-
* asking whether it is a name or already a color. [LAW:dataflow-not-control-flow]
|
|
75
|
-
*
|
|
76
|
-
* An unknown name throws, carrying near-miss suggestions from the live
|
|
77
|
-
* palette. In a template that surfaces as an evaluation error at the exact
|
|
78
|
-
* call site, which is the signal an author (or an agent editing a config) needs
|
|
79
|
-
* to fix it. [LAW:no-silent-failure]
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* ```ts
|
|
83
|
-
* const engine = createEngine({
|
|
84
|
-
* fromString: (s) => new RichText(s),
|
|
85
|
-
* toString: (rt) => rt.plain,
|
|
86
|
-
* funcs: {
|
|
87
|
-
* ...richTextFuncs(),
|
|
88
|
-
* ...colorFuncs(),
|
|
89
|
-
* ...paletteFuncs(() => currentTheme.palette),
|
|
90
|
-
* },
|
|
91
|
-
* });
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
export declare function paletteFuncs(getPalette: () => Palette): FuncMap;
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The palette-dependent template functions: `color`, and `ramp` whose stops
|
|
3
|
-
* are color references.
|
|
4
|
-
*
|
|
5
|
-
* ### Why `color` is the one name resolver
|
|
6
|
-
*
|
|
7
|
-
* This module used to register four kinds of thing: one function per
|
|
8
|
-
* identifier-safe palette variable (`{{ primary child }}`, `{{ accent child }}`,
|
|
9
|
-
* …), a general `palette "spec" child`, a `paletteOver "spec" "#bg" child` for
|
|
10
|
-
* specs needing a background, and an `auto "#bg" child` sugar. That surface had
|
|
11
|
-
* two defects worth recording, because both are easy to reintroduce.
|
|
12
|
-
*
|
|
13
|
-
* **The name family could not cover its own domain.** A themed palette carries
|
|
14
|
-
* ~150 variables; roughly 14 of them are legal Go-template identifiers. So the
|
|
15
|
-
* generated functions reached under a tenth of the palette, and the other nine
|
|
16
|
-
* tenths needed `palette "text-primary" child` — a *different expression shape*
|
|
17
|
-
* for the same intent. An author who learned `{{ primary x }}` and reasonably
|
|
18
|
-
* tried `{{ text_primary x }}` got a FuncNotFound. [LAW:composability] — the
|
|
19
|
-
* `filterByStatus`/`filterByOwner` shape: names cannot enumerate a domain, and
|
|
20
|
-
* the N+1 case always needs a form you have to learn separately.
|
|
21
|
-
*
|
|
22
|
-
* **Resolution and application were fused.** Every one of those functions
|
|
23
|
-
* consumed its color instantly into a styled fragment, so a color could never
|
|
24
|
-
* be held or passed. Composition therefore had to happen inside the spec
|
|
25
|
-
* *string* — hence the old `name-darken-N alpha%` grammar. See
|
|
26
|
-
* `color-funcs.ts` for the full argument; the short version is that a string
|
|
27
|
-
* grammar is function application with the function calls spelled as
|
|
28
|
-
* punctuation, and it grows a new production for every operation.
|
|
29
|
-
*
|
|
30
|
-
* What replaces all of it: `color "name-or-hex"` produces a color value, the
|
|
31
|
-
* functions in `color-funcs.ts` transform colors, and `fg`/`bg` in
|
|
32
|
-
* `style-funcs.ts` paint them. One shape, total over the palette, open to
|
|
33
|
-
* arbitrary composition. [LAW:one-type-per-behavior]
|
|
34
|
-
*
|
|
35
|
-
* ### Why `ramp` lives here and not with the color math
|
|
36
|
-
*
|
|
37
|
-
* `ramp` is the one function whose input is a *number*, and its stops are
|
|
38
|
-
* spelled as color references — `ramp .pct "step" 0 "panel" 50 "warning" 80
|
|
39
|
-
* "error"` — resolved through the same `resolveColorRef` that `color` crosses.
|
|
40
|
-
* Requiring `(color "panel")` around every stop would put the boilerplate
|
|
41
|
-
* back that this binding exists to remove, and an author who writes a hex
|
|
42
|
-
* literal loses nothing: the resolver is idempotent on hex. The arithmetic
|
|
43
|
-
* itself is `ColorRamp` in `themes/ramp.ts`, palette-free; only the
|
|
44
|
-
* reference resolution is here. [LAW:one-way-deps]
|
|
45
|
-
*
|
|
46
|
-
* ### Why a getter, not a palette
|
|
47
|
-
*
|
|
48
|
-
* `paletteFuncs` takes `() => Palette` rather than a `Palette`. A consumer
|
|
49
|
-
* whose theme can change at runtime (a live preview, a theme picker, a
|
|
50
|
-
* status-line that recolors on click) would otherwise be frozen to whichever
|
|
51
|
-
* palette happened to be current when the engine was constructed — and since
|
|
52
|
-
* templates are parsed once and evaluated many times, that freeze outlives
|
|
53
|
-
* every subsequent theme change while the *rest* of the consumer's colors move
|
|
54
|
-
* on. Two palettes, one render: [LAW:one-source-of-truth] violated by a
|
|
55
|
-
* captured reference.
|
|
56
|
-
*
|
|
57
|
-
* The getter costs nothing structurally. `FuncMap` entries are data in the
|
|
58
|
-
* engine and their bodies run at *evaluate* time, so reading the palette
|
|
59
|
-
* through a getter leaves parse-once/evaluate-many completely intact. What the
|
|
60
|
-
* getter must not change is *which functions exist* — and it cannot, because
|
|
61
|
-
* the two names here do not depend on the palette's contents. That was not
|
|
62
|
-
* true of the generated per-variable functions, which is the second reason
|
|
63
|
-
* they are gone.
|
|
64
|
-
*/
|
|
65
|
-
import { resolveColorRef } from "../themes/colorRef.js";
|
|
66
|
-
import { ColorRamp, parseRampEasing } from "../themes/ramp.js";
|
|
67
|
-
/**
|
|
68
|
-
* The `(position, color-ref)` pairs a `ramp` call's tail spells, as stops.
|
|
69
|
-
*
|
|
70
|
-
* The engine's `alternating` gate has already typed every even slot as a
|
|
71
|
-
* float and every odd slot as a string; what it cannot see is the *pairing*
|
|
72
|
-
* — a trailing position with no color — nor that the string is a color
|
|
73
|
-
* reference. Both are settled here, once, and `ColorRamp` receives resolved
|
|
74
|
-
* stops it never re-checks. [LAW:parse-dont-validate]
|
|
75
|
-
*
|
|
76
|
-
* Each reference resolves against the palette of *this* evaluation, so a
|
|
77
|
-
* ramp over palette names follows the theme exactly as `color` does.
|
|
78
|
-
*/
|
|
79
|
-
function colorStops(tail, palette) {
|
|
80
|
-
if (tail.length === 0) {
|
|
81
|
-
throw new RangeError(`ramp needs at least one stop after the easing: ramp <value> <easing> <position> <color> …`);
|
|
82
|
-
}
|
|
83
|
-
if (tail.length % 2 !== 0) {
|
|
84
|
-
throw new RangeError(`ramp's last stop (position ${String(tail[tail.length - 1])}) has no color — ` +
|
|
85
|
-
`stops are <position> <color> pairs`);
|
|
86
|
-
}
|
|
87
|
-
const stops = [];
|
|
88
|
-
for (let i = 0; i < tail.length; i += 2) {
|
|
89
|
-
stops.push({
|
|
90
|
-
at: tail[i],
|
|
91
|
-
color: resolveColorRef(palette, tail[i + 1]),
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
return stops;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Register `color "name-or-hex"` against a live palette.
|
|
98
|
-
*
|
|
99
|
-
* `color` resolves a palette variable name to a `#RRGGBB` string, and passes
|
|
100
|
-
* an already-literal color through unchanged. That second half is not a
|
|
101
|
-
* convenience — it makes `color` **idempotent**, which is what lets consumers
|
|
102
|
-
* apply it unconditionally to any author-written color string without first
|
|
103
|
-
* asking whether it is a name or already a color. [LAW:dataflow-not-control-flow]
|
|
104
|
-
*
|
|
105
|
-
* An unknown name throws, carrying near-miss suggestions from the live
|
|
106
|
-
* palette. In a template that surfaces as an evaluation error at the exact
|
|
107
|
-
* call site, which is the signal an author (or an agent editing a config) needs
|
|
108
|
-
* to fix it. [LAW:no-silent-failure]
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* ```ts
|
|
112
|
-
* const engine = createEngine({
|
|
113
|
-
* fromString: (s) => new RichText(s),
|
|
114
|
-
* toString: (rt) => rt.plain,
|
|
115
|
-
* funcs: {
|
|
116
|
-
* ...richTextFuncs(),
|
|
117
|
-
* ...colorFuncs(),
|
|
118
|
-
* ...paletteFuncs(() => currentTheme.palette),
|
|
119
|
-
* },
|
|
120
|
-
* });
|
|
121
|
-
* ```
|
|
122
|
-
*/
|
|
123
|
-
export function paletteFuncs(getPalette) {
|
|
124
|
-
const colorFunc = {
|
|
125
|
-
fn: ((ref) => resolveColorRef(getPalette(), ref).hex),
|
|
126
|
-
argTypes: ["string"],
|
|
127
|
-
returnType: "string",
|
|
128
|
-
};
|
|
129
|
-
// `ramp <value> <easing> <position> <color> …` — the argument list is one
|
|
130
|
-
// float/string cycle end to end (value, easing, then each stop's position
|
|
131
|
-
// and color), so the engine's `alternating` gate types every slot; the
|
|
132
|
-
// pairing and the references are parsed in `colorStops`.
|
|
133
|
-
// [LAW:types-are-the-program]
|
|
134
|
-
const rampFunc = {
|
|
135
|
-
fn: ((...args) => {
|
|
136
|
-
// The engine's `alternating` gate types each slot but sets no minimum
|
|
137
|
-
// count, so `{{ ramp }}` and `{{ ramp 65 }}` both reach here: one
|
|
138
|
-
// check over the whole list, naming what is missing. [LAW:no-silent-failure]
|
|
139
|
-
if (args.length < 2) {
|
|
140
|
-
throw new RangeError(`ramp needs a value and an easing before its stops (got ${args.length}): ` +
|
|
141
|
-
`ramp <value> "linear"|"step" <position> <color> …`);
|
|
142
|
-
}
|
|
143
|
-
const [value, easing, ...tail] = args;
|
|
144
|
-
return new ColorRamp(parseRampEasing(easing), colorStops(tail, getPalette())).at(value).hex;
|
|
145
|
-
}),
|
|
146
|
-
argTypes: ["float", "string"],
|
|
147
|
-
argTypePattern: "alternating",
|
|
148
|
-
returnType: "string",
|
|
149
|
-
};
|
|
150
|
-
return { color: colorFunc, ramp: rampFunc };
|
|
151
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Style-function registrations for the rich-js template binding.
|
|
3
|
-
*
|
|
4
|
-
* [LAW:one-source-of-truth] The function inventory below mirrors the
|
|
5
|
-
* string-syntax style vocabulary documented in `docs/style.md` — the two
|
|
6
|
-
* colour slots (`fg`/`bg`), text attributes (positive + negated), short
|
|
7
|
-
* aliases, and the hyperlink. Each registration is a templating-time analogue
|
|
8
|
-
* of a piece of `Style.parse`, so a template fragment composed by these
|
|
9
|
-
* functions round-trips through `Style` without semantic drift.
|
|
10
|
-
*
|
|
11
|
-
* [LAW:dataflow-not-control-flow] Every function follows the same
|
|
12
|
-
* shape: child `RichText` in, `RichText` out. The styling difference
|
|
13
|
-
* lives in a captured `Style` value (or constructor closure), not in
|
|
14
|
-
* branches inside a single dispatch. That is why this file is mostly
|
|
15
|
-
* factories — the data (the colour, the attribute name) is the
|
|
16
|
-
* variability; the operation is fixed.
|
|
17
|
-
*/
|
|
18
|
-
import type { FuncMap } from "@promptctl/go-template-js";
|
|
19
|
-
/**
|
|
20
|
-
* Text-styling registrations: the two colour sinks (`fg`, `bg`), text
|
|
21
|
-
* attributes (canonical names, short aliases, and `not_*` negations), the
|
|
22
|
-
* hyperlink cell-splitter (`link`), and the multi-attribute `style` spec.
|
|
23
|
-
*
|
|
24
|
-
* Colours themselves come from elsewhere: `colorFuncs()` for the palette-free
|
|
25
|
-
* math, `paletteFuncs()` for naming a theme colour. This module only paints.
|
|
26
|
-
* [LAW:one-way-deps] — nothing here imports a palette.
|
|
27
|
-
*/
|
|
28
|
-
export declare function richTextStyleFuncs(): FuncMap;
|