@crustjs/style 0.0.1

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.
@@ -0,0 +1,965 @@
1
+ /**
2
+ * An ANSI style pair consisting of an opening and closing escape sequence.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * const bold: AnsiPair = { open: "\x1b[1m", close: "\x1b[22m" };
7
+ * ```
8
+ */
9
+ interface AnsiPair {
10
+ readonly open: string;
11
+ readonly close: string;
12
+ }
13
+ /** Reset all attributes. */
14
+ declare const reset: AnsiPair;
15
+ /** Bold / increased intensity. */
16
+ declare const bold: AnsiPair;
17
+ /** Dim / decreased intensity. */
18
+ declare const dim: AnsiPair;
19
+ /** Italic. */
20
+ declare const italic: AnsiPair;
21
+ /** Underline. */
22
+ declare const underline: AnsiPair;
23
+ /** Inverse / reverse video. */
24
+ declare const inverse: AnsiPair;
25
+ /** Hidden / conceal. */
26
+ declare const hidden: AnsiPair;
27
+ /** Strikethrough / crossed out. */
28
+ declare const strikethrough: AnsiPair;
29
+ declare const black: AnsiPair;
30
+ declare const red: AnsiPair;
31
+ declare const green: AnsiPair;
32
+ declare const yellow: AnsiPair;
33
+ declare const blue: AnsiPair;
34
+ declare const magenta: AnsiPair;
35
+ declare const cyan: AnsiPair;
36
+ declare const white: AnsiPair;
37
+ /** Bright black (gray). */
38
+ declare const gray: AnsiPair;
39
+ declare const brightRed2: AnsiPair;
40
+ declare const brightGreen2: AnsiPair;
41
+ declare const brightYellow2: AnsiPair;
42
+ declare const brightBlue2: AnsiPair;
43
+ declare const brightMagenta2: AnsiPair;
44
+ declare const brightCyan2: AnsiPair;
45
+ declare const brightWhite2: AnsiPair;
46
+ declare const bgBlack2: AnsiPair;
47
+ declare const bgRed2: AnsiPair;
48
+ declare const bgGreen2: AnsiPair;
49
+ declare const bgYellow2: AnsiPair;
50
+ declare const bgBlue2: AnsiPair;
51
+ declare const bgMagenta2: AnsiPair;
52
+ declare const bgCyan2: AnsiPair;
53
+ declare const bgWhite2: AnsiPair;
54
+ declare const bgBrightBlack2: AnsiPair;
55
+ declare const bgBrightRed2: AnsiPair;
56
+ declare const bgBrightGreen2: AnsiPair;
57
+ declare const bgBrightYellow2: AnsiPair;
58
+ declare const bgBrightBlue2: AnsiPair;
59
+ declare const bgBrightMagenta2: AnsiPair;
60
+ declare const bgBrightCyan2: AnsiPair;
61
+ declare const bgBrightWhite2: AnsiPair;
62
+ /**
63
+ * Options for {@link unorderedList}.
64
+ */
65
+ interface UnorderedListOptions {
66
+ /**
67
+ * The bullet marker character.
68
+ *
69
+ * @default "•"
70
+ */
71
+ marker?: string;
72
+ /**
73
+ * Number of spaces between the marker and item content.
74
+ *
75
+ * @default 1
76
+ */
77
+ markerGap?: number;
78
+ /**
79
+ * Base indentation (number of leading spaces) for the entire list.
80
+ *
81
+ * @default 0
82
+ */
83
+ indent?: number;
84
+ }
85
+ /**
86
+ * Options for {@link orderedList}.
87
+ */
88
+ interface OrderedListOptions {
89
+ /**
90
+ * The starting index for numbering.
91
+ *
92
+ * @default 1
93
+ */
94
+ start?: number;
95
+ /**
96
+ * Number of spaces between the marker (e.g. `1.`) and item content.
97
+ *
98
+ * @default 1
99
+ */
100
+ markerGap?: number;
101
+ /**
102
+ * Base indentation (number of leading spaces) for the entire list.
103
+ *
104
+ * @default 0
105
+ */
106
+ indent?: number;
107
+ }
108
+ /**
109
+ * A single task-list item with a checked/unchecked state.
110
+ */
111
+ interface TaskListItem {
112
+ /** The text content of the item. */
113
+ text: string;
114
+ /** Whether the item is checked (complete). */
115
+ checked: boolean;
116
+ }
117
+ /**
118
+ * Options for {@link taskList}.
119
+ */
120
+ interface TaskListOptions {
121
+ /**
122
+ * The marker shown for checked items.
123
+ *
124
+ * @default "[x]"
125
+ */
126
+ checkedMarker?: string;
127
+ /**
128
+ * The marker shown for unchecked items.
129
+ *
130
+ * @default "[ ]"
131
+ */
132
+ uncheckedMarker?: string;
133
+ /**
134
+ * Number of spaces between the marker and item content.
135
+ *
136
+ * @default 1
137
+ */
138
+ markerGap?: number;
139
+ /**
140
+ * Base indentation (number of leading spaces) for the entire list.
141
+ *
142
+ * @default 0
143
+ */
144
+ indent?: number;
145
+ }
146
+ /**
147
+ * Format an array of strings as an unordered (bullet) list.
148
+ *
149
+ * Multiline items have continuation lines indented to align under the
150
+ * first line's content (after the marker). The marker's visible width
151
+ * is used for alignment so ANSI-styled markers work correctly.
152
+ *
153
+ * @param items - The list items (may contain `\n` for multiline content).
154
+ * @param options - Formatting options.
155
+ * @returns The formatted list as a single string.
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * unorderedList(["alpha", "beta", "gamma"]);
160
+ * // "• alpha\n• beta\n• gamma"
161
+ *
162
+ * unorderedList(["first\nsecond line"], { marker: "-" });
163
+ * // "- first\n second line"
164
+ * ```
165
+ */
166
+ declare function unorderedList(items: string[], options?: UnorderedListOptions): string;
167
+ /**
168
+ * Format an array of strings as an ordered (numbered) list.
169
+ *
170
+ * Marker width is computed from the widest index in the sequence so that
171
+ * items align correctly for sequences including 1 through 100+. For example,
172
+ * a 3-item list starting at 1 uses markers `1.`, `2.`, `3.` (all width 2),
173
+ * while a 10-item list right-pads `1.` through `9.` to match `10.` width.
174
+ *
175
+ * Multiline items have continuation lines indented to align under the
176
+ * first line's content (after the marker).
177
+ *
178
+ * @param items - The list items (may contain `\n` for multiline content).
179
+ * @param options - Formatting options.
180
+ * @returns The formatted list as a single string.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * orderedList(["alpha", "beta", "gamma"]);
185
+ * // "1. alpha\n2. beta\n3. gamma"
186
+ *
187
+ * orderedList(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]);
188
+ * // " 1. a\n 2. b\n ... \n10. j"
189
+ * ```
190
+ */
191
+ declare function orderedList(items: string[], options?: OrderedListOptions): string;
192
+ /**
193
+ * Format an array of task items as a checkbox-style task list.
194
+ *
195
+ * Each item is prefixed with a checked or unchecked marker. Multiline
196
+ * items have continuation lines indented to align under the first line's
197
+ * content (after the marker).
198
+ *
199
+ * @param items - The task list items with `text` and `checked` fields.
200
+ * @param options - Formatting options.
201
+ * @returns The formatted task list as a single string.
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * taskList([
206
+ * { text: "Buy milk", checked: true },
207
+ * { text: "Write tests", checked: false },
208
+ * ]);
209
+ * // "[x] Buy milk\n[ ] Write tests"
210
+ * ```
211
+ */
212
+ declare function taskList(items: TaskListItem[], options?: TaskListOptions): string;
213
+ /**
214
+ * Horizontal alignment for a table column.
215
+ */
216
+ type ColumnAlignment = "left" | "right" | "center";
217
+ /**
218
+ * Options for {@link table}.
219
+ */
220
+ interface TableOptions {
221
+ /**
222
+ * Per-column alignment. If fewer alignments than columns are provided,
223
+ * remaining columns default to `"left"`. If omitted, all columns are
224
+ * left-aligned.
225
+ */
226
+ align?: ColumnAlignment[];
227
+ /**
228
+ * Minimum column width (in visible characters). Columns are always at
229
+ * least as wide as their widest cell content regardless of this setting.
230
+ *
231
+ * @default 0
232
+ */
233
+ minColumnWidth?: number;
234
+ /**
235
+ * Padding (number of spaces) added to each side of every cell.
236
+ *
237
+ * @default 1
238
+ */
239
+ cellPadding?: number;
240
+ /**
241
+ * The character used for the horizontal separator line.
242
+ *
243
+ * @default "-"
244
+ */
245
+ separatorChar?: string;
246
+ /**
247
+ * The column separator character placed between cells.
248
+ *
249
+ * @default "|"
250
+ */
251
+ borderChar?: string;
252
+ }
253
+ /**
254
+ * Format tabular data as an aligned, bordered table string.
255
+ *
256
+ * The table includes a header row, a separator row, and data rows.
257
+ * Column widths are computed from the visible width of all cell content
258
+ * (ANSI escape sequences are excluded from width calculations), so styled
259
+ * cell values align correctly.
260
+ *
261
+ * @param headers - The header row cells.
262
+ * @param rows - The data rows (each row is an array of cell strings).
263
+ * @param options - Formatting options.
264
+ * @returns The formatted table as a single string.
265
+ *
266
+ * @example
267
+ * ```ts
268
+ * table(
269
+ * ["Name", "Age"],
270
+ * [
271
+ * ["Alice", "30"],
272
+ * ["Bob", "25"],
273
+ * ],
274
+ * );
275
+ * // "| Name | Age |"
276
+ * // "|-------|-----|"
277
+ * // "| Alice | 30 |"
278
+ * // "| Bob | 25 |"
279
+ * ```
280
+ */
281
+ declare function table(headers: string[], rows: string[][], options?: TableOptions): string;
282
+ /**
283
+ * Color emission mode for the style engine.
284
+ *
285
+ * - `"auto"` — Emit ANSI codes when stdout is a TTY and `NO_COLOR` is not set.
286
+ * - `"always"` — Always emit ANSI codes regardless of terminal detection.
287
+ * - `"never"` — Never emit ANSI codes; return plain text.
288
+ *
289
+ * @example
290
+ * ```ts
291
+ * const style = createStyle({ mode: "never" });
292
+ * style.bold("text"); // "text" (no ANSI codes)
293
+ * ```
294
+ */
295
+ type ColorMode = "auto" | "always" | "never";
296
+ /**
297
+ * Capability inputs for deterministic testing.
298
+ *
299
+ * When provided, these override the runtime environment checks.
300
+ * This allows tests to simulate different terminal environments
301
+ * without modifying `process.env` or `process.stdout`.
302
+ */
303
+ interface CapabilityOverrides {
304
+ /** Override `process.stdout.isTTY`. */
305
+ readonly isTTY?: boolean;
306
+ /** Override `process.env.NO_COLOR`. */
307
+ readonly noColor?: string | undefined;
308
+ }
309
+ /**
310
+ * Configuration options for creating a style instance.
311
+ *
312
+ * @example
313
+ * ```ts
314
+ * const style = createStyle({ mode: "always" });
315
+ * ```
316
+ */
317
+ interface StyleOptions {
318
+ /** Color emission mode. Defaults to `"auto"`. */
319
+ readonly mode?: ColorMode;
320
+ /** Capability overrides for deterministic testing. */
321
+ readonly overrides?: CapabilityOverrides;
322
+ }
323
+ /**
324
+ * A style function that applies an ANSI style pair to text,
325
+ * respecting the configured color mode.
326
+ */
327
+ type StyleFn = (text: string) => string;
328
+ /**
329
+ * A configured style instance with mode-aware styling functions.
330
+ *
331
+ * In `"never"` mode, all functions return plain text without ANSI codes.
332
+ * In `"always"` mode, ANSI codes are always emitted.
333
+ * In `"auto"` mode, behavior depends on terminal capability detection.
334
+ */
335
+ interface StyleInstance {
336
+ /** Whether ANSI codes will be emitted by this instance. */
337
+ readonly enabled: boolean;
338
+ /** Apply an arbitrary ANSI pair to text, respecting the color mode. */
339
+ readonly apply: (text: string, pair: AnsiPair) => string;
340
+ readonly bold: StyleFn;
341
+ readonly dim: StyleFn;
342
+ readonly italic: StyleFn;
343
+ readonly underline: StyleFn;
344
+ readonly inverse: StyleFn;
345
+ readonly hidden: StyleFn;
346
+ readonly strikethrough: StyleFn;
347
+ readonly black: StyleFn;
348
+ readonly red: StyleFn;
349
+ readonly green: StyleFn;
350
+ readonly yellow: StyleFn;
351
+ readonly blue: StyleFn;
352
+ readonly magenta: StyleFn;
353
+ readonly cyan: StyleFn;
354
+ readonly white: StyleFn;
355
+ readonly gray: StyleFn;
356
+ readonly brightRed: StyleFn;
357
+ readonly brightGreen: StyleFn;
358
+ readonly brightYellow: StyleFn;
359
+ readonly brightBlue: StyleFn;
360
+ readonly brightMagenta: StyleFn;
361
+ readonly brightCyan: StyleFn;
362
+ readonly brightWhite: StyleFn;
363
+ readonly bgBlack: StyleFn;
364
+ readonly bgRed: StyleFn;
365
+ readonly bgGreen: StyleFn;
366
+ readonly bgYellow: StyleFn;
367
+ readonly bgBlue: StyleFn;
368
+ readonly bgMagenta: StyleFn;
369
+ readonly bgCyan: StyleFn;
370
+ readonly bgWhite: StyleFn;
371
+ readonly bgBrightBlack: StyleFn;
372
+ readonly bgBrightRed: StyleFn;
373
+ readonly bgBrightGreen: StyleFn;
374
+ readonly bgBrightYellow: StyleFn;
375
+ readonly bgBrightBlue: StyleFn;
376
+ readonly bgBrightMagenta: StyleFn;
377
+ readonly bgBrightCyan: StyleFn;
378
+ readonly bgBrightWhite: StyleFn;
379
+ }
380
+ /**
381
+ * Resolve whether ANSI color codes should be emitted.
382
+ *
383
+ * Resolution rules:
384
+ * - `"always"` → `true` regardless of environment.
385
+ * - `"never"` → `false` regardless of environment.
386
+ * - `"auto"` → `true` only when stdout is a TTY **and** the `NO_COLOR`
387
+ * environment variable is not set. Any non-undefined value of `NO_COLOR`
388
+ * (including the empty string `""`) disables color, per the
389
+ * [NO_COLOR convention](https://no-color.org/).
390
+ *
391
+ * The `overrides` parameter allows deterministic testing by injecting
392
+ * capability inputs instead of reading from the runtime environment.
393
+ *
394
+ * @param mode - The color emission mode.
395
+ * @param overrides - Optional overrides for TTY and NO_COLOR detection.
396
+ * @returns `true` if ANSI codes should be emitted, `false` otherwise.
397
+ *
398
+ * @example
399
+ * ```ts
400
+ * resolveCapability("auto"); // true if TTY and NO_COLOR not set
401
+ * resolveCapability("always"); // true
402
+ * resolveCapability("never"); // false
403
+ * resolveCapability("auto", { isTTY: true, noColor: undefined }); // true
404
+ * resolveCapability("auto", { isTTY: true, noColor: "" }); // false
405
+ * ```
406
+ */
407
+ declare function resolveCapability(mode: ColorMode, overrides?: CapabilityOverrides): boolean;
408
+ /** Apply black foreground color. */
409
+ declare function black2(text: string): string;
410
+ /** Apply red foreground color. */
411
+ declare function red2(text: string): string;
412
+ /** Apply green foreground color. */
413
+ declare function green2(text: string): string;
414
+ /** Apply yellow foreground color. */
415
+ declare function yellow2(text: string): string;
416
+ /** Apply blue foreground color. */
417
+ declare function blue2(text: string): string;
418
+ /** Apply magenta foreground color. */
419
+ declare function magenta2(text: string): string;
420
+ /** Apply cyan foreground color. */
421
+ declare function cyan2(text: string): string;
422
+ /** Apply white foreground color. */
423
+ declare function white2(text: string): string;
424
+ /** Apply gray (bright black) foreground color. */
425
+ declare function gray2(text: string): string;
426
+ /** Apply bright red foreground color. */
427
+ declare function brightRed3(text: string): string;
428
+ /** Apply bright green foreground color. */
429
+ declare function brightGreen3(text: string): string;
430
+ /** Apply bright yellow foreground color. */
431
+ declare function brightYellow3(text: string): string;
432
+ /** Apply bright blue foreground color. */
433
+ declare function brightBlue3(text: string): string;
434
+ /** Apply bright magenta foreground color. */
435
+ declare function brightMagenta3(text: string): string;
436
+ /** Apply bright cyan foreground color. */
437
+ declare function brightCyan3(text: string): string;
438
+ /** Apply bright white foreground color. */
439
+ declare function brightWhite3(text: string): string;
440
+ /** Apply black background color. */
441
+ declare function bgBlack3(text: string): string;
442
+ /** Apply red background color. */
443
+ declare function bgRed3(text: string): string;
444
+ /** Apply green background color. */
445
+ declare function bgGreen3(text: string): string;
446
+ /** Apply yellow background color. */
447
+ declare function bgYellow3(text: string): string;
448
+ /** Apply blue background color. */
449
+ declare function bgBlue3(text: string): string;
450
+ /** Apply magenta background color. */
451
+ declare function bgMagenta3(text: string): string;
452
+ /** Apply cyan background color. */
453
+ declare function bgCyan3(text: string): string;
454
+ /** Apply white background color. */
455
+ declare function bgWhite3(text: string): string;
456
+ /** Apply bright black background color. */
457
+ declare function bgBrightBlack3(text: string): string;
458
+ /** Apply bright red background color. */
459
+ declare function bgBrightRed3(text: string): string;
460
+ /** Apply bright green background color. */
461
+ declare function bgBrightGreen3(text: string): string;
462
+ /** Apply bright yellow background color. */
463
+ declare function bgBrightYellow3(text: string): string;
464
+ /** Apply bright blue background color. */
465
+ declare function bgBrightBlue3(text: string): string;
466
+ /** Apply bright magenta background color. */
467
+ declare function bgBrightMagenta3(text: string): string;
468
+ /** Apply bright cyan background color. */
469
+ declare function bgBrightCyan3(text: string): string;
470
+ /** Apply bright white background color. */
471
+ declare function bgBrightWhite3(text: string): string;
472
+ /**
473
+ * Create a configured style instance with mode-aware styling functions.
474
+ *
475
+ * The returned instance provides the full set of modifier, foreground color,
476
+ * and background color functions. In `"never"` mode (or when `"auto"` mode
477
+ * resolves to disabled), all functions return plain text without ANSI codes.
478
+ * In `"always"` mode (or when `"auto"` resolves to enabled), ANSI codes are
479
+ * emitted via the nesting-safe style engine.
480
+ *
481
+ * @param options - Configuration options. Defaults to `{ mode: "auto" }`.
482
+ * @returns A frozen {@link StyleInstance} with all styling functions.
483
+ *
484
+ * @example
485
+ * ```ts
486
+ * // Auto-detect terminal capabilities
487
+ * const s = createStyle();
488
+ * console.log(s.bold("hello"));
489
+ *
490
+ * // Force color output
491
+ * const color = createStyle({ mode: "always" });
492
+ * console.log(color.red("error"));
493
+ *
494
+ * // Disable all styling
495
+ * const plain = createStyle({ mode: "never" });
496
+ * console.log(plain.red("error")); // "error"
497
+ *
498
+ * // Deterministic testing
499
+ * const test = createStyle({
500
+ * mode: "auto",
501
+ * overrides: { isTTY: true, noColor: undefined },
502
+ * });
503
+ * ```
504
+ */
505
+ declare function createStyle(options?: StyleOptions): StyleInstance;
506
+ /**
507
+ * Default style instance using `"auto"` mode.
508
+ *
509
+ * Emits ANSI codes when stdout is a TTY and `NO_COLOR` is not set.
510
+ * Import this for convenient access without explicit configuration.
511
+ *
512
+ * @example
513
+ * ```ts
514
+ * import { style } from "@crustjs/style";
515
+ *
516
+ * console.log(style.bold("hello"));
517
+ * console.log(style.red("error"));
518
+ * ```
519
+ */
520
+ declare const style: StyleInstance;
521
+ /**
522
+ * Apply **bold** (increased intensity) to text.
523
+ *
524
+ * @example
525
+ * ```ts
526
+ * bold("important") // "\x1b[1mimportant\x1b[22m"
527
+ * ```
528
+ */
529
+ declare function bold2(text: string): string;
530
+ /**
531
+ * Apply **dim** (decreased intensity) to text.
532
+ *
533
+ * @example
534
+ * ```ts
535
+ * dim("secondary") // "\x1b[2msecondary\x1b[22m"
536
+ * ```
537
+ */
538
+ declare function dim2(text: string): string;
539
+ /**
540
+ * Apply *italic* to text.
541
+ *
542
+ * @example
543
+ * ```ts
544
+ * italic("emphasis") // "\x1b[3memphasis\x1b[23m"
545
+ * ```
546
+ */
547
+ declare function italic2(text: string): string;
548
+ /**
549
+ * Apply underline to text.
550
+ *
551
+ * @example
552
+ * ```ts
553
+ * underline("link") // "\x1b[4mlink\x1b[24m"
554
+ * ```
555
+ */
556
+ declare function underline2(text: string): string;
557
+ /**
558
+ * Apply inverse (reverse video) to text.
559
+ *
560
+ * @example
561
+ * ```ts
562
+ * inverse("highlighted") // "\x1b[7mhighlighted\x1b[27m"
563
+ * ```
564
+ */
565
+ declare function inverse2(text: string): string;
566
+ /**
567
+ * Apply hidden (conceal) to text.
568
+ *
569
+ * @example
570
+ * ```ts
571
+ * hidden("secret") // "\x1b[8msecret\x1b[28m"
572
+ * ```
573
+ */
574
+ declare function hidden2(text: string): string;
575
+ /**
576
+ * Apply ~~strikethrough~~ to text.
577
+ *
578
+ * @example
579
+ * ```ts
580
+ * strikethrough("removed") // "\x1b[9mremoved\x1b[29m"
581
+ * ```
582
+ */
583
+ declare function strikethrough2(text: string): string;
584
+ /**
585
+ * Apply an ANSI style pair to a string with nesting-safe composition.
586
+ *
587
+ * When the input already contains the close sequence for the applied style
588
+ * (e.g. from a nested style call that shares the same close code), the engine
589
+ * reopens the outer style after each inner close to prevent style bleed.
590
+ *
591
+ * @param text - The string to style.
592
+ * @param style - The ANSI pair to apply.
593
+ * @returns The styled string, or the original string if empty.
594
+ *
595
+ * @example
596
+ * ```ts
597
+ * import { applyStyle } from "./styleEngine.ts";
598
+ * import { bold, red } from "./ansiCodes.ts";
599
+ *
600
+ * // Simple usage
601
+ * applyStyle("hello", bold); // "\x1b[1mhello\x1b[22m"
602
+ *
603
+ * // Nesting: bold wraps a red segment — bold reopens after red's close
604
+ * const inner = applyStyle("world", red);
605
+ * applyStyle(`hello ${inner}!`, bold);
606
+ * ```
607
+ */
608
+ declare function applyStyle(text: string, style: AnsiPair): string;
609
+ /**
610
+ * Compose multiple ANSI style pairs into a single style pair.
611
+ *
612
+ * The composed pair opens all styles in order and closes them in reverse
613
+ * order. Useful for creating reusable compound styles.
614
+ *
615
+ * @param styles - The ANSI pairs to compose.
616
+ * @returns A single composed ANSI pair.
617
+ *
618
+ * @example
619
+ * ```ts
620
+ * import { composeStyles } from "./styleEngine.ts";
621
+ * import { bold, red } from "./ansiCodes.ts";
622
+ *
623
+ * const boldRed = composeStyles(bold, red);
624
+ * applyStyle("error", boldRed);
625
+ * ```
626
+ */
627
+ declare function composeStyles(...styles: AnsiPair[]): AnsiPair;
628
+ /**
629
+ * Pad a string on the left (right-align) to the given visible width.
630
+ *
631
+ * Uses {@link visibleWidth} to measure the string, so ANSI escape sequences
632
+ * are excluded from the width calculation. If the string is already at or
633
+ * beyond the target width, it is returned unchanged.
634
+ *
635
+ * @param text - The string to pad (may contain ANSI escapes).
636
+ * @param width - The target visible width.
637
+ * @param fillChar - The character used for padding (default: space).
638
+ * @returns The padded string.
639
+ *
640
+ * @example
641
+ * ```ts
642
+ * padStart("hi", 5); // " hi"
643
+ * padStart("hi", 5, "."); // "...hi"
644
+ * padStart("\x1b[1mhi\x1b[22m", 5); // " \x1b[1mhi\x1b[22m"
645
+ * ```
646
+ */
647
+ declare function padStart(text: string, width: number, fillChar?: string): string;
648
+ /**
649
+ * Pad a string on the right (left-align) to the given visible width.
650
+ *
651
+ * Uses {@link visibleWidth} to measure the string, so ANSI escape sequences
652
+ * are excluded from the width calculation. If the string is already at or
653
+ * beyond the target width, it is returned unchanged.
654
+ *
655
+ * @param text - The string to pad (may contain ANSI escapes).
656
+ * @param width - The target visible width.
657
+ * @param fillChar - The character used for padding (default: space).
658
+ * @returns The padded string.
659
+ *
660
+ * @example
661
+ * ```ts
662
+ * padEnd("hi", 5); // "hi "
663
+ * padEnd("hi", 5, "."); // "hi..."
664
+ * padEnd("\x1b[1mhi\x1b[22m", 5); // "\x1b[1mhi\x1b[22m "
665
+ * ```
666
+ */
667
+ declare function padEnd(text: string, width: number, fillChar?: string): string;
668
+ /**
669
+ * Center a string within the given visible width.
670
+ *
671
+ * Distributes padding evenly on both sides. When the remaining space is
672
+ * odd, the extra character is placed on the right side.
673
+ *
674
+ * Uses {@link visibleWidth} to measure the string, so ANSI escape sequences
675
+ * are excluded from the width calculation. If the string is already at or
676
+ * beyond the target width, it is returned unchanged.
677
+ *
678
+ * @param text - The string to center (may contain ANSI escapes).
679
+ * @param width - The target visible width.
680
+ * @param fillChar - The character used for padding (default: space).
681
+ * @returns The centered string.
682
+ *
683
+ * @example
684
+ * ```ts
685
+ * center("hi", 6); // " hi "
686
+ * center("hi", 7); // " hi "
687
+ * center("\x1b[1mhi\x1b[22m", 6); // " \x1b[1mhi\x1b[22m "
688
+ * ```
689
+ */
690
+ declare function center(text: string, width: number, fillChar?: string): string;
691
+ /**
692
+ * Remove all ANSI escape sequences from a string.
693
+ *
694
+ * Returns the plain-text content with all styling, cursor, and control
695
+ * escape sequences stripped. Useful for computing visible text width,
696
+ * logging plain output, or comparing styled strings by content.
697
+ *
698
+ * @param text - The string potentially containing ANSI escape codes.
699
+ * @returns The string with all ANSI escapes removed.
700
+ *
701
+ * @example
702
+ * ```ts
703
+ * import { stripAnsi } from "./stripAnsi.ts";
704
+ *
705
+ * stripAnsi("\x1b[1mhello\x1b[22m"); // "hello"
706
+ * stripAnsi("no escapes"); // "no escapes"
707
+ * ```
708
+ */
709
+ declare function stripAnsi(text: string): string;
710
+ /**
711
+ * Compute the visible (column) width of a string.
712
+ *
713
+ * ANSI escape sequences are stripped before measurement. Full-width
714
+ * characters (CJK, fullwidth forms) count as 2 columns; all other
715
+ * printable characters count as 1.
716
+ *
717
+ * Only measures a single line. For multiline strings, split on `\n`
718
+ * and measure each line individually.
719
+ *
720
+ * @param text - The string to measure (may contain ANSI escapes).
721
+ * @returns The visible width in terminal columns.
722
+ *
723
+ * @example
724
+ * ```ts
725
+ * import { visibleWidth } from "./width.ts";
726
+ *
727
+ * visibleWidth("hello"); // 5
728
+ * visibleWidth("\x1b[1mhello\x1b[22m"); // 5
729
+ * visibleWidth("\u4f60\u597d"); // 4 (two CJK characters)
730
+ * ```
731
+ */
732
+ declare function visibleWidth(text: string): number;
733
+ /**
734
+ * Options for {@link wrapText}.
735
+ */
736
+ interface WrapOptions {
737
+ /**
738
+ * Whether to perform word-aware wrapping. When `true`, the wrapper
739
+ * breaks at the last space before the width limit rather than mid-word.
740
+ * If a single word exceeds the width, it is force-broken.
741
+ *
742
+ * @default true
743
+ */
744
+ wordBreak?: boolean;
745
+ }
746
+ /**
747
+ * Wrap text to a maximum visible width, preserving ANSI style continuity
748
+ * across line breaks.
749
+ *
750
+ * When a line is broken, any active ANSI styles are closed at the end of the
751
+ * current line and reopened at the start of the next line. This ensures each
752
+ * output line is a self-contained, properly-terminated styled string.
753
+ *
754
+ * Existing newlines in the input are preserved — each logical line is wrapped
755
+ * independently.
756
+ *
757
+ * @param text - The input text (may contain ANSI escape codes and newlines).
758
+ * @param width - The maximum visible width per line (in terminal columns).
759
+ * @param options - Optional wrapping behavior configuration.
760
+ * @returns The wrapped text with style continuity preserved.
761
+ *
762
+ * @example
763
+ * ```ts
764
+ * import { wrapText } from "./wrap.ts";
765
+ *
766
+ * wrapText("hello world", 5);
767
+ * // "hello\nworld"
768
+ *
769
+ * wrapText("\x1b[1mhello world\x1b[22m", 5);
770
+ * // "\x1b[1mhello\x1b[22m\n\x1b[1mworld\x1b[22m"
771
+ * ```
772
+ */
773
+ declare function wrapText(text: string, width: number, options?: WrapOptions): string;
774
+ /**
775
+ * A style function that transforms a string for themed terminal output.
776
+ *
777
+ * Theme slot functions are pure string-in/string-out transformers.
778
+ * They may apply ANSI styling, add structural markers, or return
779
+ * the input unchanged — depending on the theme configuration and
780
+ * color mode.
781
+ */
782
+ type ThemeSlotFn = (value: string) => string;
783
+ /**
784
+ * Semantic theme contract for GitHub Flavored Markdown (GFM) presentation.
785
+ *
786
+ * Each slot corresponds to a distinct GFM construct. A markdown renderer
787
+ * maps parsed AST nodes to these slots to produce styled terminal output.
788
+ * The theme itself is parser-agnostic — it only defines how to style
789
+ * already-extracted text for each construct.
790
+ *
791
+ * All slots are `string => string` functions. When colors are disabled,
792
+ * slots should preserve textual structure and readability without ANSI codes.
793
+ *
794
+ * @example
795
+ * ```ts
796
+ * import { defaultTheme } from "@crustjs/style";
797
+ *
798
+ * // Use theme slots to style extracted markdown content
799
+ * const styled = defaultTheme.heading1("Introduction");
800
+ * console.log(styled); // Bold + underlined "Introduction"
801
+ * ```
802
+ */
803
+ interface MarkdownTheme {
804
+ /** ATX heading level 1 text. */
805
+ readonly heading1: ThemeSlotFn;
806
+ /** ATX heading level 2 text. */
807
+ readonly heading2: ThemeSlotFn;
808
+ /** ATX heading level 3 text. */
809
+ readonly heading3: ThemeSlotFn;
810
+ /** ATX heading level 4 text. */
811
+ readonly heading4: ThemeSlotFn;
812
+ /** ATX heading level 5 text. */
813
+ readonly heading5: ThemeSlotFn;
814
+ /** ATX heading level 6 text. */
815
+ readonly heading6: ThemeSlotFn;
816
+ /** Default paragraph / body text. */
817
+ readonly text: ThemeSlotFn;
818
+ /** Italic emphasis (`*text*` or `_text_`). */
819
+ readonly emphasis: ThemeSlotFn;
820
+ /** Bold / strong emphasis (`**text**` or `__text__`). */
821
+ readonly strong: ThemeSlotFn;
822
+ /** Bold + italic (`***text***`). */
823
+ readonly strongEmphasis: ThemeSlotFn;
824
+ /** Strikethrough (`~~text~~`). */
825
+ readonly strikethrough: ThemeSlotFn;
826
+ /** Inline code span (`` `code` ``). */
827
+ readonly inlineCode: ThemeSlotFn;
828
+ /** Link display text (`[text](url)`). */
829
+ readonly linkText: ThemeSlotFn;
830
+ /** Link destination URL. */
831
+ readonly linkUrl: ThemeSlotFn;
832
+ /** Autolink display text (`<https://...>`). */
833
+ readonly autolink: ThemeSlotFn;
834
+ /** Blockquote prefix/marker (e.g. `>`). */
835
+ readonly blockquoteMarker: ThemeSlotFn;
836
+ /** Blockquote body text content. */
837
+ readonly blockquoteText: ThemeSlotFn;
838
+ /** Unordered list bullet marker. */
839
+ readonly listMarker: ThemeSlotFn;
840
+ /** Ordered list number marker (e.g. `1.`). */
841
+ readonly orderedListMarker: ThemeSlotFn;
842
+ /** Task list checked marker (e.g. `[x]`). */
843
+ readonly taskChecked: ThemeSlotFn;
844
+ /** Task list unchecked marker (e.g. `[ ]`). */
845
+ readonly taskUnchecked: ThemeSlotFn;
846
+ /** Code fence delimiter (e.g. ` ``` `). */
847
+ readonly codeFence: ThemeSlotFn;
848
+ /** Code block info string / language label. */
849
+ readonly codeInfo: ThemeSlotFn;
850
+ /** Code block body text. */
851
+ readonly codeText: ThemeSlotFn;
852
+ /** Thematic break / horizontal rule. */
853
+ readonly thematicBreak: ThemeSlotFn;
854
+ /** Table header cell text. */
855
+ readonly tableHeader: ThemeSlotFn;
856
+ /** Table body cell text. */
857
+ readonly tableCell: ThemeSlotFn;
858
+ /** Table border / separator characters. */
859
+ readonly tableBorder: ThemeSlotFn;
860
+ /** Image alt text. */
861
+ readonly imageAltText: ThemeSlotFn;
862
+ /** Image URL / destination. */
863
+ readonly imageUrl: ThemeSlotFn;
864
+ }
865
+ /**
866
+ * Partial theme override type for {@link createTheme}.
867
+ *
868
+ * Allows overriding any subset of theme slots while inheriting
869
+ * defaults for the rest.
870
+ */
871
+ type PartialMarkdownTheme = Partial<MarkdownTheme>;
872
+ /**
873
+ * Build a default {@link MarkdownTheme} from a {@link StyleInstance}.
874
+ *
875
+ * The returned theme uses the style instance's modifier and color functions,
876
+ * so color emission respects the instance's configured mode (`auto` / `always`
877
+ * / `never`). When colors are disabled the slots return the input unchanged
878
+ * (identity functions), preserving textual structure and readability.
879
+ *
880
+ * @param s - The style instance to derive theme functions from.
881
+ * @returns A frozen {@link MarkdownTheme} with readable default styles.
882
+ *
883
+ * @example
884
+ * ```ts
885
+ * import { createStyle } from "@crustjs/style";
886
+ * import { buildDefaultTheme } from "./defaultTheme.ts";
887
+ *
888
+ * const theme = buildDefaultTheme(createStyle({ mode: "always" }));
889
+ * console.log(theme.heading1("Title")); // bold + underlined
890
+ * ```
891
+ */
892
+ declare function buildDefaultMarkdownTheme(s: StyleInstance): MarkdownTheme;
893
+ /**
894
+ * Options for {@link createMarkdownTheme}.
895
+ */
896
+ interface CreateMarkdownThemeOptions {
897
+ /**
898
+ * Style configuration options (mode and capability overrides).
899
+ *
900
+ * When provided, a new {@link StyleInstance} is created with these
901
+ * options and used to build the default theme base. When omitted,
902
+ * the default `"auto"` mode is used.
903
+ */
904
+ readonly style?: StyleOptions;
905
+ /**
906
+ * Partial theme overrides to merge on top of the default theme.
907
+ *
908
+ * Only the slots you provide are overridden; all other slots
909
+ * inherit from the default theme.
910
+ *
911
+ * @example
912
+ * ```ts
913
+ * createMarkdownTheme({
914
+ * overrides: {
915
+ * heading1: (value) => `## ${value.toUpperCase()} ##`,
916
+ * },
917
+ * });
918
+ * ```
919
+ */
920
+ readonly overrides?: PartialMarkdownTheme;
921
+ }
922
+ /**
923
+ * Create a {@link MarkdownTheme} with optional style configuration and
924
+ * partial slot overrides.
925
+ *
926
+ * The factory builds a default theme using the specified style mode and
927
+ * then applies any provided overrides on top. This enables consumers to
928
+ * customize individual slots while inheriting defaults for the rest.
929
+ *
930
+ * @param options - Style configuration and/or partial theme overrides.
931
+ * @returns A frozen {@link MarkdownTheme} instance.
932
+ *
933
+ * @example
934
+ * ```ts
935
+ * import { createMarkdownTheme } from "@crustjs/style";
936
+ *
937
+ * // Default theme with auto mode
938
+ * const theme = createMarkdownTheme();
939
+ *
940
+ * // Force colors + custom heading
941
+ * const custom = createMarkdownTheme({
942
+ * style: { mode: "always" },
943
+ * overrides: {
944
+ * heading1: (value) => `# ${value.toUpperCase()}`,
945
+ * },
946
+ * });
947
+ * ```
948
+ */
949
+ declare function createMarkdownTheme(options?: CreateMarkdownThemeOptions): MarkdownTheme;
950
+ /**
951
+ * Default markdown theme using `"auto"` mode.
952
+ *
953
+ * Emits styled output when stdout is a TTY and `NO_COLOR` is not set.
954
+ * Import this for convenient access without explicit configuration.
955
+ *
956
+ * @example
957
+ * ```ts
958
+ * import { defaultTheme } from "@crustjs/style";
959
+ *
960
+ * console.log(defaultTheme.heading1("Title"));
961
+ * console.log(defaultTheme.strong("important"));
962
+ * ```
963
+ */
964
+ declare const defaultTheme: MarkdownTheme;
965
+ export { yellow as yellowCode, yellow2 as yellow, wrapText, white as whiteCode, white2 as white, visibleWidth, unorderedList, underline as underlineCode, underline2 as underline, taskList, table, style, stripAnsi, strikethrough as strikethroughCode, strikethrough2 as strikethrough, resolveCapability, reset, red as redCode, red2 as red, padStart, padEnd, orderedList, magenta as magentaCode, magenta2 as magenta, italic as italicCode, italic2 as italic, inverse as inverseCode, inverse2 as inverse, hidden as hiddenCode, hidden2 as hidden, green as greenCode, green2 as green, gray as grayCode, gray2 as gray, dim as dimCode, dim2 as dim, defaultTheme, cyan as cyanCode, cyan2 as cyan, createStyle, createMarkdownTheme, composeStyles, center, buildDefaultMarkdownTheme, brightYellow2 as brightYellowCode, brightYellow3 as brightYellow, brightWhite2 as brightWhiteCode, brightWhite3 as brightWhite, brightRed2 as brightRedCode, brightRed3 as brightRed, brightMagenta2 as brightMagentaCode, brightMagenta3 as brightMagenta, brightGreen2 as brightGreenCode, brightGreen3 as brightGreen, brightCyan2 as brightCyanCode, brightCyan3 as brightCyan, brightBlue2 as brightBlueCode, brightBlue3 as brightBlue, bold as boldCode, bold2 as bold, blue as blueCode, blue2 as blue, black as blackCode, black2 as black, bgYellow2 as bgYellowCode, bgYellow3 as bgYellow, bgWhite2 as bgWhiteCode, bgWhite3 as bgWhite, bgRed2 as bgRedCode, bgRed3 as bgRed, bgMagenta2 as bgMagentaCode, bgMagenta3 as bgMagenta, bgGreen2 as bgGreenCode, bgGreen3 as bgGreen, bgCyan2 as bgCyanCode, bgCyan3 as bgCyan, bgBrightYellow2 as bgBrightYellowCode, bgBrightYellow3 as bgBrightYellow, bgBrightWhite2 as bgBrightWhiteCode, bgBrightWhite3 as bgBrightWhite, bgBrightRed2 as bgBrightRedCode, bgBrightRed3 as bgBrightRed, bgBrightMagenta2 as bgBrightMagentaCode, bgBrightMagenta3 as bgBrightMagenta, bgBrightGreen2 as bgBrightGreenCode, bgBrightGreen3 as bgBrightGreen, bgBrightCyan2 as bgBrightCyanCode, bgBrightCyan3 as bgBrightCyan, bgBrightBlue2 as bgBrightBlueCode, bgBrightBlue3 as bgBrightBlue, bgBrightBlack2 as bgBrightBlackCode, bgBrightBlack3 as bgBrightBlack, bgBlue2 as bgBlueCode, bgBlue3 as bgBlue, bgBlack2 as bgBlackCode, bgBlack3 as bgBlack, applyStyle, WrapOptions, UnorderedListOptions, ThemeSlotFn, TaskListOptions, TaskListItem, TableOptions, StyleOptions, StyleInstance, StyleFn, PartialMarkdownTheme, OrderedListOptions, MarkdownTheme, CreateMarkdownThemeOptions, ColumnAlignment, ColorMode, CapabilityOverrides, AnsiPair };