@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.
Files changed (206) hide show
  1. package/README.md +13 -26
  2. package/package.json +7 -3
  3. package/dist/core/box.d.ts +0 -144
  4. package/dist/core/box.js +0 -391
  5. package/dist/core/cells.d.ts +0 -148
  6. package/dist/core/cells.js +0 -266
  7. package/dist/core/color.d.ts +0 -250
  8. package/dist/core/color.js +0 -1029
  9. package/dist/core/console.d.ts +0 -156
  10. package/dist/core/console.js +0 -472
  11. package/dist/core/emoji.d.ts +0 -24
  12. package/dist/core/emoji.js +0 -391
  13. package/dist/core/export-html.d.ts +0 -24
  14. package/dist/core/export-html.js +0 -106
  15. package/dist/core/export-lines.d.ts +0 -121
  16. package/dist/core/export-lines.js +0 -141
  17. package/dist/core/highlighter.d.ts +0 -33
  18. package/dist/core/highlighter.js +0 -124
  19. package/dist/core/json.d.ts +0 -27
  20. package/dist/core/json.js +0 -53
  21. package/dist/core/markup.d.ts +0 -97
  22. package/dist/core/markup.js +0 -619
  23. package/dist/core/measure.d.ts +0 -27
  24. package/dist/core/measure.js +0 -61
  25. package/dist/core/oklch.d.ts +0 -161
  26. package/dist/core/oklch.js +0 -312
  27. package/dist/core/osc8.d.ts +0 -68
  28. package/dist/core/osc8.js +0 -90
  29. package/dist/core/pretty.d.ts +0 -141
  30. package/dist/core/pretty.js +0 -472
  31. package/dist/core/protocol.d.ts +0 -137
  32. package/dist/core/protocol.js +0 -101
  33. package/dist/core/render.d.ts +0 -84
  34. package/dist/core/render.js +0 -145
  35. package/dist/core/segment.d.ts +0 -142
  36. package/dist/core/segment.js +0 -433
  37. package/dist/core/spinnerData.d.ts +0 -10
  38. package/dist/core/spinnerData.js +0 -115
  39. package/dist/core/strip.d.ts +0 -145
  40. package/dist/core/strip.js +0 -308
  41. package/dist/core/style.d.ts +0 -144
  42. package/dist/core/style.js +0 -723
  43. package/dist/core/subscription.d.ts +0 -12
  44. package/dist/core/subscription.js +0 -12
  45. package/dist/core/text.d.ts +0 -255
  46. package/dist/core/text.js +0 -990
  47. package/dist/core/wrap.d.ts +0 -41
  48. package/dist/core/wrap.js +0 -127
  49. package/dist/host/host-stream.d.ts +0 -30
  50. package/dist/host/host-stream.js +0 -35
  51. package/dist/host/index.d.ts +0 -3
  52. package/dist/host/index.js +0 -2
  53. package/dist/host/terminal-host.d.ts +0 -143
  54. package/dist/host/terminal-host.js +0 -132
  55. package/dist/index.d.ts +0 -87
  56. package/dist/index.js +0 -104
  57. package/dist/node/prompt.d.ts +0 -21
  58. package/dist/node/prompt.js +0 -30
  59. package/dist/node/save.d.ts +0 -17
  60. package/dist/node/save.js +0 -21
  61. package/dist/node/terminal-host.d.ts +0 -84
  62. package/dist/node/terminal-host.js +0 -160
  63. package/dist/node/traceback.d.ts +0 -27
  64. package/dist/node/traceback.js +0 -112
  65. package/dist/renderables/align.d.ts +0 -16
  66. package/dist/renderables/align.js +0 -46
  67. package/dist/renderables/columns.d.ts +0 -61
  68. package/dist/renderables/columns.js +0 -168
  69. package/dist/renderables/constrain.d.ts +0 -15
  70. package/dist/renderables/constrain.js +0 -37
  71. package/dist/renderables/flexStrip.d.ts +0 -41
  72. package/dist/renderables/flexStrip.js +0 -200
  73. package/dist/renderables/group.d.ts +0 -11
  74. package/dist/renderables/group.js +0 -15
  75. package/dist/renderables/layout.d.ts +0 -92
  76. package/dist/renderables/layout.js +0 -315
  77. package/dist/renderables/live.d.ts +0 -47
  78. package/dist/renderables/live.js +0 -131
  79. package/dist/renderables/markdown.d.ts +0 -24
  80. package/dist/renderables/markdown.js +0 -182
  81. package/dist/renderables/padding.d.ts +0 -38
  82. package/dist/renderables/padding.js +0 -140
  83. package/dist/renderables/panel.d.ts +0 -116
  84. package/dist/renderables/panel.js +0 -322
  85. package/dist/renderables/progress.d.ts +0 -90
  86. package/dist/renderables/progress.js +0 -241
  87. package/dist/renderables/progressBar.d.ts +0 -31
  88. package/dist/renderables/progressBar.js +0 -52
  89. package/dist/renderables/prompt.d.ts +0 -49
  90. package/dist/renderables/prompt.js +0 -125
  91. package/dist/renderables/rule.d.ts +0 -24
  92. package/dist/renderables/rule.js +0 -90
  93. package/dist/renderables/spinner.d.ts +0 -29
  94. package/dist/renderables/spinner.js +0 -64
  95. package/dist/renderables/status.d.ts +0 -23
  96. package/dist/renderables/status.js +0 -60
  97. package/dist/renderables/syntax.d.ts +0 -35
  98. package/dist/renderables/syntax.js +0 -114
  99. package/dist/renderables/table.d.ts +0 -182
  100. package/dist/renderables/table.js +0 -697
  101. package/dist/renderables/traceback.d.ts +0 -31
  102. package/dist/renderables/traceback.js +0 -109
  103. package/dist/renderables/tree.d.ts +0 -54
  104. package/dist/renderables/tree.js +0 -159
  105. package/dist/template-bindings/color-funcs.d.ts +0 -87
  106. package/dist/template-bindings/color-funcs.js +0 -219
  107. package/dist/template-bindings/helpers.d.ts +0 -24
  108. package/dist/template-bindings/helpers.js +0 -48
  109. package/dist/template-bindings/index.d.ts +0 -107
  110. package/dist/template-bindings/index.js +0 -144
  111. package/dist/template-bindings/palette-funcs.d.ts +0 -94
  112. package/dist/template-bindings/palette-funcs.js +0 -151
  113. package/dist/template-bindings/style-funcs.d.ts +0 -28
  114. package/dist/template-bindings/style-funcs.js +0 -151
  115. package/dist/themes/buildPalette.d.ts +0 -36
  116. package/dist/themes/buildPalette.js +0 -56
  117. package/dist/themes/colorMath.d.ts +0 -82
  118. package/dist/themes/colorMath.js +0 -254
  119. package/dist/themes/colorRef.d.ts +0 -51
  120. package/dist/themes/colorRef.js +0 -96
  121. package/dist/themes/data/atom-one-dark.d.ts +0 -3
  122. package/dist/themes/data/atom-one-dark.js +0 -158
  123. package/dist/themes/data/atom-one-light.d.ts +0 -3
  124. package/dist/themes/data/atom-one-light.js +0 -158
  125. package/dist/themes/data/catppuccin-frappe.d.ts +0 -3
  126. package/dist/themes/data/catppuccin-frappe.js +0 -158
  127. package/dist/themes/data/catppuccin-latte.d.ts +0 -3
  128. package/dist/themes/data/catppuccin-latte.js +0 -158
  129. package/dist/themes/data/catppuccin-macchiato.d.ts +0 -3
  130. package/dist/themes/data/catppuccin-macchiato.js +0 -158
  131. package/dist/themes/data/catppuccin-mocha.d.ts +0 -3
  132. package/dist/themes/data/catppuccin-mocha.js +0 -158
  133. package/dist/themes/data/cyberpunk.d.ts +0 -17
  134. package/dist/themes/data/cyberpunk.js +0 -191
  135. package/dist/themes/data/default.d.ts +0 -3
  136. package/dist/themes/data/default.js +0 -158
  137. package/dist/themes/data/dracula.d.ts +0 -3
  138. package/dist/themes/data/dracula.js +0 -158
  139. package/dist/themes/data/flexoki.d.ts +0 -3
  140. package/dist/themes/data/flexoki.js +0 -158
  141. package/dist/themes/data/gruvbox.d.ts +0 -3
  142. package/dist/themes/data/gruvbox.js +0 -158
  143. package/dist/themes/data/index.d.ts +0 -35
  144. package/dist/themes/data/index.js +0 -64
  145. package/dist/themes/data/monokai.d.ts +0 -3
  146. package/dist/themes/data/monokai.js +0 -158
  147. package/dist/themes/data/nord.d.ts +0 -3
  148. package/dist/themes/data/nord.js +0 -158
  149. package/dist/themes/data/rose-pine-dawn.d.ts +0 -3
  150. package/dist/themes/data/rose-pine-dawn.js +0 -158
  151. package/dist/themes/data/rose-pine-moon.d.ts +0 -3
  152. package/dist/themes/data/rose-pine-moon.js +0 -158
  153. package/dist/themes/data/rose-pine.d.ts +0 -3
  154. package/dist/themes/data/rose-pine.js +0 -158
  155. package/dist/themes/data/solarized-dark.d.ts +0 -3
  156. package/dist/themes/data/solarized-dark.js +0 -158
  157. package/dist/themes/data/solarized-light.d.ts +0 -3
  158. package/dist/themes/data/solarized-light.js +0 -158
  159. package/dist/themes/data/svg-export.d.ts +0 -3
  160. package/dist/themes/data/svg-export.js +0 -158
  161. package/dist/themes/data/textual-ansi.d.ts +0 -3
  162. package/dist/themes/data/textual-ansi.js +0 -158
  163. package/dist/themes/data/textual-dark.d.ts +0 -3
  164. package/dist/themes/data/textual-dark.js +0 -158
  165. package/dist/themes/data/textual-light.d.ts +0 -3
  166. package/dist/themes/data/textual-light.js +0 -158
  167. package/dist/themes/data/tokyo-night.d.ts +0 -3
  168. package/dist/themes/data/tokyo-night.js +0 -158
  169. package/dist/themes/data/types.d.ts +0 -15
  170. package/dist/themes/data/types.js +0 -1
  171. package/dist/themes/palette.d.ts +0 -21
  172. package/dist/themes/palette.js +0 -28
  173. package/dist/themes/ramp.d.ts +0 -83
  174. package/dist/themes/ramp.js +0 -122
  175. package/dist/themes/registry.d.ts +0 -43
  176. package/dist/themes/registry.js +0 -82
  177. package/dist/themes/terminalThemes.d.ts +0 -54
  178. package/dist/themes/terminalThemes.js +0 -68
  179. package/dist/themes/transpose.d.ts +0 -87
  180. package/dist/themes/transpose.js +0 -138
  181. package/dist/widgets/button.d.ts +0 -49
  182. package/dist/widgets/button.js +0 -206
  183. package/dist/widgets/checkbox.d.ts +0 -41
  184. package/dist/widgets/checkbox.js +0 -155
  185. package/dist/widgets/dropdown.d.ts +0 -67
  186. package/dist/widgets/dropdown.js +0 -453
  187. package/dist/widgets/event-router.d.ts +0 -78
  188. package/dist/widgets/event-router.js +0 -622
  189. package/dist/widgets/focus-manager.d.ts +0 -26
  190. package/dist/widgets/focus-manager.js +0 -193
  191. package/dist/widgets/index.d.ts +0 -22
  192. package/dist/widgets/index.js +0 -15
  193. package/dist/widgets/screen.d.ts +0 -98
  194. package/dist/widgets/screen.js +0 -530
  195. package/dist/widgets/slider.d.ts +0 -57
  196. package/dist/widgets/slider.js +0 -270
  197. package/dist/widgets/static-item.d.ts +0 -40
  198. package/dist/widgets/static-item.js +0 -60
  199. package/dist/widgets/text-input.d.ts +0 -274
  200. package/dist/widgets/text-input.js +0 -1162
  201. package/dist/widgets/toggle.d.ts +0 -44
  202. package/dist/widgets/toggle.js +0 -179
  203. package/dist/widgets/types.d.ts +0 -108
  204. package/dist/widgets/types.js +0 -31
  205. package/dist/widgets/widget-base.d.ts +0 -42
  206. package/dist/widgets/widget-base.js +0 -173
@@ -1,391 +0,0 @@
1
- /**
2
- * Emoji shortcode support — dictionary, replacement, and renderable.
3
- */
4
- import { Segment } from "./segment.js";
5
- // [LAW:one-source-of-truth] Single emoji dictionary for all shortcode lookups
6
- export const EMOJI = {
7
- // Faces
8
- smile: "😄",
9
- laugh: "😂",
10
- grinning: "😀",
11
- wink: "😉",
12
- blush: "😊",
13
- innocent: "😇",
14
- heart_eyes: "😍",
15
- kissing: "😘",
16
- thinking: "🤔",
17
- shushing: "🤫",
18
- zipper_mouth: "🤐",
19
- raised_eyebrow: "🤨",
20
- neutral: "😐",
21
- expressionless: "😑",
22
- unamused: "😒",
23
- rolling_eyes: "🙄",
24
- grimacing: "😬",
25
- lying: "🤥",
26
- relieved: "😌",
27
- pensive: "😔",
28
- sleepy: "😪",
29
- sleeping: "😴",
30
- mask: "😷",
31
- thermometer_face: "🤒",
32
- bandage_face: "🤕",
33
- nauseated: "🤢",
34
- sneezing: "🤧",
35
- cold_face: "🥶",
36
- hot_face: "🥵",
37
- dizzy_face: "😵",
38
- exploding_head: "🤯",
39
- cowboy: "🤠",
40
- party_face: "🥳",
41
- sunglasses: "😎",
42
- nerd: "🤓",
43
- monocle: "🧐",
44
- confused: "😕",
45
- worried: "😟",
46
- frowning: "☹",
47
- open_mouth: "😮",
48
- hushed: "😯",
49
- astonished: "😲",
50
- flushed: "😳",
51
- pleading: "🥺",
52
- cry: "😢",
53
- sob: "😭",
54
- scream: "😱",
55
- sweat: "😰",
56
- angry: "😡",
57
- rage: "🤬",
58
- devil: "😈",
59
- skull: "💀",
60
- poop: "💩",
61
- clown: "🤡",
62
- ghost: "👻",
63
- alien: "👽",
64
- robot: "🤖",
65
- // Hands
66
- wave: "👋",
67
- raised_hand: "✋",
68
- ok_hand: "👌",
69
- pinching: "🤏",
70
- victory: "✌",
71
- crossed_fingers: "🤞",
72
- love_you: "🤟",
73
- rock_on: "🤘",
74
- thumbs_up: "👍",
75
- thumbs_down: "👎",
76
- fist: "✊",
77
- punch: "👊",
78
- left_fist: "🤛",
79
- right_fist: "🤜",
80
- clap: "👏",
81
- raised_hands: "🙌",
82
- open_hands: "👐",
83
- palms_up: "🤲",
84
- handshake: "🤝",
85
- pray: "🙏",
86
- writing_hand: "✍",
87
- nail_polish: "💅",
88
- muscle: "💪",
89
- point_up: "☝",
90
- point_up_2: "👆",
91
- point_down: "👇",
92
- point_left: "👈",
93
- point_right: "👉",
94
- middle_finger: "🖕",
95
- // Hearts
96
- heart: "❤",
97
- orange_heart: "🧡",
98
- yellow_heart: "💛",
99
- green_heart: "💚",
100
- blue_heart: "💙",
101
- purple_heart: "💜",
102
- black_heart: "🖤",
103
- white_heart: "🤍",
104
- brown_heart: "🤎",
105
- broken_heart: "💔",
106
- heart_exclamation: "❣",
107
- two_hearts: "💕",
108
- revolving_hearts: "💞",
109
- heartbeat: "💓",
110
- heartpulse: "💗",
111
- sparkling_heart: "💖",
112
- growing_heart: "💗",
113
- cupid: "💘",
114
- gift_heart: "💝",
115
- // Objects & Symbols
116
- fire: "🔥",
117
- star: "⭐",
118
- star2: "🌟",
119
- sparkles: "✨",
120
- zap: "⚡",
121
- boom: "💥",
122
- droplet: "💧",
123
- rainbow: "🌈",
124
- sun: "☀",
125
- moon: "🌙",
126
- cloud: "☁",
127
- snowflake: "❄",
128
- umbrella: "☂",
129
- // Status
130
- check: "✅",
131
- check_mark: "✔",
132
- cross_mark: "❌",
133
- warning: "⚠",
134
- info: "ℹ",
135
- question: "❓",
136
- exclamation: "❗",
137
- no_entry: "⛔",
138
- prohibited: "🚫",
139
- stop_sign: "🛑",
140
- // Arrows
141
- arrow_up: "⬆",
142
- arrow_down: "⬇",
143
- arrow_left: "⬅",
144
- arrow_right: "➡",
145
- arrow_upper_left: "↖",
146
- arrow_upper_right: "↗",
147
- arrow_lower_left: "↙",
148
- arrow_lower_right: "↘",
149
- left_right_arrow: "↔",
150
- up_down_arrow: "↕",
151
- arrows_clockwise: "🔃",
152
- arrows_counterclockwise: "🔄",
153
- // Tech
154
- computer: "💻",
155
- keyboard: "⌨",
156
- desktop: "🖥",
157
- printer: "🖨",
158
- mouse: "🖱",
159
- cd: "💿",
160
- dvd: "📀",
161
- floppy: "💾",
162
- battery: "🔋",
163
- plug: "🔌",
164
- bulb: "💡",
165
- flashlight: "🔦",
166
- gear: "⚙",
167
- wrench: "🔧",
168
- hammer: "🔨",
169
- nut_and_bolt: "🔩",
170
- link: "🔗",
171
- chains: "⛓",
172
- lock: "🔒",
173
- unlock: "🔓",
174
- key: "🔑",
175
- shield: "🛡",
176
- bug: "🐛",
177
- magnifying_glass: "🔍",
178
- // Communication
179
- speech_balloon: "💬",
180
- thought_balloon: "💭",
181
- megaphone: "📣",
182
- loudspeaker: "📢",
183
- bell: "🔔",
184
- no_bell: "🔕",
185
- envelope: "✉",
186
- email: "📧",
187
- inbox: "📥",
188
- outbox: "📤",
189
- package: "📦",
190
- clipboard: "📋",
191
- memo: "📝",
192
- page: "📄",
193
- bookmark: "🔖",
194
- label: "🏷",
195
- // Time
196
- hourglass: "⌛",
197
- hourglass_flowing: "⏳",
198
- watch: "⌚",
199
- alarm_clock: "⏰",
200
- stopwatch: "⏱",
201
- timer: "⏲",
202
- clock: "🕐",
203
- // Numbers
204
- zero: "0️⃣",
205
- one: "1️⃣",
206
- two: "2️⃣",
207
- three: "3️⃣",
208
- four: "4️⃣",
209
- five: "5️⃣",
210
- six: "6️⃣",
211
- seven: "7️⃣",
212
- eight: "8️⃣",
213
- nine: "9️⃣",
214
- ten: "🔟",
215
- hash: "#️⃣",
216
- // Food & Drink
217
- coffee: "☕",
218
- tea: "🍵",
219
- beer: "🍺",
220
- wine: "🍷",
221
- cocktail: "🍸",
222
- pizza: "🍕",
223
- hamburger: "🍔",
224
- fries: "🍟",
225
- hotdog: "🌭",
226
- taco: "🌮",
227
- cake: "🎂",
228
- cookie: "🍪",
229
- chocolate: "🍫",
230
- candy: "🍬",
231
- apple: "🍎",
232
- banana: "🍌",
233
- // Nature & Animals
234
- dog: "🐕",
235
- cat: "🐈",
236
- snake: "🐍",
237
- turtle: "🐢",
238
- whale: "🐳",
239
- dolphin: "🐬",
240
- fish: "🐟",
241
- butterfly: "🦋",
242
- bee: "🐝",
243
- ladybug: "🐞",
244
- spider: "🕷",
245
- tree: "🌲",
246
- flower: "🌸",
247
- rose: "🌹",
248
- sunflower: "🌻",
249
- cactus: "🌵",
250
- // Activities
251
- trophy: "🏆",
252
- medal: "🏅",
253
- crown: "👑",
254
- gem: "💎",
255
- money_bag: "💰",
256
- dollar: "💵",
257
- rocket: "🚀",
258
- airplane: "✈",
259
- car: "🚗",
260
- bicycle: "🚲",
261
- house: "🏠",
262
- building: "🏢",
263
- globe: "🌍",
264
- world_map: "🗺",
265
- flag: "🏁",
266
- party: "🎉",
267
- confetti: "🎊",
268
- balloon: "🎈",
269
- gift: "🎁",
270
- art: "🎨",
271
- music: "🎵",
272
- notes: "🎶",
273
- microphone: "🎤",
274
- headphones: "🎧",
275
- movie: "🎬",
276
- camera: "📷",
277
- book: "📖",
278
- books: "📚",
279
- scroll: "📜",
280
- newspaper: "📰",
281
- // People
282
- person: "🧑",
283
- man: "👨",
284
- woman: "👩",
285
- child: "🧒",
286
- baby: "👶",
287
- eyes: "👀",
288
- eye: "👁",
289
- brain: "🧠",
290
- tongue: "👅",
291
- ear: "👂",
292
- nose: "👃",
293
- foot: "🦶",
294
- hand: "🤚",
295
- // Misc
296
- red_circle: "🔴",
297
- orange_circle: "🟠",
298
- yellow_circle: "🟡",
299
- green_circle: "🟢",
300
- blue_circle: "🔵",
301
- purple_circle: "🟣",
302
- black_circle: "⚫",
303
- white_circle: "⚪",
304
- red_square: "🟥",
305
- orange_square: "🟧",
306
- yellow_square: "🟨",
307
- green_square: "🟩",
308
- blue_square: "🟦",
309
- purple_square: "🟪",
310
- black_square: "⬛",
311
- white_square: "⬜",
312
- checkered_flag: "🏁",
313
- triangular_flag: "🚩",
314
- crossed_flags: "🎌",
315
- pirate_flag: "🏴‍☠️",
316
- white_flag: "🏳",
317
- 100: "💯",
318
- infinity: "♾",
319
- recycle: "♻",
320
- peace: "☮",
321
- yin_yang: "☯",
322
- cross: "✝",
323
- atom: "⚛",
324
- radioactive: "☢",
325
- biohazard: "☣",
326
- };
327
- const EMOJI_PATTERN = /:([a-z0-9_]+(?:-(?:emoji|text))?):/g;
328
- /**
329
- * Replaces :shortcode: patterns in text with emoji characters.
330
- */
331
- export function emojiReplace(text, defaultVariant) {
332
- return text.replace(EMOJI_PATTERN, (_match, code) => {
333
- let variant = defaultVariant;
334
- let name = code;
335
- // Check for inline variant suffix
336
- if (name.endsWith("-emoji")) {
337
- variant = "emoji";
338
- name = name.slice(0, -6);
339
- }
340
- else if (name.endsWith("-text")) {
341
- variant = "text";
342
- name = name.slice(0, -5);
343
- }
344
- const emoji = EMOJI[name];
345
- if (emoji === undefined)
346
- return _match; // Not found, leave unchanged
347
- // Apply variant selector
348
- // [LAW:dataflow-not-control-flow] Always compute suffix, let the value decide
349
- const suffix = variant === "emoji"
350
- ? "\uFE0F"
351
- : variant === "text"
352
- ? "\uFE0E"
353
- : "";
354
- return emoji + suffix;
355
- });
356
- }
357
- export class NoEmoji extends Error {
358
- constructor(name) {
359
- super(`No emoji with name: "${name}"`);
360
- this.name = "NoEmoji";
361
- }
362
- }
363
- export class Emoji {
364
- name;
365
- _char;
366
- _style;
367
- _variant;
368
- constructor(name, style, variant) {
369
- const emoji = EMOJI[name];
370
- if (emoji === undefined)
371
- throw new NoEmoji(name);
372
- this.name = name;
373
- this._char = emoji;
374
- this._style = style;
375
- this._variant = variant;
376
- }
377
- toString() {
378
- const suffix = this._variant === "emoji"
379
- ? "\uFE0F"
380
- : this._variant === "text"
381
- ? "\uFE0E"
382
- : "";
383
- return this._char + suffix;
384
- }
385
- *render(_options) {
386
- yield new Segment(this.toString(), this._style);
387
- }
388
- static replace(text) {
389
- return emojiReplace(text);
390
- }
391
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * export-html — recorded segments drawn as a standalone HTML document.
3
- *
4
- * An encoding of `export-lines` and nothing more. What a run looks like under
5
- * a theme is decided there; this module decides only how CSS says it. It never
6
- * sees a `Style`, so it cannot disagree with the SVG exporter about what
7
- * `reverse` or `dim` means — the two old converters that did disagree were
8
- * deleted when this replaced them.
9
- *
10
- * The rows are already laid out at console width, so `pre` never re-wraps
11
- * them: `white-space: pre`, and a scrollbar rather than a reflow when the page
12
- * is narrower than the terminal was.
13
- */
14
- import type { TerminalTheme } from "./color.js";
15
- import type { Segment } from "./segment.js";
16
- /**
17
- * `segments` under `theme` as a complete HTML document.
18
- *
19
- * A browser draws no line for a newline at either edge of a `pre`: the parser
20
- * drops the one straight after `<pre>`, and the one before `</pre>` ends a
21
- * line without starting another. So the page opens with a newline of its own
22
- * and every row ends with one, and a blank first or last row is still drawn.
23
- */
24
- export declare function encodeHtml(segments: Iterable<Segment>, theme?: TerminalTheme): string;
@@ -1,106 +0,0 @@
1
- /**
2
- * export-html — recorded segments drawn as a standalone HTML document.
3
- *
4
- * An encoding of `export-lines` and nothing more. What a run looks like under
5
- * a theme is decided there; this module decides only how CSS says it. It never
6
- * sees a `Style`, so it cannot disagree with the SVG exporter about what
7
- * `reverse` or `dim` means — the two old converters that did disagree were
8
- * deleted when this replaced them.
9
- *
10
- * The rows are already laid out at console width, so `pre` never re-wraps
11
- * them: `white-space: pre`, and a scrollbar rather than a reflow when the page
12
- * is narrower than the terminal was.
13
- */
14
- import { exportCanvas, exportLines } from "./export-lines.js";
15
- const ENTITIES = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" };
16
- const escapeText = (text) => text.replace(/[&<>]/g, (c) => ENTITIES[c]);
17
- const escapeAttribute = (value) => value.replace(/[&"<>]/g, (c) => ENTITIES[c]);
18
- const BLINK_KEYFRAMES = "rich-blink";
19
- // [LAW:dataflow-not-control-flow] Each enum-valued field of a look is a table
20
- // from its values to the declarations it adds, so every value is spelled once
21
- // and `Record` makes a new value a compile error until it has a row.
22
- // A double underline adds no line to the glyph's own span; `runHtml` draws it.
23
- const UNDERLINE_LINE = {
24
- none: [],
25
- single: ["underline"],
26
- double: [],
27
- };
28
- const BLINK = {
29
- none: [],
30
- slow: [`animation:${BLINK_KEYFRAMES} 1s step-end infinite`],
31
- fast: [`animation:${BLINK_KEYFRAMES} 0.5s step-end infinite`],
32
- };
33
- const FRAME = "box-shadow:inset 0 0 0 1px currentColor";
34
- const OUTLINE = {
35
- none: [],
36
- frame: [FRAME],
37
- encircle: [FRAME, "border-radius:0.5em"],
38
- };
39
- /**
40
- * The glyph colour, and the background when one is painted.
41
- *
42
- * Dim arrives already blended into `foreground`. `opacity` is never written:
43
- * it fades a painted background along with the glyph, which is the bug the
44
- * blend exists to avoid.
45
- */
46
- function paintCss(look) {
47
- return [
48
- `color:${look.foreground.hex}`,
49
- ...(look.background === "canvas" ? [] : [`background-color:${look.background.hex}`]),
50
- ];
51
- }
52
- /** What is drawn on the glyph: weight, slant, single-style lines, blink, outline. */
53
- function glyphCss(look) {
54
- const lines = [
55
- ...UNDERLINE_LINE[look.underline],
56
- ...(look.strike ? ["line-through"] : []),
57
- ...(look.overline ? ["overline"] : []),
58
- ];
59
- return [
60
- ...(look.bold ? ["font-weight:bold"] : []),
61
- ...(look.italic ? ["font-style:italic"] : []),
62
- ...(lines.length === 0 ? [] : [`text-decoration-line:${lines.join(" ")}`]),
63
- ...BLINK[look.blink],
64
- ...OUTLINE[look.outline],
65
- ];
66
- }
67
- const span = (css, content) => `<span style="${escapeAttribute(css.join(";"))}">${content}</span>`;
68
- /**
69
- * One run as markup.
70
- *
71
- * An element has one `text-decoration-style`, so a double underline sharing a
72
- * span with a strike would double the strike too. It gets an outer span of its
73
- * own instead. That span carries the paint, because a descendant's background
74
- * may be painted over an ancestor's underline, and the blink, so the underline
75
- * blinks with the glyph.
76
- */
77
- function runHtml({ text, look }) {
78
- const glyph = escapeText(text);
79
- const drawn = look.underline === "double"
80
- ? span([...paintCss(look), "text-decoration-line:underline", "text-decoration-style:double", ...BLINK[look.blink]], span([`color:${look.foreground.hex}`, ...glyphCss(look)], glyph))
81
- : span([...paintCss(look), ...glyphCss(look)], glyph);
82
- return look.href === null ? drawn : `<a href="${escapeAttribute(look.href)}">${drawn}</a>`;
83
- }
84
- /**
85
- * `segments` under `theme` as a complete HTML document.
86
- *
87
- * A browser draws no line for a newline at either edge of a `pre`: the parser
88
- * drops the one straight after `<pre>`, and the one before `</pre>` ends a
89
- * line without starting another. So the page opens with a newline of its own
90
- * and every row ends with one, and a blank first or last row is still drawn.
91
- */
92
- export function encodeHtml(segments, theme) {
93
- const canvas = exportCanvas(theme);
94
- const rows = exportLines(segments, theme).map((row) => `${row.map(runHtml).join("")}\n`);
95
- const css = [
96
- `body{background:${canvas.background.hex};color:${canvas.foreground.hex};padding:1em}`,
97
- "pre{margin:0;font-family:monospace;white-space:pre;overflow-x:auto}",
98
- "a{color:inherit;text-decoration:inherit}",
99
- `@keyframes ${BLINK_KEYFRAMES}{50%{color:transparent}}`,
100
- ].join("\n");
101
- return [
102
- "<!DOCTYPE html>",
103
- `<html><head><meta charset="utf-8"><style>\n${css}\n</style></head>`,
104
- `<body><pre>\n${rows.join("")}</pre></body></html>`,
105
- ].join("\n");
106
- }
@@ -1,121 +0,0 @@
1
- /**
2
- * export-lines — recorded segments resolved against a `TerminalTheme` into the
3
- * lines every exporter draws.
4
- *
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 colour its glyph is,
7
- * whether its background is painted, which decorations it carries, where it
8
- * links — is decided here, once, and an exporter decides only how to write
9
- * that down. Before it existed the decision was made twice, by a CSS method
10
- * on `Style` and by a private converter on `Console`, and the two had already
11
- * disagreed: one honoured `underline2`, the other dropped it.
12
- *
13
- * [LAW:types-are-the-program] `ExportLook` has no `reverse`, `dim`, `conceal`
14
- * or default colour, because all four are consumed by `resolveLook` and turned
15
- * into plain RGB. An exporter holding a look cannot forget to swap a reversed
16
- * run or to fade a dim one: there is nothing left in its hands to forget. That
17
- * is the whole reason the representation is resolved rather than a `Style`
18
- * handed through.
19
- *
20
- * Runs rather than a cell grid. A grid gives a wide character a phantom
21
- * continuation cell every consumer must know to skip, and gives an HTML
22
- * exporter — which lays text out by flowing it — nothing it needs. A run's
23
- * column and cell width are `cellLen` of the text before it and of its own
24
- * text; they are not stored, so they cannot disagree with the text
25
- * [LAW:one-source-of-truth]. The SVG exporter, the one consumer that positions
26
- * anything, derives them.
27
- *
28
- * Browser-safe by construction: this imports `color`, `style`, `segment` and
29
- * nothing that touches the host, so `Console` can reach it from the main
30
- * barrel and the fs half of exporting stays in `src/node/save.ts`.
31
- */
32
- import { type ColorRgba, type TerminalTheme } from "./color.js";
33
- import { type Style } from "./style.js";
34
- import type { Segment } from "./segment.js";
35
- declare const _href: unique symbol;
36
- /**
37
- * A link target that is safe to write into a published document.
38
- *
39
- * [LAW:parse-dont-validate] Only `parseHref` produces one, so an exporter that
40
- * writes an `href` attribute from an `Href` cannot have skipped the check.
41
- */
42
- export type Href = string & {
43
- readonly [_href]: true;
44
- };
45
- /**
46
- * Where a run's background comes from. `"canvas"` is the theme background
47
- * showing through — nothing painted — and is distinct from a painted colour
48
- * that happens to equal it, because `on default` and `on #000000` are
49
- * different requests even over a black theme.
50
- */
51
- export type Background = ColorRgba | "canvas";
52
- /** Everything an exporter needs to draw one run, and nothing left to resolve. */
53
- export interface ExportLook {
54
- readonly foreground: ColorRgba;
55
- readonly background: Background;
56
- readonly bold: boolean;
57
- readonly italic: boolean;
58
- readonly underline: "none" | "single" | "double";
59
- readonly strike: boolean;
60
- readonly overline: boolean;
61
- readonly blink: "none" | "slow" | "fast";
62
- readonly outline: "none" | "frame" | "encircle";
63
- readonly href: Href | null;
64
- }
65
- export interface ExportRun {
66
- readonly text: string;
67
- readonly look: ExportLook;
68
- }
69
- /** One terminal row, left to right. An empty array is a blank row. */
70
- export type ExportLine = readonly ExportRun[];
71
- /**
72
- * `Style.link` as a link an export may write, or `null` when it may not.
73
- *
74
- * A refused link loses only its target: the run keeps its text and every other
75
- * attribute, so nothing the terminal showed disappears from the export. The
76
- * canonical `URL.href` is what comes back, since the parse is what vouches for
77
- * it.
78
- */
79
- export declare function parseHref(link: string): Href | null;
80
- /** What an unstyled cell shows under a theme: the canvas, and ink on it. */
81
- export interface ExportCanvas {
82
- readonly background: ColorRgba;
83
- readonly foreground: ColorRgba;
84
- }
85
- /**
86
- * The ground every export is drawn on under `theme`.
87
- *
88
- * An exporter paints its page or window with this; `resolveLook` flattens
89
- * every run over the same `background`, so a run showing the canvas and the
90
- * page around it cannot come out different colours.
91
- */
92
- export declare function exportCanvas(theme?: TerminalTheme): ExportCanvas;
93
- /**
94
- * A `Style` as it appears on screen under `theme`.
95
- *
96
- * The order is the terminal's: colours resolve through the theme and lose
97
- * their alpha — paper over the canvas, ink over the paper, as `toSgrCodes`
98
- * flattens them — `reverse` swaps them, `dim` fades the glyph toward whatever
99
- * background it ended up on, and `conceal` finally paints the glyph in that
100
- * background. Every step after flattening works on opaque colour, so no
101
- * exporter ever draws a translucent one. Text under `conceal` is still
102
- * present, and still selectable, in both formats.
103
- *
104
- * The one difference from `toSgrCodes` is the substrate: a terminal cannot
105
- * know what lies under its cells and assumes black, while an export draws its
106
- * own canvas and flattens over that.
107
- *
108
- * `theme` omitted is `ColorSpec.getTruecolor`'s own fallback — black canvas,
109
- * white ink, the standard ANSI table. Choosing it there rather than naming a
110
- * preset here is what keeps `core/` from a third upward edge into `themes/`.
111
- */
112
- export declare function resolveLook(style: Style, theme?: TerminalTheme): ExportLook;
113
- /**
114
- * Recorded segments as terminal rows under `theme`.
115
- *
116
- * `"\n"` ends a row, so output that ends with a newline — every `print` does —
117
- * has no empty row after it, and `"a\n\nb"` keeps its blank row. Callers pass
118
- * the recording buffer, which already holds no control segments.
119
- */
120
- export declare function exportLines(segments: Iterable<Segment>, theme?: TerminalTheme): ExportLine[];
121
- export {};