@markii/ansi 0.16.0 → 0.17.0-next.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 (41) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/callout.d.ts +15 -1
  3. package/dist/components/callout.js +32 -19
  4. package/dist/components/card.d.ts +10 -0
  5. package/dist/components/card.js +21 -13
  6. package/dist/components/chart.d.ts +1 -1
  7. package/dist/components/chart.js +8 -9
  8. package/dist/components/details-string.js +1 -1
  9. package/dist/components/details.d.ts +3 -1
  10. package/dist/components/details.js +7 -6
  11. package/dist/components/divider.js +3 -5
  12. package/dist/components/progress.js +2 -3
  13. package/dist/components/rating.js +2 -2
  14. package/dist/components/row.d.ts +2 -0
  15. package/dist/components/row.js +3 -1
  16. package/dist/components/stat.js +1 -2
  17. package/dist/components/table-grid.d.ts +2 -1
  18. package/dist/components/table-grid.js +13 -10
  19. package/dist/components/table.js +1 -1
  20. package/dist/components/tabs.d.ts +3 -1
  21. package/dist/components/tabs.js +25 -7
  22. package/dist/failure-presentation.d.ts +15 -0
  23. package/dist/failure-presentation.js +22 -0
  24. package/dist/glyphs.d.ts +73 -0
  25. package/dist/glyphs.js +88 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.js +4 -0
  28. package/dist/ink-string.d.ts +11 -0
  29. package/dist/ink-string.js +24 -0
  30. package/dist/interactive.d.ts +31 -6
  31. package/dist/interactive.js +155 -12
  32. package/dist/pack-loader.d.ts +64 -0
  33. package/dist/pack-loader.js +172 -0
  34. package/dist/pack-script.d.ts +44 -0
  35. package/dist/pack-script.js +135 -0
  36. package/dist/registry.d.ts +15 -0
  37. package/dist/render.d.ts +24 -1
  38. package/dist/render.js +401 -83
  39. package/dist/text-grid.d.ts +43 -7
  40. package/dist/text-grid.js +69 -18
  41. package/package.json +6 -5
@@ -19,6 +19,7 @@
19
19
  * Unicode grapheme-segmentation table (see the doc comment below for the one
20
20
  * documented limitation).
21
21
  */
22
+ import type { FrameEdges, GlyphSet } from './glyphs.js';
22
23
  /** Removes every SGR and OSC 8 escape sequence this engine can itself produce, so `measureWidth` counts only what a terminal actually draws. */
23
24
  export declare function stripEscapes(text: string): string;
24
25
  /**
@@ -37,18 +38,53 @@ export interface FrameOptions {
37
38
  style: 'solid' | 'dashed';
38
39
  title?: string;
39
40
  width: number;
41
+ /** The render's glyph set (`./glyphs.ts`), so a frame follows the box style. */
42
+ glyphs: GlyphSet;
40
43
  }
44
+ /**
45
+ * The edge glyphs for a frame of `style`. Exposed so a caller that draws
46
+ * its OWN edges (`render.tsx`'s Ink-`Box`-bordered `card`) can match
47
+ * `frameBlock`'s glyphs exactly without duplicating them.
48
+ */
49
+ export declare function frameGlyphs(style: 'solid' | 'dashed', glyphs: GlyphSet): FrameEdges;
50
+ /**
51
+ * Just the top edge of a self-drawing frame, with an optional title woven
52
+ * in. Factored out of `frameBlock` for `render.tsx`'s `card`: an Ink `Box`
53
+ * border draws a plain edge perfectly well on its own (left, right, and an
54
+ * untitled top/bottom), but has no primitive for weaving text into a
55
+ * border line, so a titled card still builds this one line by hand and
56
+ * disables Ink's own top border for it.
57
+ */
58
+ export declare function frameTopLine(options: FrameOptions): string;
41
59
  /** Draws a box around `block`, one glyph set for `'solid'`, another for `'dashed'`, with an optional title woven into the top edge. */
42
60
  export declare function frameBlock(block: string, options: FrameOptions): string;
43
- /** A full-width horizontal rule, `char` (default `─`) repeated to `width` columns. */
44
- export declare function ruleLine(width: number, char?: string): string;
45
- /** Prefixes every line of `block` (split on `\n`) with `prefix`, e.g. a blockquote's `│ `. */
61
+ /** The `left`/`right`/`top`/`bottom`/`topLeft`/`topRight`/`bottomLeft`/`bottomRight` glyph set Ink's `Box` `borderStyle` prop takes, matching `frameBlock`'s own character set exactly for `style`. Corners are always the shared set, exactly like `frameBlock`'s (a dashed frame still has solid corners). */
62
+ export declare function inkBorderStyle(style: 'solid' | 'dashed', glyphs: GlyphSet): {
63
+ topLeft: string;
64
+ top: string;
65
+ topRight: string;
66
+ right: string;
67
+ bottomRight: string;
68
+ bottom: string;
69
+ bottomLeft: string;
70
+ left: string;
71
+ };
72
+ /** The three-value per-line alignment every self-drawing component's `text=` attribute and every generic `align=` layout preset ultimately reduces to — the ONE spelling both `padText` (a pre-built string) and a caller pre-justifying a line before handing it to Ink share. */
73
+ export declare const TEXT_ALIGNS: readonly ["left", "center", "right"];
74
+ export type TextAlign = (typeof TEXT_ALIGNS)[number];
75
+ export declare function isTextAlign(value: string): value is TextAlign;
76
+ /** `text` cut to at most `width` terminal columns, with no ellipsis (so no glyph outside the engine's own table). Plain text only: an escape sequence would be measured and cut like prose. */
77
+ export declare function cutToWidth(text: string, width: number): string;
78
+ /** A full-width horizontal rule, `char` repeated to `width` columns. */
79
+ export declare function ruleLine(width: number, char: string): string;
80
+ /** Prefixes every line of `block` (split on `\n`) with `prefix`, e.g. a blockquote's bar. */
46
81
  export declare function indentBlock(block: string, prefix: string): string;
47
82
  /**
48
83
  * Places `blocks` side by side, each padded (left-aligned) to its entry in
49
- * `widths`, joined by `gutter` spaces, top-aligned. Used only by the plain
50
- * GFM markdown table (`render.tsx`'s `renderGfmTable`) and
51
- * `table-grid.ts`'s own row-drawing; `row`'s OWN columns are placed by a
52
- * real Ink flex `Box` instead (`components/row.tsx`), not by this helper.
84
+ * `widths`, joined by `gutter` spaces, top-aligned. The string emitter of
85
+ * `row` (`render.tsx`'s `renderRowString`, reached when a `row` sits inside
86
+ * a body drawn as a string) places its cells with this. The Ink element
87
+ * emitter (`renderRowElement`) uses a flex `Box` with the same cell widths
88
+ * and gutter, both read from `components/row.ts`'s `resolveRowLayout`.
53
89
  */
54
90
  export declare function columnsBlock(blocks: readonly string[], widths: readonly number[], gutter: number): string;
package/dist/text-grid.js CHANGED
@@ -197,32 +197,82 @@ export function padText(text, width, align) {
197
197
  }
198
198
  return text + ' '.repeat(total);
199
199
  }
200
- /** Draws a box around `block`, one glyph set for `'solid'`, another for `'dashed'`, with an optional title woven into the top edge. */
201
- export function frameBlock(block, options) {
202
- const { style: kind, title, width } = options;
203
- const horizontal = kind === 'dashed' ? '╌' : '─';
204
- const vertical = kind === 'dashed' ? '┆' : '│';
200
+ /**
201
+ * The edge glyphs for a frame of `style`. Exposed so a caller that draws
202
+ * its OWN edges (`render.tsx`'s Ink-`Box`-bordered `card`) can match
203
+ * `frameBlock`'s glyphs exactly without duplicating them.
204
+ */
205
+ export function frameGlyphs(style, glyphs) {
206
+ return style === 'dashed' ? glyphs.dashed : glyphs.solid;
207
+ }
208
+ /**
209
+ * Just the top edge of a self-drawing frame, with an optional title woven
210
+ * in. Factored out of `frameBlock` for `render.tsx`'s `card`: an Ink `Box`
211
+ * border draws a plain edge perfectly well on its own (left, right, and an
212
+ * untitled top/bottom), but has no primitive for weaving text into a
213
+ * border line, so a titled card still builds this one line by hand and
214
+ * disables Ink's own top border for it.
215
+ */
216
+ export function frameTopLine(options) {
217
+ const { style: kind, title, width, glyphs } = options;
218
+ const { horizontal } = frameGlyphs(kind, glyphs);
205
219
  const innerWidth = Math.max(1, width - 2);
206
- let top;
207
220
  if (title) {
208
221
  const label = ` ${title} `;
209
222
  const remaining = Math.max(0, innerWidth - measureWidth(label) - 1);
210
- top = `┌${horizontal}${label}${horizontal.repeat(remaining)}┐`;
211
- }
212
- else {
213
- top = `┌${horizontal.repeat(innerWidth)}┐`;
223
+ return `${glyphs.topLeft}${horizontal}${label}${horizontal.repeat(remaining)}${glyphs.topRight}`;
214
224
  }
215
- const bottom = `└${horizontal.repeat(innerWidth)}┘`;
225
+ return `${glyphs.topLeft}${horizontal.repeat(innerWidth)}${glyphs.topRight}`;
226
+ }
227
+ /** Draws a box around `block`, one glyph set for `'solid'`, another for `'dashed'`, with an optional title woven into the top edge. */
228
+ export function frameBlock(block, options) {
229
+ const { style: kind, width, glyphs } = options;
230
+ const { horizontal, vertical } = frameGlyphs(kind, glyphs);
231
+ const innerWidth = Math.max(1, width - 2);
232
+ const top = frameTopLine(options);
233
+ const bottom = `${glyphs.bottomLeft}${horizontal.repeat(innerWidth)}${glyphs.bottomRight}`;
216
234
  const lines = block
217
235
  .split('\n')
218
236
  .map((line) => `${vertical}${padText(line, innerWidth, 'left')}${vertical}`);
219
237
  return [top, ...lines, bottom].join('\n');
220
238
  }
221
- /** A full-width horizontal rule, `char` (default `─`) repeated to `width` columns. */
222
- export function ruleLine(width, char = '─') {
239
+ /** The `left`/`right`/`top`/`bottom`/`topLeft`/`topRight`/`bottomLeft`/`bottomRight` glyph set Ink's `Box` `borderStyle` prop takes, matching `frameBlock`'s own character set exactly for `style`. Corners are always the shared set, exactly like `frameBlock`'s (a dashed frame still has solid corners). */
240
+ export function inkBorderStyle(style, glyphs) {
241
+ const { horizontal, vertical } = frameGlyphs(style, glyphs);
242
+ return {
243
+ topLeft: glyphs.topLeft,
244
+ top: horizontal,
245
+ topRight: glyphs.topRight,
246
+ right: vertical,
247
+ bottomRight: glyphs.bottomRight,
248
+ bottom: horizontal,
249
+ bottomLeft: glyphs.bottomLeft,
250
+ left: vertical,
251
+ };
252
+ }
253
+ /** The three-value per-line alignment every self-drawing component's `text=` attribute and every generic `align=` layout preset ultimately reduces to — the ONE spelling both `padText` (a pre-built string) and a caller pre-justifying a line before handing it to Ink share. */
254
+ export const TEXT_ALIGNS = ['left', 'center', 'right'];
255
+ export function isTextAlign(value) {
256
+ return TEXT_ALIGNS.includes(value);
257
+ }
258
+ /** `text` cut to at most `width` terminal columns, with no ellipsis (so no glyph outside the engine's own table). Plain text only: an escape sequence would be measured and cut like prose. */
259
+ export function cutToWidth(text, width) {
260
+ let out = '';
261
+ let used = 0;
262
+ for (const char of text) {
263
+ const next = measureWidth(char);
264
+ if (used + next > width)
265
+ break;
266
+ out += char;
267
+ used += next;
268
+ }
269
+ return out;
270
+ }
271
+ /** A full-width horizontal rule, `char` repeated to `width` columns. */
272
+ export function ruleLine(width, char) {
223
273
  return char.repeat(Math.max(0, width));
224
274
  }
225
- /** Prefixes every line of `block` (split on `\n`) with `prefix`, e.g. a blockquote's `│ `. */
275
+ /** Prefixes every line of `block` (split on `\n`) with `prefix`, e.g. a blockquote's bar. */
226
276
  export function indentBlock(block, prefix) {
227
277
  return block
228
278
  .split('\n')
@@ -231,10 +281,11 @@ export function indentBlock(block, prefix) {
231
281
  }
232
282
  /**
233
283
  * Places `blocks` side by side, each padded (left-aligned) to its entry in
234
- * `widths`, joined by `gutter` spaces, top-aligned. Used only by the plain
235
- * GFM markdown table (`render.tsx`'s `renderGfmTable`) and
236
- * `table-grid.ts`'s own row-drawing; `row`'s OWN columns are placed by a
237
- * real Ink flex `Box` instead (`components/row.tsx`), not by this helper.
284
+ * `widths`, joined by `gutter` spaces, top-aligned. The string emitter of
285
+ * `row` (`render.tsx`'s `renderRowString`, reached when a `row` sits inside
286
+ * a body drawn as a string) places its cells with this. The Ink element
287
+ * emitter (`renderRowElement`) uses a flex `Box` with the same cell widths
288
+ * and gutter, both read from `components/row.ts`'s `resolveRowLayout`.
238
289
  */
239
290
  export function columnsBlock(blocks, widths, gutter) {
240
291
  const gap = ' '.repeat(Math.max(0, gutter));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@markii/ansi",
3
- "version": "0.16.0",
4
- "description": "A framework-free terminal renderer for Markii (.mk.md): a registry-driven hast-to-ANSI-text engine. Zero React; for a terminal, a pipe, or any host that wants a plain string with optional color.",
3
+ "version": "0.17.0-next.0",
4
+ "description": "The terminal renderer for Markii (.mk.md): a registry-driven hast-to-terminal engine built on Ink. Renders a note once as a string with optional color, for a pipe or a log, or as a live Ink tree a host can mount.",
5
5
  "keywords": [
6
6
  "markdown",
7
7
  "markii",
@@ -51,14 +51,15 @@
51
51
  "regenerate:fixtures": "npm run build:dist && node scripts/regenerate-ansi-fixtures.ts"
52
52
  },
53
53
  "dependencies": {
54
- "@markii/core": "^0.16.0",
55
- "@markii/stdlib": "^0.16.0",
54
+ "@markii/core": "^0.17.0-next.0",
55
+ "@markii/pack": "^0.17.0-next.0",
56
+ "@markii/stdlib": "^0.17.0-next.0",
56
57
  "ink": "^7.1.1",
57
58
  "react": "^19.2.0"
58
59
  },
59
60
  "devDependencies": {
60
61
  "@types/hast": "^3.0.4",
61
- "@markii/runtime": "^0.16.0",
62
+ "@markii/runtime": "^0.17.0-next.0",
62
63
  "@types/react": "^19.2.0"
63
64
  }
64
65
  }