@promptctl/rich-js 0.18.0 → 0.19.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 +9 -7
- package/dist/core/anchor.d.ts +45 -0
- package/dist/core/anchor.js +39 -0
- package/dist/core/ansi.d.ts +65 -0
- package/dist/core/ansi.js +231 -0
- package/dist/core/box.d.ts +145 -0
- package/dist/core/box.js +372 -0
- package/dist/core/cells.d.ts +192 -0
- package/dist/core/cells.js +334 -0
- package/dist/core/clock.d.ts +48 -0
- package/dist/core/clock.js +42 -0
- package/dist/core/color.d.ts +326 -0
- package/dist/core/color.js +1225 -0
- package/dist/core/console.d.ts +196 -0
- package/dist/core/console.js +596 -0
- package/dist/core/easing.d.ts +86 -0
- package/dist/core/easing.js +171 -0
- package/dist/core/emoji.d.ts +24 -0
- package/dist/core/emoji.js +391 -0
- package/dist/core/env.d.ts +16 -0
- package/dist/core/env.js +16 -0
- package/dist/core/export-html.d.ts +59 -0
- package/dist/core/export-html.js +197 -0
- package/dist/core/export-lines.d.ts +130 -0
- package/dist/core/export-lines.js +159 -0
- package/dist/core/export-svg.d.ts +49 -0
- package/dist/core/export-svg.js +213 -0
- package/dist/core/fnv1a.d.ts +10 -0
- package/dist/core/fnv1a.js +17 -0
- package/dist/core/highlighter.d.ts +33 -0
- package/dist/core/highlighter.js +190 -0
- package/dist/core/json.d.ts +27 -0
- package/dist/core/json.js +53 -0
- package/dist/core/markup.d.ts +140 -0
- package/dist/core/markup.js +654 -0
- package/dist/core/measure.d.ts +27 -0
- package/dist/core/measure.js +67 -0
- package/dist/core/memo.d.ts +19 -0
- package/dist/core/memo.js +34 -0
- package/dist/core/oklch.d.ts +161 -0
- package/dist/core/oklch.js +312 -0
- package/dist/core/osc8.d.ts +68 -0
- package/dist/core/osc8.js +78 -0
- package/dist/core/paint.d.ts +107 -0
- package/dist/core/paint.js +150 -0
- package/dist/core/place.d.ts +30 -0
- package/dist/core/place.js +49 -0
- package/dist/core/pretty.d.ts +247 -0
- package/dist/core/pretty.js +906 -0
- package/dist/core/protocol.d.ts +305 -0
- package/dist/core/protocol.js +183 -0
- package/dist/core/render.d.ts +87 -0
- package/dist/core/render.js +105 -0
- package/dist/core/segment.d.ts +162 -0
- package/dist/core/segment.js +488 -0
- package/dist/core/spinnerData.d.ts +12 -0
- package/dist/core/spinnerData.js +117 -0
- package/dist/core/strip.d.ts +152 -0
- package/dist/core/strip.js +326 -0
- package/dist/core/style.d.ts +189 -0
- package/dist/core/style.js +758 -0
- package/dist/core/subscription.d.ts +12 -0
- package/dist/core/subscription.js +12 -0
- package/dist/core/text.d.ts +283 -0
- package/dist/core/text.js +1097 -0
- package/dist/core/wrap.d.ts +46 -0
- package/dist/core/wrap.js +140 -0
- package/dist/host/app.d.ts +133 -0
- package/dist/host/app.js +285 -0
- package/dist/host/host-environment.d.ts +26 -0
- package/dist/host/host-environment.js +44 -0
- package/dist/host/index.d.ts +6 -0
- package/dist/host/index.js +3 -0
- package/dist/host/terminal-host.d.ts +180 -0
- package/dist/host/terminal-host.js +186 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.js +114 -0
- package/dist/node/prompt.d.ts +34 -0
- package/dist/node/prompt.js +51 -0
- package/dist/node/save.d.ts +18 -0
- package/dist/node/save.js +24 -0
- package/dist/node/terminal-host.d.ts +114 -0
- package/dist/node/terminal-host.js +227 -0
- package/dist/node/traceback.d.ts +38 -0
- package/dist/node/traceback.js +98 -0
- package/dist/renderables/align.d.ts +16 -0
- package/dist/renderables/align.js +26 -0
- package/dist/renderables/columns.d.ts +77 -0
- package/dist/renderables/columns.js +191 -0
- package/dist/renderables/constrain.d.ts +15 -0
- package/dist/renderables/constrain.js +31 -0
- package/dist/renderables/effect.d.ts +98 -0
- package/dist/renderables/effect.js +160 -0
- package/dist/renderables/embed.d.ts +107 -0
- package/dist/renderables/embed.js +160 -0
- package/dist/renderables/flexStrip.d.ts +41 -0
- package/dist/renderables/flexStrip.js +200 -0
- package/dist/renderables/group.d.ts +14 -0
- package/dist/renderables/group.js +22 -0
- package/dist/renderables/layout.d.ts +75 -0
- package/dist/renderables/layout.js +223 -0
- package/dist/renderables/live.d.ts +74 -0
- package/dist/renderables/live.js +188 -0
- package/dist/renderables/markdown.d.ts +38 -0
- package/dist/renderables/markdown.js +587 -0
- package/dist/renderables/padding.d.ts +59 -0
- package/dist/renderables/padding.js +147 -0
- package/dist/renderables/panel.d.ts +114 -0
- package/dist/renderables/panel.js +303 -0
- package/dist/renderables/progress.d.ts +178 -0
- package/dist/renderables/progress.js +362 -0
- package/dist/renderables/progressBar.d.ts +31 -0
- package/dist/renderables/progressBar.js +64 -0
- package/dist/renderables/prompt.d.ts +71 -0
- package/dist/renderables/prompt.js +165 -0
- package/dist/renderables/ratio.d.ts +123 -0
- package/dist/renderables/ratio.js +213 -0
- package/dist/renderables/rule.d.ts +26 -0
- package/dist/renderables/rule.js +86 -0
- package/dist/renderables/spinner.d.ts +57 -0
- package/dist/renderables/spinner.js +103 -0
- package/dist/renderables/status.d.ts +29 -0
- package/dist/renderables/status.js +46 -0
- package/dist/renderables/syntax.d.ts +65 -0
- package/dist/renderables/syntax.js +166 -0
- package/dist/renderables/table.d.ts +232 -0
- package/dist/renderables/table.js +973 -0
- package/dist/renderables/traceback.d.ts +32 -0
- package/dist/renderables/traceback.js +279 -0
- package/dist/renderables/tree.d.ts +76 -0
- package/dist/renderables/tree.js +177 -0
- package/dist/renderables/viewport.d.ts +114 -0
- package/dist/renderables/viewport.js +196 -0
- package/dist/template-bindings/color-funcs.d.ts +109 -0
- package/dist/template-bindings/color-funcs.js +243 -0
- package/dist/template-bindings/helpers.d.ts +26 -0
- package/dist/template-bindings/helpers.js +33 -0
- package/dist/template-bindings/index.d.ts +119 -0
- package/dist/template-bindings/index.js +162 -0
- package/dist/template-bindings/palette-funcs.d.ts +96 -0
- package/dist/template-bindings/palette-funcs.js +145 -0
- package/dist/template-bindings/style-funcs.d.ts +28 -0
- package/dist/template-bindings/style-funcs.js +157 -0
- package/dist/themes/buildPalette.d.ts +57 -0
- package/dist/themes/buildPalette.js +100 -0
- package/dist/themes/colorMath.d.ts +94 -0
- package/dist/themes/colorMath.js +280 -0
- package/dist/themes/colorRef.d.ts +36 -0
- package/dist/themes/colorRef.js +78 -0
- package/dist/themes/data/ansi-tables.d.ts +14 -0
- package/dist/themes/data/ansi-tables.js +49 -0
- package/dist/themes/data/atom-one-dark.d.ts +3 -0
- package/dist/themes/data/atom-one-dark.js +177 -0
- package/dist/themes/data/atom-one-light.d.ts +3 -0
- package/dist/themes/data/atom-one-light.js +177 -0
- package/dist/themes/data/catppuccin-frappe.d.ts +3 -0
- package/dist/themes/data/catppuccin-frappe.js +177 -0
- package/dist/themes/data/catppuccin-latte.d.ts +3 -0
- package/dist/themes/data/catppuccin-latte.js +177 -0
- package/dist/themes/data/catppuccin-macchiato.d.ts +3 -0
- package/dist/themes/data/catppuccin-macchiato.js +177 -0
- package/dist/themes/data/catppuccin-mocha.d.ts +3 -0
- package/dist/themes/data/catppuccin-mocha.js +177 -0
- package/dist/themes/data/cyberpunk.d.ts +17 -0
- package/dist/themes/data/cyberpunk.js +193 -0
- package/dist/themes/data/default.d.ts +3 -0
- package/dist/themes/data/default.js +160 -0
- package/dist/themes/data/dracula.d.ts +3 -0
- package/dist/themes/data/dracula.js +177 -0
- package/dist/themes/data/flexoki.d.ts +3 -0
- package/dist/themes/data/flexoki.js +177 -0
- package/dist/themes/data/gruvbox.d.ts +3 -0
- package/dist/themes/data/gruvbox.js +177 -0
- package/dist/themes/data/index.d.ts +35 -0
- package/dist/themes/data/index.js +64 -0
- package/dist/themes/data/monokai.d.ts +3 -0
- package/dist/themes/data/monokai.js +177 -0
- package/dist/themes/data/nord.d.ts +3 -0
- package/dist/themes/data/nord.js +177 -0
- package/dist/themes/data/rose-pine-dawn.d.ts +3 -0
- package/dist/themes/data/rose-pine-dawn.js +177 -0
- package/dist/themes/data/rose-pine-moon.d.ts +3 -0
- package/dist/themes/data/rose-pine-moon.js +177 -0
- package/dist/themes/data/rose-pine.d.ts +3 -0
- package/dist/themes/data/rose-pine.js +177 -0
- package/dist/themes/data/solarized-dark.d.ts +3 -0
- package/dist/themes/data/solarized-dark.js +177 -0
- package/dist/themes/data/solarized-light.d.ts +3 -0
- package/dist/themes/data/solarized-light.js +177 -0
- package/dist/themes/data/svg-export.d.ts +3 -0
- package/dist/themes/data/svg-export.js +177 -0
- package/dist/themes/data/textual-ansi.d.ts +3 -0
- package/dist/themes/data/textual-ansi.js +160 -0
- package/dist/themes/data/textual-dark.d.ts +3 -0
- package/dist/themes/data/textual-dark.js +160 -0
- package/dist/themes/data/textual-light.d.ts +3 -0
- package/dist/themes/data/textual-light.js +160 -0
- package/dist/themes/data/tokyo-night.d.ts +3 -0
- package/dist/themes/data/tokyo-night.js +177 -0
- package/dist/themes/data/types.d.ts +31 -0
- package/dist/themes/data/types.js +10 -0
- package/dist/themes/palette.d.ts +45 -0
- package/dist/themes/palette.js +71 -0
- package/dist/themes/ramp.d.ts +70 -0
- package/dist/themes/ramp.js +103 -0
- package/dist/themes/registry.d.ts +44 -0
- package/dist/themes/registry.js +105 -0
- package/dist/themes/terminalThemes.d.ts +49 -0
- package/dist/themes/terminalThemes.js +63 -0
- package/dist/themes/transpose.d.ts +87 -0
- package/dist/themes/transpose.js +138 -0
- package/dist/widgets/button.d.ts +45 -0
- package/dist/widgets/button.js +177 -0
- package/dist/widgets/checkbox.d.ts +38 -0
- package/dist/widgets/checkbox.js +135 -0
- package/dist/widgets/dropdown.d.ts +64 -0
- package/dist/widgets/dropdown.js +416 -0
- package/dist/widgets/event-router.d.ts +71 -0
- package/dist/widgets/event-router.js +629 -0
- package/dist/widgets/focus-manager.d.ts +45 -0
- package/dist/widgets/focus-manager.js +191 -0
- package/dist/widgets/hit.d.ts +64 -0
- package/dist/widgets/hit.js +113 -0
- package/dist/widgets/index.d.ts +20 -0
- package/dist/widgets/index.js +14 -0
- package/dist/widgets/ink.d.ts +22 -0
- package/dist/widgets/ink.js +31 -0
- package/dist/widgets/slider.d.ts +54 -0
- package/dist/widgets/slider.js +247 -0
- package/dist/widgets/static-item.d.ts +34 -0
- package/dist/widgets/static-item.js +54 -0
- package/dist/widgets/text-input.d.ts +283 -0
- package/dist/widgets/text-input.js +1174 -0
- package/dist/widgets/themed-widget.d.ts +20 -0
- package/dist/widgets/themed-widget.js +89 -0
- package/dist/widgets/toggle.d.ts +41 -0
- package/dist/widgets/toggle.js +157 -0
- package/dist/widgets/types.d.ts +87 -0
- package/dist/widgets/types.js +30 -0
- package/dist/widgets/widget-app.d.ts +65 -0
- package/dist/widgets/widget-app.js +206 -0
- package/dist/widgets/widget-base.d.ts +42 -0
- package/dist/widgets/widget-base.js +172 -0
- package/package.json +16 -2
|
@@ -0,0 +1,119 @@
|
|
|
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 type { RenderOptions } from "../core/protocol.js";
|
|
40
|
+
import { type DrawnAt } from "./color-funcs.js";
|
|
41
|
+
export { paletteFuncs } from "./palette-funcs.js";
|
|
42
|
+
export { colorFuncs, readableOnFunc, type DrawnAt } from "./color-funcs.js";
|
|
43
|
+
/**
|
|
44
|
+
* Funcs registered by the rich-js binding — the colour sinks, the palette-free
|
|
45
|
+
* colour math, text attributes, and the `link` cell-splitter. Nothing here
|
|
46
|
+
* needs a theme; the two that do (`color`, `ramp`) ship separately via
|
|
47
|
+
* `paletteFuncs(getPalette)`, merged consumer-side. `drawnAt` is forwarded to
|
|
48
|
+
* `colorFuncs` — the depth `readableOn` measures at, truecolor when omitted.
|
|
49
|
+
*
|
|
50
|
+
* `FuncMap` is not parameterised over `T` in `@promptctl/go-template-js` — the engine's
|
|
51
|
+
* `T` lives on the `Engine`/`EngineConfig`, and per-function input/output
|
|
52
|
+
* types are carried as runtime `argTypes` on each `TemplateFunc`. The map
|
|
53
|
+
* therefore *type-checks* against any `EngineConfig<T>.funcs`, but the
|
|
54
|
+
* functions returned here are only *runtime-compatible* with
|
|
55
|
+
* `Engine<RichText>`: each style function returns a `RichText` and
|
|
56
|
+
* requires its lifted child to be a `RichText` (enforced by an
|
|
57
|
+
* `instanceof` check that throws on misuse). Consumers merging this map
|
|
58
|
+
* into a wider engine must keep `T = RichText`; merging into an engine
|
|
59
|
+
* whose `T` is something else will compile but fail at evaluation time.
|
|
60
|
+
*/
|
|
61
|
+
export declare function richTextFuncs(drawnAt?: () => DrawnAt): FuncMap;
|
|
62
|
+
/**
|
|
63
|
+
* Construct an `Engine<RichText>` with the rich-js style-function set
|
|
64
|
+
* registered. Consumers that already manage their own engine should call
|
|
65
|
+
* `richTextFuncs()` and merge the result into their own `createEngine`
|
|
66
|
+
* configuration; consumers that just want rich-js styling can use this
|
|
67
|
+
* factory directly.
|
|
68
|
+
*
|
|
69
|
+
* `fromString` lifts text literals into `RichText`. `toString` flattens a
|
|
70
|
+
* `RichText` to its plain text — the engine's no-silent-flatten guard uses
|
|
71
|
+
* this only for `printf "%s"` / `"%q"` and `print*` slots, where ANSI is
|
|
72
|
+
* not desired anyway.
|
|
73
|
+
*/
|
|
74
|
+
export declare function createRichTextEngine(): Engine<RichText>;
|
|
75
|
+
export interface RenderTemplateOptions extends Partial<RenderOptions> {
|
|
76
|
+
/**
|
|
77
|
+
* Defaults to 400 — large enough that downstream `splitLines` /
|
|
78
|
+
* `adjustLineLength` clipping decides actual width, matching the typical
|
|
79
|
+
* "render wide, fit on output" pipeline. The error line is fitted to it too,
|
|
80
|
+
* so only a caller that passes the width it draws at sees a cut error end in
|
|
81
|
+
* `…` rather than be cropped by whatever draws it.
|
|
82
|
+
*/
|
|
83
|
+
maxWidth?: number;
|
|
84
|
+
/** The error line's style, a `Style.parse` spec (default `"red dim"`). */
|
|
85
|
+
errorStyle?: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Compile a template source against `engine` and render the result to a
|
|
89
|
+
* flat `Segment[]`. The 90%-case convenience over chaining `engine.compile`,
|
|
90
|
+
* `RichText.fromFragments`, and `.render` by hand:
|
|
91
|
+
*
|
|
92
|
+
* - Runs `engine.compile(source)(scope)` to get the engine's `RichText[]`.
|
|
93
|
+
* - Flattens that fragment list into a single styled `RichText` via
|
|
94
|
+
* `RichText.fromFragments` so every fragment's wrapping style survives.
|
|
95
|
+
* - Renders to a `Segment[]` with the given render options — `maxWidth`,
|
|
96
|
+
* `theme`, `onStyleError` and the rest — as a terminal unless they say not.
|
|
97
|
+
* - On a parse/evaluate failure, emits a single dim styled
|
|
98
|
+
* `[error: <message>]` segment, one line fitted to `maxWidth`, the caller
|
|
99
|
+
* can drop into their layout. No bespoke fallback wiring required at every
|
|
100
|
+
* call site.
|
|
101
|
+
*
|
|
102
|
+
* Only compile, evaluate and flatten are inside the `try`: the error line reports a
|
|
103
|
+
* template that failed, nothing else. Whatever the render throws — a style
|
|
104
|
+
* error an `onStyleError` handler rethrew, or a fault in the render itself —
|
|
105
|
+
* leaves this function rather than being folded into an `[error: …]` line.
|
|
106
|
+
*
|
|
107
|
+
* [LAW:single-enforcer] One place owns "render a template to segments,
|
|
108
|
+
* degrade gracefully when the template fails" — every consumer that wants this exact
|
|
109
|
+
* shape reads from here rather than re-implementing the same try/catch +
|
|
110
|
+
* error-formatting glue.
|
|
111
|
+
*
|
|
112
|
+
* For the 10% — custom error UX, intermediate access to the `RichText`,
|
|
113
|
+
* pre-compiled templates re-used many times — call the engine directly
|
|
114
|
+
* and use `RichText.fromFragments` to flatten. This helper is sugar for
|
|
115
|
+
* the live-render case (e.g. a preview pane), not a replacement for the
|
|
116
|
+
* compile-once-evaluate-many pattern.
|
|
117
|
+
|
|
118
|
+
*/
|
|
119
|
+
export declare function renderTemplate(engine: Engine<RichText>, source: string, scope?: unknown, options?: RenderTemplateOptions): Segment[];
|
|
@@ -0,0 +1,162 @@
|
|
|
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[]` with the given render options — `maxWidth`,
|
|
95
|
+
* `theme`, `onStyleError` and the rest — as a terminal unless they say not.
|
|
96
|
+
* - On a parse/evaluate failure, emits a single dim styled
|
|
97
|
+
* `[error: <message>]` segment, one line fitted to `maxWidth`, the caller
|
|
98
|
+
* can drop into their layout. No bespoke fallback wiring required at every
|
|
99
|
+
* call site.
|
|
100
|
+
*
|
|
101
|
+
* Only compile, evaluate and flatten are inside the `try`: the error line reports a
|
|
102
|
+
* template that failed, nothing else. Whatever the render throws — a style
|
|
103
|
+
* error an `onStyleError` handler rethrew, or a fault in the render itself —
|
|
104
|
+
* leaves this function rather than being folded into an `[error: …]` line.
|
|
105
|
+
*
|
|
106
|
+
* [LAW:single-enforcer] One place owns "render a template to segments,
|
|
107
|
+
* degrade gracefully when the template fails" — every consumer that wants this exact
|
|
108
|
+
* shape reads from here rather than re-implementing the same try/catch +
|
|
109
|
+
* error-formatting glue.
|
|
110
|
+
*
|
|
111
|
+
* For the 10% — custom error UX, intermediate access to the `RichText`,
|
|
112
|
+
* pre-compiled templates re-used many times — call the engine directly
|
|
113
|
+
* and use `RichText.fromFragments` to flatten. This helper is sugar for
|
|
114
|
+
* the live-render case (e.g. a preview pane), not a replacement for the
|
|
115
|
+
* compile-once-evaluate-many pattern.
|
|
116
|
+
|
|
117
|
+
*/
|
|
118
|
+
export function renderTemplate(engine, source, scope = {}, options) {
|
|
119
|
+
const { errorStyle, ...renderOptions } = options ?? {};
|
|
120
|
+
const maxWidth = renderOptions.maxWidth ?? 400;
|
|
121
|
+
// Flattening belongs to the template: a scope value the engine passes
|
|
122
|
+
// through unlifted fails here, and that is a template that failed.
|
|
123
|
+
let text;
|
|
124
|
+
try {
|
|
125
|
+
text = RichText.fromFragments(engine.compile(source)(scope));
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
return [new Segment(errorLine(e, maxWidth), safeErrorStyle(errorStyle))];
|
|
129
|
+
}
|
|
130
|
+
return Array.from(text.render({ isTerminal: true, ...renderOptions, maxWidth }));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* A caught error as the one line `renderTemplate` promises. The summary is the
|
|
134
|
+
* error's `message` — `String(e)` on an engine error appends a multi-line code
|
|
135
|
+
* frame — and even a `message` can carry the character it is complaining about
|
|
136
|
+
* (`bad escape sequence \⏎`). Any whitespace that is not a plain space — a line
|
|
137
|
+
* break, or a tab, whose stop depends on the column the line is set at and so
|
|
138
|
+
* cannot be measured here — folds, with the spaces around it, to one space.
|
|
139
|
+
*
|
|
140
|
+
* [LAW:one-source-of-truth] The line fits the same `maxWidth` the success path
|
|
141
|
+
* draws at, not a width of its own, and a cut ends in an ellipsis so it never
|
|
142
|
+
* reads as the whole message.
|
|
143
|
+
*/
|
|
144
|
+
function errorLine(e, maxWidth) {
|
|
145
|
+
const summary = (e instanceof Error ? e.message : String(e)).replace(/\s*[^\S ]\s*/g, " ");
|
|
146
|
+
return new RichText(`[error: ${summary}]`).truncate(maxWidth).plain;
|
|
147
|
+
}
|
|
148
|
+
// [LAW:single-enforcer] The error-path Style must not itself throw, or
|
|
149
|
+
// the whole "degrade gracefully" promise of renderTemplate is broken. A
|
|
150
|
+
// bogus user-supplied `errorStyle` spec falls back to a hard-coded safe
|
|
151
|
+
// Style — never propagates the parse failure to the caller.
|
|
152
|
+
const FALLBACK_ERROR_STYLE = new Style({ color: "red", dim: true });
|
|
153
|
+
function safeErrorStyle(spec) {
|
|
154
|
+
if (spec === undefined)
|
|
155
|
+
return FALLBACK_ERROR_STYLE;
|
|
156
|
+
try {
|
|
157
|
+
return Style.parse(spec);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return FALLBACK_ERROR_STYLE;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
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 its hex string — `#RRGGBB`, or
|
|
71
|
+
* `#00000000` for a theme's "no background", which `bg` paints as no
|
|
72
|
+
* background and the colour functions refuse — and passes
|
|
73
|
+
* an already-literal color through unchanged. That second half is not a
|
|
74
|
+
* convenience — it makes `color` **idempotent**, which is what lets consumers
|
|
75
|
+
* apply it unconditionally to any author-written color string without first
|
|
76
|
+
* asking whether it is a name or already a color. [LAW:dataflow-not-control-flow]
|
|
77
|
+
*
|
|
78
|
+
* An unknown name throws, carrying near-miss suggestions from the live
|
|
79
|
+
* palette. In a template that surfaces as an evaluation error at the exact
|
|
80
|
+
* call site, which is the signal an author (or an agent editing a config) needs
|
|
81
|
+
* to fix it. [LAW:no-silent-failure]
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* const engine = createEngine({
|
|
86
|
+
* fromString: (s) => new RichText(s),
|
|
87
|
+
* toString: (rt) => rt.plain,
|
|
88
|
+
* funcs: {
|
|
89
|
+
* ...richTextFuncs(),
|
|
90
|
+
* ...colorFuncs(),
|
|
91
|
+
* ...paletteFuncs(() => currentTheme.palette),
|
|
92
|
+
* },
|
|
93
|
+
* });
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function paletteFuncs(getPalette: () => Palette): FuncMap;
|
|
@@ -0,0 +1,145 @@
|
|
|
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 { parseEase } from "../core/easing.js";
|
|
67
|
+
import { ColorRamp } from "../themes/ramp.js";
|
|
68
|
+
import { computable } from "./color-funcs.js";
|
|
69
|
+
/**
|
|
70
|
+
* The `(position, color-ref)` pairs a `ramp` call's tail spells, as stops.
|
|
71
|
+
*
|
|
72
|
+
* The engine's `alternating` gate has already typed every even slot as a
|
|
73
|
+
* float and every odd slot as a string; what it cannot see is the *pairing*
|
|
74
|
+
* — a trailing position with no color — nor that the string is a color
|
|
75
|
+
* reference. Both are settled here, once, and `ColorRamp` receives resolved
|
|
76
|
+
* stops it never re-checks. [LAW:parse-dont-validate]
|
|
77
|
+
*
|
|
78
|
+
* Each reference resolves against the palette of *this* evaluation, so a
|
|
79
|
+
* ramp over palette names follows the theme exactly as `color` does.
|
|
80
|
+
*/
|
|
81
|
+
function colorStops(tail, palette) {
|
|
82
|
+
if (tail.length % 2 !== 0) {
|
|
83
|
+
throw new RangeError(`ramp's last stop (position ${String(tail[tail.length - 1])}) has no color — ` +
|
|
84
|
+
`stops are <position> <color> pairs`);
|
|
85
|
+
}
|
|
86
|
+
const stops = [];
|
|
87
|
+
for (let i = 0; i < tail.length; i += 2) {
|
|
88
|
+
stops.push({
|
|
89
|
+
at: tail[i],
|
|
90
|
+
color: computable(resolveColorRef(palette, tail[i + 1]), "ramp", JSON.stringify(tail[i + 1])),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return stops;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Register `color "name-or-hex"` against a live palette.
|
|
97
|
+
*
|
|
98
|
+
* `color` resolves a palette variable name to its hex string — `#RRGGBB`, or
|
|
99
|
+
* `#00000000` for a theme's "no background", which `bg` paints as no
|
|
100
|
+
* background and the colour functions refuse — and passes
|
|
101
|
+
* an already-literal color through unchanged. That second half is not a
|
|
102
|
+
* convenience — it makes `color` **idempotent**, which is what lets consumers
|
|
103
|
+
* apply it unconditionally to any author-written color string without first
|
|
104
|
+
* asking whether it is a name or already a color. [LAW:dataflow-not-control-flow]
|
|
105
|
+
*
|
|
106
|
+
* An unknown name throws, carrying near-miss suggestions from the live
|
|
107
|
+
* palette. In a template that surfaces as an evaluation error at the exact
|
|
108
|
+
* call site, which is the signal an author (or an agent editing a config) needs
|
|
109
|
+
* to fix it. [LAW:no-silent-failure]
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const engine = createEngine({
|
|
114
|
+
* fromString: (s) => new RichText(s),
|
|
115
|
+
* toString: (rt) => rt.plain,
|
|
116
|
+
* funcs: {
|
|
117
|
+
* ...richTextFuncs(),
|
|
118
|
+
* ...colorFuncs(),
|
|
119
|
+
* ...paletteFuncs(() => currentTheme.palette),
|
|
120
|
+
* },
|
|
121
|
+
* });
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export function paletteFuncs(getPalette) {
|
|
125
|
+
const colorFunc = {
|
|
126
|
+
fn: ((ref) => resolveColorRef(getPalette(), ref).hex),
|
|
127
|
+
argTypes: ["string"],
|
|
128
|
+
arity: { kind: "exact" },
|
|
129
|
+
returnType: "string",
|
|
130
|
+
};
|
|
131
|
+
// `ramp <value> <ease> <position> <color> …` — the argument list is one
|
|
132
|
+
// float/string cycle end to end (value, ease, then each stop's position
|
|
133
|
+
// and color), so the engine's `alternating` gate types every slot; the
|
|
134
|
+
// pairing and the references are parsed in `colorStops`. Its minimum is the
|
|
135
|
+
// value, the ease, and one stop, so the gate refuses a stopless call.
|
|
136
|
+
// [LAW:types-are-the-program]
|
|
137
|
+
const rampFunc = {
|
|
138
|
+
fn: ((value, ease, ...tail) => new ColorRamp(parseEase(ease), colorStops(tail, getPalette())).at(value)
|
|
139
|
+
.hex),
|
|
140
|
+
argTypes: ["float", "string"],
|
|
141
|
+
arity: { kind: "alternating", minimum: 4 },
|
|
142
|
+
returnType: "string",
|
|
143
|
+
};
|
|
144
|
+
return { color: colorFunc, ramp: rampFunc };
|
|
145
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
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;
|