@vincemakes/kiso-tui-cells 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/md.d.ts ADDED
@@ -0,0 +1,137 @@
1
+ /**
2
+ * TUI2-MD — the markdown renderer. Hand-rolled, zero dependencies, and
3
+ * deliberately a SUBSET: the constructs assistant prose actually uses,
4
+ * rendered under the mono discipline (attributes over colours, zero
5
+ * syntax highlighting).
6
+ *
7
+ * THE BLOCK-FREEZE DISCIPLINE. kiso's committed bytes are never
8
+ * re-emitted (ADR-0046) — the terminal's own scrollback is the
9
+ * transcript. A renderer that re-lexes the whole message per delta (the
10
+ * shape a whole-text parser forces on you) can therefore not be used
11
+ * here at all: it would need to repaint lines that have already left
12
+ * the live region. So the scanner below IS the streaming state machine.
13
+ * It consumes appended text and yields two things:
14
+ *
15
+ * - CLOSED blocks: their source is final, so their render is final;
16
+ * the compositor commits them through the path it already had.
17
+ * - the OPEN TAIL block: the live region's occupant, re-rendered in
18
+ * place per delta, bounded by construction (one block).
19
+ *
20
+ * The freeze property — a closed block's rendered lines never change as
21
+ * more text arrives — is earned by ONE rule: block boundaries are
22
+ * decided only on COMPLETE lines. A trailing partial line renders
23
+ * eagerly but can never close anything, because a decision taken on an
24
+ * incomplete line can be wrong ("#" is a heading until it becomes
25
+ * "#hashtag") and a wrong decision here is a wrong commit.
26
+ *
27
+ * Everything else follows: an unclosed `**` renders literal and flips
28
+ * when it closes, but only ever inside the open block; a fence body
29
+ * line is line-local (no highlighting means no cross-line lexer state),
30
+ * so it closes the instant its newline arrives and long code blocks
31
+ * never bloat the live region; a table re-layouts as rows stream, and
32
+ * only inside the tail.
33
+ *
34
+ * The style table is the round's normative one (the owner's circled
35
+ * group D): the BLOCK half is `blockBody` below, the INLINE half is
36
+ * `inlineSpans`, and every entry is pinned by a fixture rather than
37
+ * described twice.
38
+ */
39
+ /** The block kinds. `fence-open`/`fence-line` are separate kinds on
40
+ * purpose: a fence's rows must be able to freeze ONE AT A TIME. */
41
+ export type MdKind = "para" | "heading" | "list" | "table" | "quote" | "rule" | "fence-open" | "fence-line";
42
+ /** One block: its SOURCE lines, never a rendered form. The render is a
43
+ * pure function of (block, width), which is what makes the freeze
44
+ * property a property of the scanner alone. */
45
+ export interface MdBlock {
46
+ readonly kind: MdKind;
47
+ readonly lines: readonly string[];
48
+ /** a blank row precedes this block — the markdown rhythm, owned here
49
+ * rather than by the compositor's W11 join formula (which reads row
50
+ * COUNTS and so cannot express "no blank between two rows of one
51
+ * fence"). */
52
+ readonly gap: boolean;
53
+ /** the fence's language tag; "" everywhere else. */
54
+ readonly lang: string;
55
+ }
56
+ export declare class MdStream {
57
+ #private;
58
+ /** Append streamed text. Only COMPLETE lines reach the state machine. */
59
+ push(text: string): void;
60
+ /** The message ended: the trailing partial line is a complete line
61
+ * after all, and the open block closes. */
62
+ end(): void;
63
+ /** Every block so far: `closed()` of them are FINAL, and at most one
64
+ * open tail follows. Fresh objects — a closed block's source can
65
+ * never be reached through this. */
66
+ blocks(): readonly MdBlock[];
67
+ /** How many leading blocks are CLOSED — the commit-eligible count. */
68
+ closed(): number;
69
+ }
70
+ /** The whole message at once — the freeze property's oracle, and the
71
+ * path a non-streaming caller takes. */
72
+ export declare function renderMarkdown(text: string, W: number): string[];
73
+ /** One block's screen rows. Pure in (block, W) — this is the whole
74
+ * freeze guarantee: same source, same width, same bytes, forever. */
75
+ export declare function renderBlock(b: MdBlock, W: number): string[];
76
+ /**
77
+ * The inline pass — the mono style table applied to one block's text.
78
+ *
79
+ * Scoped to `**bold**`, `*italic*`, `` `code` ``, `[text](url)` and the
80
+ * backslash escape, with two rules that matter more than coverage:
81
+ *
82
+ * RAW UNTIL CLOSED — an opener with no closer in this text stays
83
+ * literal. That is what lets a half-streamed `**` show its asterisks
84
+ * and flip the instant the closer lands, inside the live block and
85
+ * nowhere else.
86
+ *
87
+ * CLOSE BACK TO `base` — the block's own style (a heading's bold, a
88
+ * quote's dim) is passed in, and every span reopens it on the way
89
+ * out, so a nested span can never strand it. Italic is the one span
90
+ * that closes surgically (SGR 23), because it can.
91
+ *
92
+ * Documented deviations from CommonMark: `_` never emphasizes (it is a
93
+ * character in identifiers far more often than a marker in prose);
94
+ * emphasis does not nest across a code span; `~~` is not a construct at
95
+ * all — the markers are content (the strict tokenizer both reference
96
+ * implementations converged on, taken to its honest conclusion, since
97
+ * SGR 9's terminal support is too fragmented to promise).
98
+ */
99
+ export declare function inlineSpans(text: string, base: string): string;
100
+ /** Split a table line into cells. The `|` walls are found on the RAW
101
+ * line, but a pipe INSIDE a code span is content — two independent
102
+ * reference implementations both patched exactly this, because a
103
+ * command in a cell (`grep a | wc`) is common and splitting it puts
104
+ * the human's own text in the wrong column. A backslash-escaped pipe
105
+ * is content too. */
106
+ export declare function splitCells(line: string): string[];
107
+ export type MdAlign = "left" | "center" | "right";
108
+ export interface MdTable {
109
+ readonly header: readonly string[];
110
+ readonly align: readonly MdAlign[];
111
+ readonly rows: readonly (readonly string[])[];
112
+ }
113
+ /** The table shape, or null when these lines are NOT a table.
114
+ *
115
+ * Two rejections, both borrowed: a second line that is not a delimiter
116
+ * row means this is prose that contains pipes; and a body row carrying
117
+ * MORE columns than the header is malformed — rendering it would have
118
+ * to guess where the extra content belongs, and a guess printed into
119
+ * scrollback is indistinguishable from a fact. Rejected tables fall
120
+ * back to their own source bytes, which are still valid markdown. */
121
+ export declare function tableShape(lines: readonly string[]): MdTable | null;
122
+ /**
123
+ * Wrap styled text into rows of at most W columns, with a HANGING
124
+ * INDENT: `first` prefixes the first row, `hang` every later one, and
125
+ * the text column is what continuations align to.
126
+ *
127
+ * The SGR spans open at a break are closed at the row's end and
128
+ * reopened at the next row's start, so no style leaks into the padding
129
+ * and none is lost across the break. Italic's own close (23) is
130
+ * understood, so `\x1b[3m…\x1b[23m` inside a bold heading tracks
131
+ * correctly.
132
+ *
133
+ * Every emitted row measures ≤ W through the SAME width authority the
134
+ * compositor's invariant ① measures with — which is the only way the
135
+ * two can agree.
136
+ */
137
+ export declare function mdWrap(text: string, W: number, first: string, hang: string): string[];