ansimax 1.4.0 → 1.4.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.
- package/CHANGELOG.md +105 -0
- package/README.es.md +26 -2
- package/README.md +26 -2
- package/dist/index.d.mts +120 -96
- package/dist/index.d.ts +120 -96
- package/dist/index.js +129 -56
- package/dist/index.mjs +129 -56
- package/examples/all-in-one.cjs +1 -1
- package/examples/all-in-one.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,111 @@
|
|
|
3
3
|
All notable changes to **ansimax** are documented in this file.
|
|
4
4
|
This project follows [Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [1.4.1] — Grid v2 + markdown internal refactor
|
|
7
|
+
|
|
8
|
+
Patch release with two improvements: **grid** gains CSS Grid-style
|
|
9
|
+
column spans + uniform row heights + flow direction control, and the
|
|
10
|
+
**markdown** module is internally refactored from a 522-line monolith
|
|
11
|
+
into 4 focused files (no API changes).
|
|
12
|
+
|
|
13
|
+
### Added — `panels.grid` v2
|
|
14
|
+
|
|
15
|
+
**`colSpan: number[]`** — per-block column span (CSS Grid-style):
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { panels, ascii } from 'ansimax';
|
|
19
|
+
|
|
20
|
+
const header = ascii.box('Dashboard', { borderStyle: 'rounded' });
|
|
21
|
+
const sidebar = ascii.box('Sidebar', { borderStyle: 'rounded' });
|
|
22
|
+
const content = ascii.box('Main content area', { borderStyle: 'rounded' });
|
|
23
|
+
const footer = ascii.box('Footer', { borderStyle: 'rounded' });
|
|
24
|
+
|
|
25
|
+
// 2 columns, header + footer span the full width
|
|
26
|
+
console.log(panels.grid([header, sidebar, content, footer], {
|
|
27
|
+
columns: 2,
|
|
28
|
+
colSpan: [2, 1, 1, 2],
|
|
29
|
+
}));
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Auto-flow: each block consumes its `span` columns. If a row's remaining
|
|
33
|
+
capacity can't fit the next block, the layout wraps to a new row.
|
|
34
|
+
Invalid spans (NaN, negative, > columns) are normalized to safe values.
|
|
35
|
+
|
|
36
|
+
**`cellHeight: number | null`** — uniform vertical sizing per row:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
// All rows exactly 5 lines tall — short blocks padded, tall blocks truncated
|
|
40
|
+
panels.grid(blocks, { columns: 3, cellHeight: 5 });
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Complements the existing `cellWidth` option for fully uniform grids.
|
|
44
|
+
|
|
45
|
+
**`flow: 'row' | 'column'`** — auto-flow direction:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
// Default: row flow (left-to-right, then wrap down)
|
|
49
|
+
panels.grid([1, 2, 3, 4, 5, 6], { columns: 3, flow: 'row' });
|
|
50
|
+
// 1 2 3
|
|
51
|
+
// 4 5 6
|
|
52
|
+
|
|
53
|
+
// Column flow (top-to-bottom, then wrap right)
|
|
54
|
+
panels.grid([1, 2, 3, 4, 5, 6], { columns: 3, flow: 'column' });
|
|
55
|
+
// 1 3 5
|
|
56
|
+
// 2 4 6
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When `colSpan` contains values > 1, flow is forced to `'row'` (the
|
|
60
|
+
column-flow + spans combination requires a full packing algorithm,
|
|
61
|
+
deferred to a later release).
|
|
62
|
+
|
|
63
|
+
### Improved — `markdown` module refactored
|
|
64
|
+
|
|
65
|
+
The single-file `src/markdown/index.ts` (522 lines) split into 5 files
|
|
66
|
+
of focused responsibility — **zero API changes, fully backward compatible**:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
src/markdown/
|
|
70
|
+
├── types.ts — Public types (MarkdownTheme, Block, …)
|
|
71
|
+
├── theme.ts — Color palettes (THEMES record, private)
|
|
72
|
+
├── block-parser.ts — parseBlocks + line regexes
|
|
73
|
+
├── inline-parser.ts — parseInline + protected-code placeholders
|
|
74
|
+
├── renderer.ts — render (dispatches blocks → ansimax primitives)
|
|
75
|
+
└── index.ts — Re-exports + `markdown` namespace
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
External imports keep working unchanged:
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
import { markdown, parseMarkdownBlocks, parseMarkdownInline, renderMarkdown }
|
|
82
|
+
from 'ansimax';
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Submodule imports now also work (advanced use):
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
import { parseBlocks } from 'ansimax/markdown/block-parser'; // tree-shake friendly
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Improved — Tests
|
|
92
|
+
|
|
93
|
+
- `+18` tests for `colSpan` (defaults, clamping, wrapping, invalid input)
|
|
94
|
+
- `+4` tests for `cellHeight` (pad, truncate, null, zero clamp)
|
|
95
|
+
- `+5` tests for `flow` (row, column, non-multiples, fallback with colSpan)
|
|
96
|
+
- `+1` integration test (colSpan + cellHeight together)
|
|
97
|
+
- `+4` tests verifying submodule imports work after refactor
|
|
98
|
+
|
|
99
|
+
Total: **+32 tests** in `panels.test.ts` and `markdown.test.ts`.
|
|
100
|
+
|
|
101
|
+
### Notes
|
|
102
|
+
|
|
103
|
+
- **Zero behavior changes** for v1.4.0 users — `panels.grid` without the
|
|
104
|
+
new options produces byte-identical output
|
|
105
|
+
- **Zero breaking changes** — `markdown` API surface unchanged
|
|
106
|
+
- Submodule imports enabled (`ansimax/markdown/block-parser`) for
|
|
107
|
+
tree-shaking-friendly bundling
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
6
111
|
## [1.4.0] — Phase 4 closure: Markdown rendering
|
|
7
112
|
|
|
8
113
|
**Minor release** introducing the long-planned `markdown` module — the
|
package/README.es.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
_Colores • Gradientes • Animaciones • ASCII Art • Pixel Art • Árboles • Componentes • Temas_
|
|
8
8
|
|
|
9
9
|
[](LICENSE)
|
|
10
|
-
[](https://www.npmjs.com/package/ansimax)
|
|
11
11
|
[](tsconfig.json)
|
|
12
12
|
[](#testing)
|
|
13
13
|
[](#testing)
|
|
@@ -478,7 +478,7 @@ console.log(components.table([
|
|
|
478
478
|
['loaders', color.green('● listo'), '100%'],
|
|
479
479
|
], { borderStyle: 'rounded' }));
|
|
480
480
|
|
|
481
|
-
console.log(components.badge('VERSION', 'v1.4.
|
|
481
|
+
console.log(components.badge('VERSION', 'v1.4.1'));
|
|
482
482
|
console.log(components.badge('BUILD', 'passing'));
|
|
483
483
|
```
|
|
484
484
|
|
|
@@ -1065,6 +1065,30 @@ ansimax/
|
|
|
1065
1065
|
|
|
1066
1066
|
## 📝 Changelog
|
|
1067
1067
|
|
|
1068
|
+
### v1.4.1 — Grid v2 + refactor markdown
|
|
1069
|
+
|
|
1070
|
+
Release patch. Cero breaking changes:
|
|
1071
|
+
|
|
1072
|
+
- 🎯 **`panels.grid` — colSpan**: span de columnas por bloque (auto-flow estilo CSS Grid)
|
|
1073
|
+
- 📏 **`panels.grid` — cellHeight**: alturas de fila uniformes (complementa `cellWidth`)
|
|
1074
|
+
- 🔀 **`panels.grid` — flow**: dirección de auto-flow `'row'` (default) o `'column'`
|
|
1075
|
+
- 📁 **`markdown` refactorizado** de monolito de 522 líneas → 5 submódulos enfocados (API sin cambios)
|
|
1076
|
+
- 🌳 Imports de submódulo habilitados: `import { parseBlocks } from 'ansimax/markdown/block-parser'`
|
|
1077
|
+
- 🧪 **+32 tests**
|
|
1078
|
+
|
|
1079
|
+
```js
|
|
1080
|
+
import { panels, ascii } from 'ansimax';
|
|
1081
|
+
|
|
1082
|
+
// Header span ambas columnas, luego sidebar + content lado a lado
|
|
1083
|
+
panels.grid([header, sidebar, content], {
|
|
1084
|
+
columns: 2,
|
|
1085
|
+
colSpan: [2, 1, 1],
|
|
1086
|
+
cellHeight: 10, // altura de fila uniforme
|
|
1087
|
+
});
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
Drop-in replacement para `1.4.0`.
|
|
1091
|
+
|
|
1068
1092
|
### v1.4.0 — Cierre de Fase 4: Renderizado Markdown 🎉
|
|
1069
1093
|
|
|
1070
1094
|
**Release minor** completando la Fase 4 con el nuevo módulo `markdown`:
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
_Colors • Gradients • Animations • ASCII Art • Pixel Art • Trees • Components • Themes_
|
|
8
8
|
|
|
9
9
|
[](LICENSE)
|
|
10
|
-
[](https://www.npmjs.com/package/ansimax)
|
|
11
11
|
[](tsconfig.json)
|
|
12
12
|
[](#testing)
|
|
13
13
|
[](#testing)
|
|
@@ -478,7 +478,7 @@ console.log(components.table([
|
|
|
478
478
|
['loaders', color.green('● ready'), '100%'],
|
|
479
479
|
], { borderStyle: 'rounded' }));
|
|
480
480
|
|
|
481
|
-
console.log(components.badge('VERSION', 'v1.4.
|
|
481
|
+
console.log(components.badge('VERSION', 'v1.4.1'));
|
|
482
482
|
console.log(components.badge('BUILD', 'passing'));
|
|
483
483
|
```
|
|
484
484
|
|
|
@@ -1065,6 +1065,30 @@ ansimax/
|
|
|
1065
1065
|
|
|
1066
1066
|
## 📝 Changelog
|
|
1067
1067
|
|
|
1068
|
+
### v1.4.1 — Grid v2 + markdown refactor
|
|
1069
|
+
|
|
1070
|
+
Patch release. Zero breaking changes:
|
|
1071
|
+
|
|
1072
|
+
- 🎯 **`panels.grid` — colSpan**: per-block column span (CSS Grid-style auto-flow)
|
|
1073
|
+
- 📏 **`panels.grid` — cellHeight**: uniform row heights (complements `cellWidth`)
|
|
1074
|
+
- 🔀 **`panels.grid` — flow**: `'row'` (default) or `'column'` auto-flow direction
|
|
1075
|
+
- 📁 **`markdown` refactored** from 522-line monolith → 5 focused submodules (API unchanged)
|
|
1076
|
+
- 🌳 Submodule imports enabled: `import { parseBlocks } from 'ansimax/markdown/block-parser'`
|
|
1077
|
+
- 🧪 **+32 tests**
|
|
1078
|
+
|
|
1079
|
+
```js
|
|
1080
|
+
import { panels, ascii } from 'ansimax';
|
|
1081
|
+
|
|
1082
|
+
// Header spans both columns, then sidebar + content side by side
|
|
1083
|
+
panels.grid([header, sidebar, content], {
|
|
1084
|
+
columns: 2,
|
|
1085
|
+
colSpan: [2, 1, 1],
|
|
1086
|
+
cellHeight: 10, // uniform row height
|
|
1087
|
+
});
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
Drop-in replacement for `1.4.0`.
|
|
1091
|
+
|
|
1068
1092
|
### v1.4.0 — Phase 4 closure: Markdown rendering 🎉
|
|
1069
1093
|
|
|
1070
1094
|
**Minor release** completing Phase 4 with the new `markdown` module:
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,76 @@
|
|
|
1
|
+
/** Visual theme for rendered output. */
|
|
2
|
+
type MarkdownTheme = 'dark' | 'light';
|
|
3
|
+
interface MarkdownOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Maximum width in columns. Long lines wrap. Default: terminal width
|
|
6
|
+
* or 80 if unavailable.
|
|
7
|
+
*/
|
|
8
|
+
width?: number;
|
|
9
|
+
/**
|
|
10
|
+
* Color theme. `'dark'` (default) uses bright colors for dark backgrounds.
|
|
11
|
+
* `'light'` uses dimmer/contrast colors for light backgrounds.
|
|
12
|
+
*/
|
|
13
|
+
theme?: MarkdownTheme;
|
|
14
|
+
/**
|
|
15
|
+
* Override the gradient used for top-level (`# H1`) headings. Receives
|
|
16
|
+
* a list of hex colors. Default uses the dracula palette.
|
|
17
|
+
*/
|
|
18
|
+
headingGradient?: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Render code blocks inside an ASCII box. Default `true`. If `false`,
|
|
21
|
+
* code blocks render as indented dim text.
|
|
22
|
+
*/
|
|
23
|
+
boxCodeBlocks?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Inline code background tint. Default `true`. If `false`, inline code
|
|
26
|
+
* shows only as dim text (cleaner in some terminals).
|
|
27
|
+
*/
|
|
28
|
+
inlineCodeBackground?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Internal options shape passed to `parseInline`. Exposed for advanced
|
|
32
|
+
* use cases that bypass `render` (custom block handlers, etc.).
|
|
33
|
+
*
|
|
34
|
+
* @since 1.4.0
|
|
35
|
+
*/
|
|
36
|
+
interface InlineOptions {
|
|
37
|
+
theme: MarkdownTheme;
|
|
38
|
+
inlineCodeBackground: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Block-level token after parsing the markdown into structural pieces.
|
|
42
|
+
* Tokens contain raw inline text — inline parsing happens at render time.
|
|
43
|
+
*
|
|
44
|
+
* @since 1.4.0
|
|
45
|
+
*/
|
|
46
|
+
type Block = {
|
|
47
|
+
type: 'heading';
|
|
48
|
+
level: number;
|
|
49
|
+
text: string;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'paragraph';
|
|
52
|
+
text: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: 'codeblock';
|
|
55
|
+
lang: string;
|
|
56
|
+
code: string;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'list';
|
|
59
|
+
ordered: boolean;
|
|
60
|
+
items: string[];
|
|
61
|
+
} | {
|
|
62
|
+
type: 'blockquote';
|
|
63
|
+
text: string;
|
|
64
|
+
} | {
|
|
65
|
+
type: 'table';
|
|
66
|
+
headers: string[];
|
|
67
|
+
rows: string[][];
|
|
68
|
+
} | {
|
|
69
|
+
type: 'hr';
|
|
70
|
+
} | {
|
|
71
|
+
type: 'blank';
|
|
72
|
+
};
|
|
73
|
+
|
|
1
74
|
/** Color rendering capability. 'none' suppresses all color output. */
|
|
2
75
|
type ColorMode = 'none' | 'basic' | '256' | 'truecolor' | 'auto';
|
|
3
76
|
/** Animation pacing multiplier preset. */
|
|
@@ -2713,6 +2786,46 @@ interface GridOptions {
|
|
|
2713
2786
|
* use the max width of the widest block in their column.
|
|
2714
2787
|
*/
|
|
2715
2788
|
cellWidth?: number | null;
|
|
2789
|
+
/**
|
|
2790
|
+
* **v1.4.1+** Fix each row to this height (in lines). When the block has
|
|
2791
|
+
* fewer lines, it is padded (using `alignY`). When it has more lines, it
|
|
2792
|
+
* is truncated. If omitted (default), rows take the natural height of
|
|
2793
|
+
* their tallest block.
|
|
2794
|
+
*
|
|
2795
|
+
* @since 1.4.1
|
|
2796
|
+
*/
|
|
2797
|
+
cellHeight?: number | null;
|
|
2798
|
+
/**
|
|
2799
|
+
* **v1.4.1+** Per-block column span. `colSpan[i]` is the number of
|
|
2800
|
+
* columns block `i` occupies. Defaults to `1` for every block when
|
|
2801
|
+
* omitted or shorter than `blocks`.
|
|
2802
|
+
*
|
|
2803
|
+
* The auto-flow algorithm wraps to the next row when the current row's
|
|
2804
|
+
* remaining capacity is less than the next block's span. Spans that
|
|
2805
|
+
* exceed `columns` are clamped to `columns`.
|
|
2806
|
+
*
|
|
2807
|
+
* @example
|
|
2808
|
+
* ```js
|
|
2809
|
+
* // Header spans full width, then 2 cells in a row
|
|
2810
|
+
* panels.grid([header, left, right], {
|
|
2811
|
+
* columns: 2,
|
|
2812
|
+
* colSpan: [2, 1, 1],
|
|
2813
|
+
* });
|
|
2814
|
+
* ```
|
|
2815
|
+
*
|
|
2816
|
+
* @since 1.4.1
|
|
2817
|
+
*/
|
|
2818
|
+
colSpan?: number[];
|
|
2819
|
+
/**
|
|
2820
|
+
* **v1.4.1+** Auto-flow direction. `'row'` (default) fills cells
|
|
2821
|
+
* left-to-right then wraps to the next row — matches CSS Grid's
|
|
2822
|
+
* `grid-auto-flow: row`. `'column'` fills top-to-bottom then wraps to
|
|
2823
|
+
* the next column. Not applicable when `colSpan` is set with any
|
|
2824
|
+
* span > 1 (forces 'row' mode).
|
|
2825
|
+
*
|
|
2826
|
+
* @since 1.4.1
|
|
2827
|
+
*/
|
|
2828
|
+
flow?: 'row' | 'column';
|
|
2716
2829
|
}
|
|
2717
2830
|
/**
|
|
2718
2831
|
* Arrange blocks in a grid of N columns, flowing left-to-right then
|
|
@@ -2887,63 +3000,6 @@ declare const json: {
|
|
|
2887
3000
|
pretty: (value: unknown, opts?: PrettyOptions) => string;
|
|
2888
3001
|
};
|
|
2889
3002
|
|
|
2890
|
-
/** Visual theme for rendered output. */
|
|
2891
|
-
type MarkdownTheme = 'dark' | 'light';
|
|
2892
|
-
interface MarkdownOptions {
|
|
2893
|
-
/**
|
|
2894
|
-
* Maximum width in columns. Long lines wrap. Default: terminal width
|
|
2895
|
-
* or 80 if unavailable.
|
|
2896
|
-
*/
|
|
2897
|
-
width?: number;
|
|
2898
|
-
/**
|
|
2899
|
-
* Color theme. `'dark'` (default) uses bright colors for dark backgrounds.
|
|
2900
|
-
* `'light'` uses dimmer/contrast colors for light backgrounds.
|
|
2901
|
-
*/
|
|
2902
|
-
theme?: MarkdownTheme;
|
|
2903
|
-
/**
|
|
2904
|
-
* Override the gradient used for top-level (`# H1`) headings. Receives
|
|
2905
|
-
* a list of hex colors. Default uses the dracula palette.
|
|
2906
|
-
*/
|
|
2907
|
-
headingGradient?: string[];
|
|
2908
|
-
/**
|
|
2909
|
-
* Render code blocks inside an ASCII box. Default `true`. If `false`,
|
|
2910
|
-
* code blocks render as indented dim text.
|
|
2911
|
-
*/
|
|
2912
|
-
boxCodeBlocks?: boolean;
|
|
2913
|
-
/**
|
|
2914
|
-
* Inline code background tint. Default `true`. If `false`, inline code
|
|
2915
|
-
* shows only as dim text (cleaner in some terminals).
|
|
2916
|
-
*/
|
|
2917
|
-
inlineCodeBackground?: boolean;
|
|
2918
|
-
}
|
|
2919
|
-
/** Block-level token after parsing the markdown into structural pieces. */
|
|
2920
|
-
type Block = {
|
|
2921
|
-
type: 'heading';
|
|
2922
|
-
level: number;
|
|
2923
|
-
text: string;
|
|
2924
|
-
} | {
|
|
2925
|
-
type: 'paragraph';
|
|
2926
|
-
text: string;
|
|
2927
|
-
} | {
|
|
2928
|
-
type: 'codeblock';
|
|
2929
|
-
lang: string;
|
|
2930
|
-
code: string;
|
|
2931
|
-
} | {
|
|
2932
|
-
type: 'list';
|
|
2933
|
-
ordered: boolean;
|
|
2934
|
-
items: string[];
|
|
2935
|
-
} | {
|
|
2936
|
-
type: 'blockquote';
|
|
2937
|
-
text: string;
|
|
2938
|
-
} | {
|
|
2939
|
-
type: 'table';
|
|
2940
|
-
headers: string[];
|
|
2941
|
-
rows: string[][];
|
|
2942
|
-
} | {
|
|
2943
|
-
type: 'hr';
|
|
2944
|
-
} | {
|
|
2945
|
-
type: 'blank';
|
|
2946
|
-
};
|
|
2947
3003
|
/**
|
|
2948
3004
|
* Parse markdown source into a flat sequence of block tokens.
|
|
2949
3005
|
* Tokens contain raw inline text — inline parsing happens at render time.
|
|
@@ -2951,15 +3007,14 @@ type Block = {
|
|
|
2951
3007
|
* @since 1.4.0
|
|
2952
3008
|
*/
|
|
2953
3009
|
declare const parseBlocks: (source: string) => Block[];
|
|
3010
|
+
|
|
2954
3011
|
/**
|
|
2955
3012
|
* Apply inline markdown markup (bold/italic/code/links/etc.) to a string.
|
|
2956
3013
|
*
|
|
2957
3014
|
* @since 1.4.0
|
|
2958
3015
|
*/
|
|
2959
|
-
declare const parseInline: (text: string, opts?:
|
|
2960
|
-
|
|
2961
|
-
inlineCodeBackground: boolean;
|
|
2962
|
-
}) => string;
|
|
3016
|
+
declare const parseInline: (text: string, opts?: InlineOptions) => string;
|
|
3017
|
+
|
|
2963
3018
|
/**
|
|
2964
3019
|
* Render a markdown source string to a terminal-ready string with ANSI
|
|
2965
3020
|
* styling. Handles headings, paragraphs, code blocks, lists, blockquotes,
|
|
@@ -2988,6 +3043,7 @@ declare const parseInline: (text: string, opts?: {
|
|
|
2988
3043
|
* @since 1.4.0
|
|
2989
3044
|
*/
|
|
2990
3045
|
declare const render: (source: string, opts?: MarkdownOptions) => string;
|
|
3046
|
+
|
|
2991
3047
|
/**
|
|
2992
3048
|
* Markdown → terminal renderer. Use `markdown.render(source, opts?)` to
|
|
2993
3049
|
* convert a markdown string to an ANSI-styled string ready for
|
|
@@ -3001,10 +3057,7 @@ declare const render: (source: string, opts?: MarkdownOptions) => string;
|
|
|
3001
3057
|
declare const markdown: {
|
|
3002
3058
|
render: (source: string, opts?: MarkdownOptions) => string;
|
|
3003
3059
|
parseBlocks: (source: string) => Block[];
|
|
3004
|
-
parseInline: (text: string, opts?:
|
|
3005
|
-
theme: MarkdownTheme;
|
|
3006
|
-
inlineCodeBackground: boolean;
|
|
3007
|
-
}) => string;
|
|
3060
|
+
parseInline: (text: string, opts?: InlineOptions) => string;
|
|
3008
3061
|
};
|
|
3009
3062
|
|
|
3010
3063
|
type EasingFunction = (t: number) => number;
|
|
@@ -3220,37 +3273,8 @@ declare const ansimax: {
|
|
|
3220
3273
|
};
|
|
3221
3274
|
markdown: {
|
|
3222
3275
|
render: (source: string, opts?: MarkdownOptions) => string;
|
|
3223
|
-
parseBlocks: (source: string) =>
|
|
3224
|
-
|
|
3225
|
-
level: number;
|
|
3226
|
-
text: string;
|
|
3227
|
-
} | {
|
|
3228
|
-
type: "paragraph";
|
|
3229
|
-
text: string;
|
|
3230
|
-
} | {
|
|
3231
|
-
type: "codeblock";
|
|
3232
|
-
lang: string;
|
|
3233
|
-
code: string;
|
|
3234
|
-
} | {
|
|
3235
|
-
type: "list";
|
|
3236
|
-
ordered: boolean;
|
|
3237
|
-
items: string[];
|
|
3238
|
-
} | {
|
|
3239
|
-
type: "blockquote";
|
|
3240
|
-
text: string;
|
|
3241
|
-
} | {
|
|
3242
|
-
type: "table";
|
|
3243
|
-
headers: string[];
|
|
3244
|
-
rows: string[][];
|
|
3245
|
-
} | {
|
|
3246
|
-
type: "hr";
|
|
3247
|
-
} | {
|
|
3248
|
-
type: "blank";
|
|
3249
|
-
})[];
|
|
3250
|
-
parseInline: (text: string, opts?: {
|
|
3251
|
-
theme: MarkdownTheme;
|
|
3252
|
-
inlineCodeBackground: boolean;
|
|
3253
|
-
}) => string;
|
|
3276
|
+
parseBlocks: (source: string) => Block[];
|
|
3277
|
+
parseInline: (text: string, opts?: InlineOptions) => string;
|
|
3254
3278
|
};
|
|
3255
3279
|
};
|
|
3256
3280
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,76 @@
|
|
|
1
|
+
/** Visual theme for rendered output. */
|
|
2
|
+
type MarkdownTheme = 'dark' | 'light';
|
|
3
|
+
interface MarkdownOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Maximum width in columns. Long lines wrap. Default: terminal width
|
|
6
|
+
* or 80 if unavailable.
|
|
7
|
+
*/
|
|
8
|
+
width?: number;
|
|
9
|
+
/**
|
|
10
|
+
* Color theme. `'dark'` (default) uses bright colors for dark backgrounds.
|
|
11
|
+
* `'light'` uses dimmer/contrast colors for light backgrounds.
|
|
12
|
+
*/
|
|
13
|
+
theme?: MarkdownTheme;
|
|
14
|
+
/**
|
|
15
|
+
* Override the gradient used for top-level (`# H1`) headings. Receives
|
|
16
|
+
* a list of hex colors. Default uses the dracula palette.
|
|
17
|
+
*/
|
|
18
|
+
headingGradient?: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Render code blocks inside an ASCII box. Default `true`. If `false`,
|
|
21
|
+
* code blocks render as indented dim text.
|
|
22
|
+
*/
|
|
23
|
+
boxCodeBlocks?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Inline code background tint. Default `true`. If `false`, inline code
|
|
26
|
+
* shows only as dim text (cleaner in some terminals).
|
|
27
|
+
*/
|
|
28
|
+
inlineCodeBackground?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Internal options shape passed to `parseInline`. Exposed for advanced
|
|
32
|
+
* use cases that bypass `render` (custom block handlers, etc.).
|
|
33
|
+
*
|
|
34
|
+
* @since 1.4.0
|
|
35
|
+
*/
|
|
36
|
+
interface InlineOptions {
|
|
37
|
+
theme: MarkdownTheme;
|
|
38
|
+
inlineCodeBackground: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Block-level token after parsing the markdown into structural pieces.
|
|
42
|
+
* Tokens contain raw inline text — inline parsing happens at render time.
|
|
43
|
+
*
|
|
44
|
+
* @since 1.4.0
|
|
45
|
+
*/
|
|
46
|
+
type Block = {
|
|
47
|
+
type: 'heading';
|
|
48
|
+
level: number;
|
|
49
|
+
text: string;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'paragraph';
|
|
52
|
+
text: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: 'codeblock';
|
|
55
|
+
lang: string;
|
|
56
|
+
code: string;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'list';
|
|
59
|
+
ordered: boolean;
|
|
60
|
+
items: string[];
|
|
61
|
+
} | {
|
|
62
|
+
type: 'blockquote';
|
|
63
|
+
text: string;
|
|
64
|
+
} | {
|
|
65
|
+
type: 'table';
|
|
66
|
+
headers: string[];
|
|
67
|
+
rows: string[][];
|
|
68
|
+
} | {
|
|
69
|
+
type: 'hr';
|
|
70
|
+
} | {
|
|
71
|
+
type: 'blank';
|
|
72
|
+
};
|
|
73
|
+
|
|
1
74
|
/** Color rendering capability. 'none' suppresses all color output. */
|
|
2
75
|
type ColorMode = 'none' | 'basic' | '256' | 'truecolor' | 'auto';
|
|
3
76
|
/** Animation pacing multiplier preset. */
|
|
@@ -2713,6 +2786,46 @@ interface GridOptions {
|
|
|
2713
2786
|
* use the max width of the widest block in their column.
|
|
2714
2787
|
*/
|
|
2715
2788
|
cellWidth?: number | null;
|
|
2789
|
+
/**
|
|
2790
|
+
* **v1.4.1+** Fix each row to this height (in lines). When the block has
|
|
2791
|
+
* fewer lines, it is padded (using `alignY`). When it has more lines, it
|
|
2792
|
+
* is truncated. If omitted (default), rows take the natural height of
|
|
2793
|
+
* their tallest block.
|
|
2794
|
+
*
|
|
2795
|
+
* @since 1.4.1
|
|
2796
|
+
*/
|
|
2797
|
+
cellHeight?: number | null;
|
|
2798
|
+
/**
|
|
2799
|
+
* **v1.4.1+** Per-block column span. `colSpan[i]` is the number of
|
|
2800
|
+
* columns block `i` occupies. Defaults to `1` for every block when
|
|
2801
|
+
* omitted or shorter than `blocks`.
|
|
2802
|
+
*
|
|
2803
|
+
* The auto-flow algorithm wraps to the next row when the current row's
|
|
2804
|
+
* remaining capacity is less than the next block's span. Spans that
|
|
2805
|
+
* exceed `columns` are clamped to `columns`.
|
|
2806
|
+
*
|
|
2807
|
+
* @example
|
|
2808
|
+
* ```js
|
|
2809
|
+
* // Header spans full width, then 2 cells in a row
|
|
2810
|
+
* panels.grid([header, left, right], {
|
|
2811
|
+
* columns: 2,
|
|
2812
|
+
* colSpan: [2, 1, 1],
|
|
2813
|
+
* });
|
|
2814
|
+
* ```
|
|
2815
|
+
*
|
|
2816
|
+
* @since 1.4.1
|
|
2817
|
+
*/
|
|
2818
|
+
colSpan?: number[];
|
|
2819
|
+
/**
|
|
2820
|
+
* **v1.4.1+** Auto-flow direction. `'row'` (default) fills cells
|
|
2821
|
+
* left-to-right then wraps to the next row — matches CSS Grid's
|
|
2822
|
+
* `grid-auto-flow: row`. `'column'` fills top-to-bottom then wraps to
|
|
2823
|
+
* the next column. Not applicable when `colSpan` is set with any
|
|
2824
|
+
* span > 1 (forces 'row' mode).
|
|
2825
|
+
*
|
|
2826
|
+
* @since 1.4.1
|
|
2827
|
+
*/
|
|
2828
|
+
flow?: 'row' | 'column';
|
|
2716
2829
|
}
|
|
2717
2830
|
/**
|
|
2718
2831
|
* Arrange blocks in a grid of N columns, flowing left-to-right then
|
|
@@ -2887,63 +3000,6 @@ declare const json: {
|
|
|
2887
3000
|
pretty: (value: unknown, opts?: PrettyOptions) => string;
|
|
2888
3001
|
};
|
|
2889
3002
|
|
|
2890
|
-
/** Visual theme for rendered output. */
|
|
2891
|
-
type MarkdownTheme = 'dark' | 'light';
|
|
2892
|
-
interface MarkdownOptions {
|
|
2893
|
-
/**
|
|
2894
|
-
* Maximum width in columns. Long lines wrap. Default: terminal width
|
|
2895
|
-
* or 80 if unavailable.
|
|
2896
|
-
*/
|
|
2897
|
-
width?: number;
|
|
2898
|
-
/**
|
|
2899
|
-
* Color theme. `'dark'` (default) uses bright colors for dark backgrounds.
|
|
2900
|
-
* `'light'` uses dimmer/contrast colors for light backgrounds.
|
|
2901
|
-
*/
|
|
2902
|
-
theme?: MarkdownTheme;
|
|
2903
|
-
/**
|
|
2904
|
-
* Override the gradient used for top-level (`# H1`) headings. Receives
|
|
2905
|
-
* a list of hex colors. Default uses the dracula palette.
|
|
2906
|
-
*/
|
|
2907
|
-
headingGradient?: string[];
|
|
2908
|
-
/**
|
|
2909
|
-
* Render code blocks inside an ASCII box. Default `true`. If `false`,
|
|
2910
|
-
* code blocks render as indented dim text.
|
|
2911
|
-
*/
|
|
2912
|
-
boxCodeBlocks?: boolean;
|
|
2913
|
-
/**
|
|
2914
|
-
* Inline code background tint. Default `true`. If `false`, inline code
|
|
2915
|
-
* shows only as dim text (cleaner in some terminals).
|
|
2916
|
-
*/
|
|
2917
|
-
inlineCodeBackground?: boolean;
|
|
2918
|
-
}
|
|
2919
|
-
/** Block-level token after parsing the markdown into structural pieces. */
|
|
2920
|
-
type Block = {
|
|
2921
|
-
type: 'heading';
|
|
2922
|
-
level: number;
|
|
2923
|
-
text: string;
|
|
2924
|
-
} | {
|
|
2925
|
-
type: 'paragraph';
|
|
2926
|
-
text: string;
|
|
2927
|
-
} | {
|
|
2928
|
-
type: 'codeblock';
|
|
2929
|
-
lang: string;
|
|
2930
|
-
code: string;
|
|
2931
|
-
} | {
|
|
2932
|
-
type: 'list';
|
|
2933
|
-
ordered: boolean;
|
|
2934
|
-
items: string[];
|
|
2935
|
-
} | {
|
|
2936
|
-
type: 'blockquote';
|
|
2937
|
-
text: string;
|
|
2938
|
-
} | {
|
|
2939
|
-
type: 'table';
|
|
2940
|
-
headers: string[];
|
|
2941
|
-
rows: string[][];
|
|
2942
|
-
} | {
|
|
2943
|
-
type: 'hr';
|
|
2944
|
-
} | {
|
|
2945
|
-
type: 'blank';
|
|
2946
|
-
};
|
|
2947
3003
|
/**
|
|
2948
3004
|
* Parse markdown source into a flat sequence of block tokens.
|
|
2949
3005
|
* Tokens contain raw inline text — inline parsing happens at render time.
|
|
@@ -2951,15 +3007,14 @@ type Block = {
|
|
|
2951
3007
|
* @since 1.4.0
|
|
2952
3008
|
*/
|
|
2953
3009
|
declare const parseBlocks: (source: string) => Block[];
|
|
3010
|
+
|
|
2954
3011
|
/**
|
|
2955
3012
|
* Apply inline markdown markup (bold/italic/code/links/etc.) to a string.
|
|
2956
3013
|
*
|
|
2957
3014
|
* @since 1.4.0
|
|
2958
3015
|
*/
|
|
2959
|
-
declare const parseInline: (text: string, opts?:
|
|
2960
|
-
|
|
2961
|
-
inlineCodeBackground: boolean;
|
|
2962
|
-
}) => string;
|
|
3016
|
+
declare const parseInline: (text: string, opts?: InlineOptions) => string;
|
|
3017
|
+
|
|
2963
3018
|
/**
|
|
2964
3019
|
* Render a markdown source string to a terminal-ready string with ANSI
|
|
2965
3020
|
* styling. Handles headings, paragraphs, code blocks, lists, blockquotes,
|
|
@@ -2988,6 +3043,7 @@ declare const parseInline: (text: string, opts?: {
|
|
|
2988
3043
|
* @since 1.4.0
|
|
2989
3044
|
*/
|
|
2990
3045
|
declare const render: (source: string, opts?: MarkdownOptions) => string;
|
|
3046
|
+
|
|
2991
3047
|
/**
|
|
2992
3048
|
* Markdown → terminal renderer. Use `markdown.render(source, opts?)` to
|
|
2993
3049
|
* convert a markdown string to an ANSI-styled string ready for
|
|
@@ -3001,10 +3057,7 @@ declare const render: (source: string, opts?: MarkdownOptions) => string;
|
|
|
3001
3057
|
declare const markdown: {
|
|
3002
3058
|
render: (source: string, opts?: MarkdownOptions) => string;
|
|
3003
3059
|
parseBlocks: (source: string) => Block[];
|
|
3004
|
-
parseInline: (text: string, opts?:
|
|
3005
|
-
theme: MarkdownTheme;
|
|
3006
|
-
inlineCodeBackground: boolean;
|
|
3007
|
-
}) => string;
|
|
3060
|
+
parseInline: (text: string, opts?: InlineOptions) => string;
|
|
3008
3061
|
};
|
|
3009
3062
|
|
|
3010
3063
|
type EasingFunction = (t: number) => number;
|
|
@@ -3220,37 +3273,8 @@ declare const ansimax: {
|
|
|
3220
3273
|
};
|
|
3221
3274
|
markdown: {
|
|
3222
3275
|
render: (source: string, opts?: MarkdownOptions) => string;
|
|
3223
|
-
parseBlocks: (source: string) =>
|
|
3224
|
-
|
|
3225
|
-
level: number;
|
|
3226
|
-
text: string;
|
|
3227
|
-
} | {
|
|
3228
|
-
type: "paragraph";
|
|
3229
|
-
text: string;
|
|
3230
|
-
} | {
|
|
3231
|
-
type: "codeblock";
|
|
3232
|
-
lang: string;
|
|
3233
|
-
code: string;
|
|
3234
|
-
} | {
|
|
3235
|
-
type: "list";
|
|
3236
|
-
ordered: boolean;
|
|
3237
|
-
items: string[];
|
|
3238
|
-
} | {
|
|
3239
|
-
type: "blockquote";
|
|
3240
|
-
text: string;
|
|
3241
|
-
} | {
|
|
3242
|
-
type: "table";
|
|
3243
|
-
headers: string[];
|
|
3244
|
-
rows: string[][];
|
|
3245
|
-
} | {
|
|
3246
|
-
type: "hr";
|
|
3247
|
-
} | {
|
|
3248
|
-
type: "blank";
|
|
3249
|
-
})[];
|
|
3250
|
-
parseInline: (text: string, opts?: {
|
|
3251
|
-
theme: MarkdownTheme;
|
|
3252
|
-
inlineCodeBackground: boolean;
|
|
3253
|
-
}) => string;
|
|
3276
|
+
parseBlocks: (source: string) => Block[];
|
|
3277
|
+
parseInline: (text: string, opts?: InlineOptions) => string;
|
|
3254
3278
|
};
|
|
3255
3279
|
};
|
|
3256
3280
|
|
package/dist/index.js
CHANGED
|
@@ -6158,37 +6158,105 @@ var grid = (blocks, opts) => {
|
|
|
6158
6158
|
const alignX = opts.alignX ?? "start";
|
|
6159
6159
|
const alignY = opts.alignY ?? "start";
|
|
6160
6160
|
const cellW = opts.cellWidth != null ? Math.max(0, Math.floor(opts.cellWidth)) : null;
|
|
6161
|
-
const
|
|
6162
|
-
|
|
6163
|
-
|
|
6161
|
+
const cellH = opts.cellHeight != null ? Math.max(1, Math.floor(opts.cellHeight)) : null;
|
|
6162
|
+
const flow = opts.flow === "column" ? "column" : "row";
|
|
6163
|
+
const spans = blocks.map((_, i) => {
|
|
6164
|
+
const raw = opts.colSpan?.[i];
|
|
6165
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 1) return 1;
|
|
6166
|
+
return Math.min(columns2, Math.floor(raw));
|
|
6167
|
+
});
|
|
6168
|
+
const hasSpans = spans.some((s) => s > 1);
|
|
6169
|
+
const cellRows = [];
|
|
6170
|
+
if (flow === "column" && !hasSpans) {
|
|
6171
|
+
const rowCount = Math.ceil(blocks.length / columns2);
|
|
6172
|
+
for (let r = 0; r < rowCount; r++) cellRows.push([]);
|
|
6173
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
6174
|
+
const c = Math.floor(i / rowCount);
|
|
6175
|
+
const r = i % rowCount;
|
|
6176
|
+
cellRows[r].push({ block: blocks[i], span: 1, col: c });
|
|
6177
|
+
}
|
|
6178
|
+
} else {
|
|
6179
|
+
let row = [];
|
|
6180
|
+
let colInRow = 0;
|
|
6181
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
6182
|
+
const span = spans[i];
|
|
6183
|
+
if (colInRow + span > columns2 && row.length > 0) {
|
|
6184
|
+
cellRows.push(row);
|
|
6185
|
+
row = [];
|
|
6186
|
+
colInRow = 0;
|
|
6187
|
+
}
|
|
6188
|
+
row.push({ block: blocks[i], span, col: colInRow });
|
|
6189
|
+
colInRow += span;
|
|
6190
|
+
}
|
|
6191
|
+
if (row.length > 0) cellRows.push(row);
|
|
6164
6192
|
}
|
|
6165
|
-
let widths
|
|
6193
|
+
let widths;
|
|
6166
6194
|
if (cellW != null) {
|
|
6167
6195
|
widths = Array(columns2).fill(cellW);
|
|
6168
6196
|
} else {
|
|
6169
6197
|
widths = Array(columns2).fill(0);
|
|
6170
|
-
for (const
|
|
6171
|
-
for (
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
widths[
|
|
6198
|
+
for (const r of cellRows) {
|
|
6199
|
+
for (const cell of r) {
|
|
6200
|
+
if (cell.span === 1) {
|
|
6201
|
+
const { maxWidth } = _splitBlock(cell.block);
|
|
6202
|
+
if (maxWidth > widths[cell.col]) {
|
|
6203
|
+
widths[cell.col] = maxWidth;
|
|
6204
|
+
}
|
|
6175
6205
|
}
|
|
6176
6206
|
}
|
|
6177
6207
|
}
|
|
6178
|
-
}
|
|
6179
|
-
const renderedRows = rows.map((row) => {
|
|
6180
|
-
const padded = [];
|
|
6181
6208
|
for (let c = 0; c < columns2; c++) {
|
|
6182
|
-
|
|
6209
|
+
if (widths[c] === 0) {
|
|
6210
|
+
for (const r of cellRows) {
|
|
6211
|
+
for (const cell of r) {
|
|
6212
|
+
if (cell.col <= c && cell.col + cell.span > c) {
|
|
6213
|
+
const { maxWidth } = _splitBlock(cell.block);
|
|
6214
|
+
const each = Math.ceil(maxWidth / cell.span);
|
|
6215
|
+
if (each > widths[c]) widths[c] = each;
|
|
6216
|
+
}
|
|
6217
|
+
}
|
|
6218
|
+
}
|
|
6219
|
+
}
|
|
6183
6220
|
}
|
|
6184
|
-
|
|
6221
|
+
}
|
|
6222
|
+
const renderedRows = cellRows.map((row) => {
|
|
6223
|
+
const mergedBlocks = [];
|
|
6224
|
+
const mergedWidths = [];
|
|
6225
|
+
let nextCol = 0;
|
|
6226
|
+
for (const cell of row) {
|
|
6227
|
+
let w = 0;
|
|
6228
|
+
for (let k = 0; k < cell.span; k++) {
|
|
6229
|
+
w += widths[cell.col + k];
|
|
6230
|
+
}
|
|
6231
|
+
w += Math.max(0, cell.span - 1) * gapX;
|
|
6232
|
+
let blockToRender = cell.block;
|
|
6233
|
+
if (cellH != null) {
|
|
6234
|
+
blockToRender = _fitHeight(cell.block, cellH);
|
|
6235
|
+
}
|
|
6236
|
+
mergedBlocks.push(blockToRender);
|
|
6237
|
+
mergedWidths.push(w);
|
|
6238
|
+
nextCol += cell.span;
|
|
6239
|
+
}
|
|
6240
|
+
while (nextCol < columns2) {
|
|
6241
|
+
mergedBlocks.push("");
|
|
6242
|
+
mergedWidths.push(widths[nextCol]);
|
|
6243
|
+
nextCol++;
|
|
6244
|
+
}
|
|
6245
|
+
return vsplit(mergedBlocks, {
|
|
6185
6246
|
gap: gapX,
|
|
6186
6247
|
align: alignY,
|
|
6187
|
-
widths
|
|
6248
|
+
widths: mergedWidths
|
|
6188
6249
|
});
|
|
6189
6250
|
});
|
|
6190
6251
|
return hsplit(renderedRows, { gap: gapY, align: alignX });
|
|
6191
6252
|
};
|
|
6253
|
+
var _fitHeight = (block, targetH) => {
|
|
6254
|
+
const lines = block.split("\n");
|
|
6255
|
+
if (lines.length === targetH) return block;
|
|
6256
|
+
if (lines.length > targetH) return lines.slice(0, targetH).join("\n");
|
|
6257
|
+
const pad = Array(targetH - lines.length).fill("");
|
|
6258
|
+
return [...lines, ...pad].join("\n");
|
|
6259
|
+
};
|
|
6192
6260
|
var panels = {
|
|
6193
6261
|
vsplit,
|
|
6194
6262
|
hsplit,
|
|
@@ -6346,8 +6414,8 @@ var _renderValue = (value, depth, config) => {
|
|
|
6346
6414
|
inlineItems.push(_c(`... (${remaining} more)`, COLORS.comment, useColor));
|
|
6347
6415
|
}
|
|
6348
6416
|
const candidate = _c("[", COLORS.bracket, useColor) + inlineItems.join(", ") + _c("]", COLORS.bracket, useColor);
|
|
6349
|
-
const
|
|
6350
|
-
if (
|
|
6417
|
+
const visibleLen2 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
6418
|
+
if (visibleLen2 <= inlineArrayMaxLength) {
|
|
6351
6419
|
return candidate;
|
|
6352
6420
|
}
|
|
6353
6421
|
}
|
|
@@ -6426,38 +6494,7 @@ var json = {
|
|
|
6426
6494
|
pretty
|
|
6427
6495
|
};
|
|
6428
6496
|
|
|
6429
|
-
// src/markdown/
|
|
6430
|
-
var THEMES = {
|
|
6431
|
-
dark: {
|
|
6432
|
-
h1: ["#ff79c6", "#bd93f9", "#8be9fd"],
|
|
6433
|
-
h2: "#bd93f9",
|
|
6434
|
-
h3: "#8be9fd",
|
|
6435
|
-
h4: "#50fa7b",
|
|
6436
|
-
h5: "#f1fa8c",
|
|
6437
|
-
h6: "#ffb86c",
|
|
6438
|
-
code: "#ff79c6",
|
|
6439
|
-
codeBlockBorder: "#6272a4",
|
|
6440
|
-
link: "#8be9fd",
|
|
6441
|
-
blockquote: "#6272a4",
|
|
6442
|
-
hr: "#6272a4",
|
|
6443
|
-
tableHeader: "#bd93f9"
|
|
6444
|
-
},
|
|
6445
|
-
light: {
|
|
6446
|
-
h1: ["#d63384", "#6f42c1", "#0d6efd"],
|
|
6447
|
-
h2: "#6f42c1",
|
|
6448
|
-
h3: "#0d6efd",
|
|
6449
|
-
h4: "#198754",
|
|
6450
|
-
h5: "#664d03",
|
|
6451
|
-
h6: "#fd7e14",
|
|
6452
|
-
code: "#d63384",
|
|
6453
|
-
codeBlockBorder: "#adb5bd",
|
|
6454
|
-
link: "#0d6efd",
|
|
6455
|
-
blockquote: "#6c757d",
|
|
6456
|
-
hr: "#adb5bd",
|
|
6457
|
-
tableHeader: "#6f42c1"
|
|
6458
|
-
}
|
|
6459
|
-
};
|
|
6460
|
-
var _normalize = (text) => typeof text === "string" ? text.replace(/\r\n/g, "\n").replace(/\r/g, "\n") : "";
|
|
6497
|
+
// src/markdown/block-parser.ts
|
|
6461
6498
|
var HEADING_RE = /^(#{1,6})\s+(.+?)\s*#*\s*$/;
|
|
6462
6499
|
var ORDERED_LIST_RE = /^(\s*)(\d+)[.)]\s+(.+)$/;
|
|
6463
6500
|
var UNORDERED_LIST_RE = /^(\s*)[-*+]\s+(.+)$/;
|
|
@@ -6467,6 +6504,11 @@ var CODEBLOCK_CLOSE_RE = /^```\s*$/;
|
|
|
6467
6504
|
var BLOCKQUOTE_RE = /^>\s?(.*)$/;
|
|
6468
6505
|
var TABLE_SEPARATOR_RE = /^\|?[ \t]*:?-{2,}:?[ \t]*(\|[ \t]*:?-{2,}:?[ \t]*)+\|?[ \t]*$/;
|
|
6469
6506
|
var TABLE_ROW_RE = /^\|.*\|[ \t]*$/;
|
|
6507
|
+
var _normalize = (text) => typeof text === "string" ? text.replace(/\r\n/g, "\n").replace(/\r/g, "\n") : "";
|
|
6508
|
+
var _splitTableRow = (row) => {
|
|
6509
|
+
const stripped = row.trim().replace(/^\|/, "").replace(/\|[ \t]*$/, "");
|
|
6510
|
+
return stripped.split("|").map((c) => c.trim());
|
|
6511
|
+
};
|
|
6470
6512
|
var parseBlocks = (source) => {
|
|
6471
6513
|
if (typeof source !== "string" || source.length === 0) return [];
|
|
6472
6514
|
const lines = _normalize(source).split("\n");
|
|
@@ -6562,14 +6604,41 @@ var parseBlocks = (source) => {
|
|
|
6562
6604
|
}
|
|
6563
6605
|
return out;
|
|
6564
6606
|
};
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6607
|
+
|
|
6608
|
+
// src/markdown/theme.ts
|
|
6609
|
+
var THEMES = {
|
|
6610
|
+
dark: {
|
|
6611
|
+
h1: ["#ff79c6", "#bd93f9", "#8be9fd"],
|
|
6612
|
+
h2: "#bd93f9",
|
|
6613
|
+
h3: "#8be9fd",
|
|
6614
|
+
h4: "#50fa7b",
|
|
6615
|
+
h5: "#f1fa8c",
|
|
6616
|
+
h6: "#ffb86c",
|
|
6617
|
+
code: "#ff79c6",
|
|
6618
|
+
codeBlockBorder: "#6272a4",
|
|
6619
|
+
link: "#8be9fd",
|
|
6620
|
+
blockquote: "#6272a4",
|
|
6621
|
+
hr: "#6272a4",
|
|
6622
|
+
tableHeader: "#bd93f9"
|
|
6623
|
+
},
|
|
6624
|
+
light: {
|
|
6625
|
+
h1: ["#d63384", "#6f42c1", "#0d6efd"],
|
|
6626
|
+
h2: "#6f42c1",
|
|
6627
|
+
h3: "#0d6efd",
|
|
6628
|
+
h4: "#198754",
|
|
6629
|
+
h5: "#664d03",
|
|
6630
|
+
h6: "#fd7e14",
|
|
6631
|
+
code: "#d63384",
|
|
6632
|
+
codeBlockBorder: "#adb5bd",
|
|
6633
|
+
link: "#0d6efd",
|
|
6634
|
+
blockquote: "#6c757d",
|
|
6635
|
+
hr: "#adb5bd",
|
|
6636
|
+
tableHeader: "#6f42c1"
|
|
6637
|
+
}
|
|
6568
6638
|
};
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
}) => {
|
|
6639
|
+
|
|
6640
|
+
// src/markdown/inline-parser.ts
|
|
6641
|
+
var parseInline = (text, opts = { theme: "dark", inlineCodeBackground: true }) => {
|
|
6573
6642
|
if (typeof text !== "string" || text.length === 0) return "";
|
|
6574
6643
|
const t = THEMES[opts.theme];
|
|
6575
6644
|
const codeSlots = [];
|
|
@@ -6589,6 +6658,8 @@ var parseInline = (text, opts = {
|
|
|
6589
6658
|
s = s.replace(/\x00CODE(\d+)\x00/g, (_m, idx) => codeSlots[Number(idx)] ?? "");
|
|
6590
6659
|
return s;
|
|
6591
6660
|
};
|
|
6661
|
+
|
|
6662
|
+
// src/markdown/renderer.ts
|
|
6592
6663
|
var _detectWidth = () => {
|
|
6593
6664
|
const w = process.stdout?.columns;
|
|
6594
6665
|
return isFiniteNumber2(w) && w > 10 ? w : 80;
|
|
@@ -6683,6 +6754,8 @@ var render = (source, opts = {}) => {
|
|
|
6683
6754
|
while (out.length > 0 && out[out.length - 1] === "") out.pop();
|
|
6684
6755
|
return out.join("\n");
|
|
6685
6756
|
};
|
|
6757
|
+
|
|
6758
|
+
// src/markdown/index.ts
|
|
6686
6759
|
var markdown = {
|
|
6687
6760
|
render,
|
|
6688
6761
|
parseBlocks,
|
package/dist/index.mjs
CHANGED
|
@@ -5946,37 +5946,105 @@ var grid = (blocks, opts) => {
|
|
|
5946
5946
|
const alignX = opts.alignX ?? "start";
|
|
5947
5947
|
const alignY = opts.alignY ?? "start";
|
|
5948
5948
|
const cellW = opts.cellWidth != null ? Math.max(0, Math.floor(opts.cellWidth)) : null;
|
|
5949
|
-
const
|
|
5950
|
-
|
|
5951
|
-
|
|
5949
|
+
const cellH = opts.cellHeight != null ? Math.max(1, Math.floor(opts.cellHeight)) : null;
|
|
5950
|
+
const flow = opts.flow === "column" ? "column" : "row";
|
|
5951
|
+
const spans = blocks.map((_, i) => {
|
|
5952
|
+
const raw = opts.colSpan?.[i];
|
|
5953
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 1) return 1;
|
|
5954
|
+
return Math.min(columns2, Math.floor(raw));
|
|
5955
|
+
});
|
|
5956
|
+
const hasSpans = spans.some((s) => s > 1);
|
|
5957
|
+
const cellRows = [];
|
|
5958
|
+
if (flow === "column" && !hasSpans) {
|
|
5959
|
+
const rowCount = Math.ceil(blocks.length / columns2);
|
|
5960
|
+
for (let r = 0; r < rowCount; r++) cellRows.push([]);
|
|
5961
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
5962
|
+
const c = Math.floor(i / rowCount);
|
|
5963
|
+
const r = i % rowCount;
|
|
5964
|
+
cellRows[r].push({ block: blocks[i], span: 1, col: c });
|
|
5965
|
+
}
|
|
5966
|
+
} else {
|
|
5967
|
+
let row = [];
|
|
5968
|
+
let colInRow = 0;
|
|
5969
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
5970
|
+
const span = spans[i];
|
|
5971
|
+
if (colInRow + span > columns2 && row.length > 0) {
|
|
5972
|
+
cellRows.push(row);
|
|
5973
|
+
row = [];
|
|
5974
|
+
colInRow = 0;
|
|
5975
|
+
}
|
|
5976
|
+
row.push({ block: blocks[i], span, col: colInRow });
|
|
5977
|
+
colInRow += span;
|
|
5978
|
+
}
|
|
5979
|
+
if (row.length > 0) cellRows.push(row);
|
|
5952
5980
|
}
|
|
5953
|
-
let widths
|
|
5981
|
+
let widths;
|
|
5954
5982
|
if (cellW != null) {
|
|
5955
5983
|
widths = Array(columns2).fill(cellW);
|
|
5956
5984
|
} else {
|
|
5957
5985
|
widths = Array(columns2).fill(0);
|
|
5958
|
-
for (const
|
|
5959
|
-
for (
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
widths[
|
|
5986
|
+
for (const r of cellRows) {
|
|
5987
|
+
for (const cell of r) {
|
|
5988
|
+
if (cell.span === 1) {
|
|
5989
|
+
const { maxWidth } = _splitBlock(cell.block);
|
|
5990
|
+
if (maxWidth > widths[cell.col]) {
|
|
5991
|
+
widths[cell.col] = maxWidth;
|
|
5992
|
+
}
|
|
5963
5993
|
}
|
|
5964
5994
|
}
|
|
5965
5995
|
}
|
|
5966
|
-
}
|
|
5967
|
-
const renderedRows = rows.map((row) => {
|
|
5968
|
-
const padded = [];
|
|
5969
5996
|
for (let c = 0; c < columns2; c++) {
|
|
5970
|
-
|
|
5997
|
+
if (widths[c] === 0) {
|
|
5998
|
+
for (const r of cellRows) {
|
|
5999
|
+
for (const cell of r) {
|
|
6000
|
+
if (cell.col <= c && cell.col + cell.span > c) {
|
|
6001
|
+
const { maxWidth } = _splitBlock(cell.block);
|
|
6002
|
+
const each = Math.ceil(maxWidth / cell.span);
|
|
6003
|
+
if (each > widths[c]) widths[c] = each;
|
|
6004
|
+
}
|
|
6005
|
+
}
|
|
6006
|
+
}
|
|
6007
|
+
}
|
|
5971
6008
|
}
|
|
5972
|
-
|
|
6009
|
+
}
|
|
6010
|
+
const renderedRows = cellRows.map((row) => {
|
|
6011
|
+
const mergedBlocks = [];
|
|
6012
|
+
const mergedWidths = [];
|
|
6013
|
+
let nextCol = 0;
|
|
6014
|
+
for (const cell of row) {
|
|
6015
|
+
let w = 0;
|
|
6016
|
+
for (let k = 0; k < cell.span; k++) {
|
|
6017
|
+
w += widths[cell.col + k];
|
|
6018
|
+
}
|
|
6019
|
+
w += Math.max(0, cell.span - 1) * gapX;
|
|
6020
|
+
let blockToRender = cell.block;
|
|
6021
|
+
if (cellH != null) {
|
|
6022
|
+
blockToRender = _fitHeight(cell.block, cellH);
|
|
6023
|
+
}
|
|
6024
|
+
mergedBlocks.push(blockToRender);
|
|
6025
|
+
mergedWidths.push(w);
|
|
6026
|
+
nextCol += cell.span;
|
|
6027
|
+
}
|
|
6028
|
+
while (nextCol < columns2) {
|
|
6029
|
+
mergedBlocks.push("");
|
|
6030
|
+
mergedWidths.push(widths[nextCol]);
|
|
6031
|
+
nextCol++;
|
|
6032
|
+
}
|
|
6033
|
+
return vsplit(mergedBlocks, {
|
|
5973
6034
|
gap: gapX,
|
|
5974
6035
|
align: alignY,
|
|
5975
|
-
widths
|
|
6036
|
+
widths: mergedWidths
|
|
5976
6037
|
});
|
|
5977
6038
|
});
|
|
5978
6039
|
return hsplit(renderedRows, { gap: gapY, align: alignX });
|
|
5979
6040
|
};
|
|
6041
|
+
var _fitHeight = (block, targetH) => {
|
|
6042
|
+
const lines = block.split("\n");
|
|
6043
|
+
if (lines.length === targetH) return block;
|
|
6044
|
+
if (lines.length > targetH) return lines.slice(0, targetH).join("\n");
|
|
6045
|
+
const pad = Array(targetH - lines.length).fill("");
|
|
6046
|
+
return [...lines, ...pad].join("\n");
|
|
6047
|
+
};
|
|
5980
6048
|
var panels = {
|
|
5981
6049
|
vsplit,
|
|
5982
6050
|
hsplit,
|
|
@@ -6134,8 +6202,8 @@ var _renderValue = (value, depth, config) => {
|
|
|
6134
6202
|
inlineItems.push(_c(`... (${remaining} more)`, COLORS.comment, useColor));
|
|
6135
6203
|
}
|
|
6136
6204
|
const candidate = _c("[", COLORS.bracket, useColor) + inlineItems.join(", ") + _c("]", COLORS.bracket, useColor);
|
|
6137
|
-
const
|
|
6138
|
-
if (
|
|
6205
|
+
const visibleLen2 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
6206
|
+
if (visibleLen2 <= inlineArrayMaxLength) {
|
|
6139
6207
|
return candidate;
|
|
6140
6208
|
}
|
|
6141
6209
|
}
|
|
@@ -6214,38 +6282,7 @@ var json = {
|
|
|
6214
6282
|
pretty
|
|
6215
6283
|
};
|
|
6216
6284
|
|
|
6217
|
-
// src/markdown/
|
|
6218
|
-
var THEMES = {
|
|
6219
|
-
dark: {
|
|
6220
|
-
h1: ["#ff79c6", "#bd93f9", "#8be9fd"],
|
|
6221
|
-
h2: "#bd93f9",
|
|
6222
|
-
h3: "#8be9fd",
|
|
6223
|
-
h4: "#50fa7b",
|
|
6224
|
-
h5: "#f1fa8c",
|
|
6225
|
-
h6: "#ffb86c",
|
|
6226
|
-
code: "#ff79c6",
|
|
6227
|
-
codeBlockBorder: "#6272a4",
|
|
6228
|
-
link: "#8be9fd",
|
|
6229
|
-
blockquote: "#6272a4",
|
|
6230
|
-
hr: "#6272a4",
|
|
6231
|
-
tableHeader: "#bd93f9"
|
|
6232
|
-
},
|
|
6233
|
-
light: {
|
|
6234
|
-
h1: ["#d63384", "#6f42c1", "#0d6efd"],
|
|
6235
|
-
h2: "#6f42c1",
|
|
6236
|
-
h3: "#0d6efd",
|
|
6237
|
-
h4: "#198754",
|
|
6238
|
-
h5: "#664d03",
|
|
6239
|
-
h6: "#fd7e14",
|
|
6240
|
-
code: "#d63384",
|
|
6241
|
-
codeBlockBorder: "#adb5bd",
|
|
6242
|
-
link: "#0d6efd",
|
|
6243
|
-
blockquote: "#6c757d",
|
|
6244
|
-
hr: "#adb5bd",
|
|
6245
|
-
tableHeader: "#6f42c1"
|
|
6246
|
-
}
|
|
6247
|
-
};
|
|
6248
|
-
var _normalize = (text) => typeof text === "string" ? text.replace(/\r\n/g, "\n").replace(/\r/g, "\n") : "";
|
|
6285
|
+
// src/markdown/block-parser.ts
|
|
6249
6286
|
var HEADING_RE = /^(#{1,6})\s+(.+?)\s*#*\s*$/;
|
|
6250
6287
|
var ORDERED_LIST_RE = /^(\s*)(\d+)[.)]\s+(.+)$/;
|
|
6251
6288
|
var UNORDERED_LIST_RE = /^(\s*)[-*+]\s+(.+)$/;
|
|
@@ -6255,6 +6292,11 @@ var CODEBLOCK_CLOSE_RE = /^```\s*$/;
|
|
|
6255
6292
|
var BLOCKQUOTE_RE = /^>\s?(.*)$/;
|
|
6256
6293
|
var TABLE_SEPARATOR_RE = /^\|?[ \t]*:?-{2,}:?[ \t]*(\|[ \t]*:?-{2,}:?[ \t]*)+\|?[ \t]*$/;
|
|
6257
6294
|
var TABLE_ROW_RE = /^\|.*\|[ \t]*$/;
|
|
6295
|
+
var _normalize = (text) => typeof text === "string" ? text.replace(/\r\n/g, "\n").replace(/\r/g, "\n") : "";
|
|
6296
|
+
var _splitTableRow = (row) => {
|
|
6297
|
+
const stripped = row.trim().replace(/^\|/, "").replace(/\|[ \t]*$/, "");
|
|
6298
|
+
return stripped.split("|").map((c) => c.trim());
|
|
6299
|
+
};
|
|
6258
6300
|
var parseBlocks = (source) => {
|
|
6259
6301
|
if (typeof source !== "string" || source.length === 0) return [];
|
|
6260
6302
|
const lines = _normalize(source).split("\n");
|
|
@@ -6350,14 +6392,41 @@ var parseBlocks = (source) => {
|
|
|
6350
6392
|
}
|
|
6351
6393
|
return out;
|
|
6352
6394
|
};
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6395
|
+
|
|
6396
|
+
// src/markdown/theme.ts
|
|
6397
|
+
var THEMES = {
|
|
6398
|
+
dark: {
|
|
6399
|
+
h1: ["#ff79c6", "#bd93f9", "#8be9fd"],
|
|
6400
|
+
h2: "#bd93f9",
|
|
6401
|
+
h3: "#8be9fd",
|
|
6402
|
+
h4: "#50fa7b",
|
|
6403
|
+
h5: "#f1fa8c",
|
|
6404
|
+
h6: "#ffb86c",
|
|
6405
|
+
code: "#ff79c6",
|
|
6406
|
+
codeBlockBorder: "#6272a4",
|
|
6407
|
+
link: "#8be9fd",
|
|
6408
|
+
blockquote: "#6272a4",
|
|
6409
|
+
hr: "#6272a4",
|
|
6410
|
+
tableHeader: "#bd93f9"
|
|
6411
|
+
},
|
|
6412
|
+
light: {
|
|
6413
|
+
h1: ["#d63384", "#6f42c1", "#0d6efd"],
|
|
6414
|
+
h2: "#6f42c1",
|
|
6415
|
+
h3: "#0d6efd",
|
|
6416
|
+
h4: "#198754",
|
|
6417
|
+
h5: "#664d03",
|
|
6418
|
+
h6: "#fd7e14",
|
|
6419
|
+
code: "#d63384",
|
|
6420
|
+
codeBlockBorder: "#adb5bd",
|
|
6421
|
+
link: "#0d6efd",
|
|
6422
|
+
blockquote: "#6c757d",
|
|
6423
|
+
hr: "#adb5bd",
|
|
6424
|
+
tableHeader: "#6f42c1"
|
|
6425
|
+
}
|
|
6356
6426
|
};
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
}) => {
|
|
6427
|
+
|
|
6428
|
+
// src/markdown/inline-parser.ts
|
|
6429
|
+
var parseInline = (text, opts = { theme: "dark", inlineCodeBackground: true }) => {
|
|
6361
6430
|
if (typeof text !== "string" || text.length === 0) return "";
|
|
6362
6431
|
const t = THEMES[opts.theme];
|
|
6363
6432
|
const codeSlots = [];
|
|
@@ -6377,6 +6446,8 @@ var parseInline = (text, opts = {
|
|
|
6377
6446
|
s = s.replace(/\x00CODE(\d+)\x00/g, (_m, idx) => codeSlots[Number(idx)] ?? "");
|
|
6378
6447
|
return s;
|
|
6379
6448
|
};
|
|
6449
|
+
|
|
6450
|
+
// src/markdown/renderer.ts
|
|
6380
6451
|
var _detectWidth = () => {
|
|
6381
6452
|
const w = process.stdout?.columns;
|
|
6382
6453
|
return isFiniteNumber2(w) && w > 10 ? w : 80;
|
|
@@ -6471,6 +6542,8 @@ var render = (source, opts = {}) => {
|
|
|
6471
6542
|
while (out.length > 0 && out[out.length - 1] === "") out.pop();
|
|
6472
6543
|
return out.join("\n");
|
|
6473
6544
|
};
|
|
6545
|
+
|
|
6546
|
+
// src/markdown/index.ts
|
|
6474
6547
|
var markdown = {
|
|
6475
6548
|
render,
|
|
6476
6549
|
parseBlocks,
|
package/examples/all-in-one.cjs
CHANGED
|
@@ -118,7 +118,7 @@ async function main() {
|
|
|
118
118
|
console.log(components.section('🏷️ Badges & Status', { width: 60 }));
|
|
119
119
|
console.log();
|
|
120
120
|
console.log(' ',
|
|
121
|
-
components.badge('VERSION', 'v1.4.
|
|
121
|
+
components.badge('VERSION', 'v1.4.1'),
|
|
122
122
|
components.badge('BUILD', 'passing'),
|
|
123
123
|
components.badge('LICENSE', 'Apache 2.0'));
|
|
124
124
|
console.log();
|
package/examples/all-in-one.mjs
CHANGED
|
@@ -117,7 +117,7 @@ console.log();
|
|
|
117
117
|
console.log(components.section('🏷️ Badges & Status', { width: 60 }));
|
|
118
118
|
console.log();
|
|
119
119
|
console.log(' ',
|
|
120
|
-
components.badge('VERSION', 'v1.4.
|
|
120
|
+
components.badge('VERSION', 'v1.4.1'),
|
|
121
121
|
components.badge('BUILD', 'passing'),
|
|
122
122
|
components.badge('LICENSE', 'Apache 2.0'));
|
|
123
123
|
console.log();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ansimax",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Zero-dependency CLI rendering library: colors, gradients, animations, ASCII art, pixel art, components, and themes \u2014 all in TypeScript.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|