@tooee/renderers 0.1.12 → 0.1.14

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.
@@ -1,3 +1,4 @@
1
+ import { type Token } from "marked";
1
2
  import { type ReactNode, type RefObject } from "react";
2
3
  import type { MarkState } from "@tooee/marks";
3
4
  import type { RowDocumentRenderable } from "./RowDocumentRenderable.js";
@@ -9,6 +10,18 @@ interface MarkdownViewProps {
9
10
  marks?: MarkState;
10
11
  docRef?: RefObject<RowDocumentRenderable | null>;
11
12
  }
13
+ /**
14
+ * A flattened block — all blocks exist at the top level with an indent.
15
+ * Nested structures (lists containing code blocks, etc.) are flattened
16
+ * into sibling blocks with appropriate indentation.
17
+ */
18
+ export interface FlatBlock {
19
+ token: Token;
20
+ indent: number;
21
+ bullet?: string;
22
+ checked?: boolean;
23
+ }
24
+ export declare function flattenTokens(tokens: Token[]): FlatBlock[];
12
25
  export declare function MarkdownView({ content, showLineNumbers, marks, docRef }: MarkdownViewProps): ReactNode;
13
26
  export {};
14
27
  //# sourceMappingURL=MarkdownView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownView.d.ts","sourceRoot":"","sources":["../src/MarkdownView.tsx"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAI/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAEvE,OAAO,mBAAmB,CAAA;AAC1B,OAAO,iBAAiB,CAAA;AAExB,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAA;CACjD;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,eAAsB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,iBAAiB,aAsBjG"}
1
+ {"version":3,"file":"MarkdownView.d.ts","sourceRoot":"","sources":["../src/MarkdownView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,KAAK,EAAe,MAAM,QAAQ,CAAA;AACxD,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAc/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAEvE,OAAO,mBAAmB,CAAA;AAC1B,OAAO,iBAAiB,CAAA;AAMxB,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAA;CACjD;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAMD,wBAAgB,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,EAAE,CAI1D;AA0FD,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,eAAsB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,iBAAiB,aAsBjG"}
@@ -2,36 +2,131 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@opentui/reac
2
2
  import { marked } from "marked";
3
3
  import { useMemo } from "react";
4
4
  import { useTheme } from "@tooee/themes";
5
- import { bold as boldChunk } from "@opentui/core";
5
+ import { bold as boldChunk, italic as italicChunk, underline as underlineChunk, parseColor, } from "@opentui/core";
6
6
  import { useGutterPalette } from "./useGutterPalette.js";
7
7
  import "./row-document.js";
8
8
  import "./text-table.js";
9
+ // ---------------------------------------------------------------------------
10
+ // Token flattening
11
+ // ---------------------------------------------------------------------------
12
+ export function flattenTokens(tokens) {
13
+ const result = [];
14
+ flattenTokenList(tokens, 0, result);
15
+ return result;
16
+ }
17
+ function flattenTokenList(tokens, indent, result) {
18
+ for (const token of tokens) {
19
+ if (token.type === "space")
20
+ continue;
21
+ if (token.type === "list") {
22
+ const list = token;
23
+ for (let i = 0; i < list.items.length; i++) {
24
+ const item = list.items[i];
25
+ const bullet = list.ordered ? `${i + (list.start || 1)}. ` : "- ";
26
+ flattenListItem(item, indent, bullet, result);
27
+ }
28
+ }
29
+ else {
30
+ result.push({ token, indent });
31
+ }
32
+ }
33
+ }
34
+ function flattenListItem(item, indent, bullet, result) {
35
+ const checked = item.checked != null ? item.checked : undefined;
36
+ const childTokens = item.tokens || [];
37
+ let bulletUsed = false;
38
+ for (const token of childTokens) {
39
+ if (token.type === "space" || token.type === "checkbox")
40
+ continue;
41
+ if (token.type === "text" || token.type === "paragraph") {
42
+ // Inline content — attach the bullet to the first one
43
+ result.push({
44
+ token,
45
+ indent,
46
+ bullet: bulletUsed ? undefined : bullet,
47
+ checked: bulletUsed ? undefined : checked,
48
+ });
49
+ bulletUsed = true;
50
+ }
51
+ else if (token.type === "list") {
52
+ // Emit bullet line if nothing preceded this nested list
53
+ if (!bulletUsed) {
54
+ result.push({
55
+ token: { type: "text", raw: "", text: "", tokens: [] },
56
+ indent,
57
+ bullet,
58
+ checked,
59
+ });
60
+ bulletUsed = true;
61
+ }
62
+ // Nested list — increase indent to align with content after bullet
63
+ const list = token;
64
+ for (let i = 0; i < list.items.length; i++) {
65
+ const subItem = list.items[i];
66
+ const subBullet = list.ordered ? `${i + (list.start || 1)}. ` : "- ";
67
+ flattenListItem(subItem, indent + bullet.length, subBullet, result);
68
+ }
69
+ }
70
+ else {
71
+ // Block content (code, table, blockquote, hr, etc.)
72
+ if (!bulletUsed) {
73
+ result.push({
74
+ token: { type: "text", raw: "", text: "", tokens: [] },
75
+ indent,
76
+ bullet,
77
+ checked,
78
+ });
79
+ bulletUsed = true;
80
+ }
81
+ // Emit the block indented to align with content after the bullet
82
+ result.push({ token, indent: indent + bullet.length });
83
+ }
84
+ }
85
+ // List item had no content tokens — still emit the bullet
86
+ if (!bulletUsed) {
87
+ result.push({
88
+ token: { type: "text", raw: "", text: "", tokens: [] },
89
+ indent,
90
+ bullet,
91
+ checked,
92
+ });
93
+ }
94
+ }
95
+ // ---------------------------------------------------------------------------
96
+ // Component
97
+ // ---------------------------------------------------------------------------
9
98
  export function MarkdownView({ content, showLineNumbers = true, marks, docRef }) {
10
99
  const { theme, syntax } = useTheme();
11
100
  const palette = useGutterPalette();
12
101
  const tokens = marked.lexer(content);
13
- const blocks = tokens.filter((t) => t.type !== "space");
14
- const blockElements = blocks.map((token, index) => (_jsx(TokenRenderer, { token: token, theme: theme, syntax: syntax }, index)));
102
+ const blocks = flattenTokens(tokens);
103
+ const blockElements = blocks.map((block, index) => (_jsx(FlatBlockRenderer, { block: block, theme: theme, syntax: syntax }, index)));
15
104
  return (_jsx("row-document", { ref: docRef, showLineNumbers: showLineNumbers, palette: palette, decorations: marks?.sets, signColumnWidth: 1, style: { flexGrow: 1 }, children: blockElements }));
16
105
  }
17
- function TokenRenderer({ token, theme, syntax, }) {
106
+ // ---------------------------------------------------------------------------
107
+ // Block renderer (flat)
108
+ // ---------------------------------------------------------------------------
109
+ function FlatBlockRenderer({ block, theme, syntax, }) {
110
+ const { token, indent, bullet } = block;
111
+ // List item line (has bullet)
112
+ if (bullet !== undefined) {
113
+ return _jsx(ListLineRenderer, { block: block, theme: theme });
114
+ }
115
+ // Regular block token
18
116
  switch (token.type) {
19
117
  case "heading":
20
- return _jsx(HeadingRenderer, { token: token, theme: theme });
118
+ return _jsx(HeadingRenderer, { token: token, theme: theme, indent: indent });
21
119
  case "paragraph":
22
- return _jsx(ParagraphRenderer, { token: token, theme: theme });
120
+ return _jsx(ParagraphRenderer, { token: token, theme: theme, indent: indent });
23
121
  case "code":
24
- return _jsx(CodeBlockRenderer, { token: token, theme: theme, syntax: syntax });
122
+ return (_jsx(CodeBlockRenderer, { token: token, theme: theme, syntax: syntax, indent: indent }));
25
123
  case "blockquote":
26
- return _jsx(BlockquoteRenderer, { token: token, theme: theme });
27
- case "list":
28
- return _jsx(ListRenderer, { token: token, theme: theme });
124
+ return (_jsx(BlockquoteRenderer, { token: token, theme: theme, indent: indent }));
29
125
  case "table":
30
- return _jsx(MarkdownTableRenderer, { token: token });
126
+ return _jsx(MarkdownTableRenderer, { token: token, indent: indent });
31
127
  case "hr":
32
- return _jsx(HorizontalRule, { theme: theme });
128
+ return _jsx(HorizontalRule, { theme: theme, indent: indent });
33
129
  case "space":
34
- return null;
35
130
  case "html":
36
131
  return null;
37
132
  default:
@@ -40,14 +135,30 @@ function TokenRenderer({ token, theme, syntax, }) {
40
135
  fg: theme.markdownText,
41
136
  marginBottom: 1,
42
137
  marginTop: 0,
43
- marginLeft: 1,
138
+ marginLeft: 1 + indent,
44
139
  marginRight: 1,
45
140
  } }));
46
141
  }
47
142
  return null;
48
143
  }
49
144
  }
50
- function HeadingRenderer({ token, theme }) {
145
+ // ---------------------------------------------------------------------------
146
+ // List line renderer
147
+ // ---------------------------------------------------------------------------
148
+ function ListLineRenderer({ block, theme }) {
149
+ const { token, indent, bullet, checked } = block;
150
+ const checkboxPrefix = checked !== undefined ? (checked ? "[x] " : "[ ] ") : "";
151
+ // Get inline tokens from the text/paragraph token
152
+ const inlineTokens = "tokens" in token && Array.isArray(token.tokens) ? token.tokens : [];
153
+ const hasText = "text" in token && typeof token.text === "string" && token.text.length > 0;
154
+ const hasContent = inlineTokens.length > 0 || hasText;
155
+ return (_jsx("box", { style: { marginLeft: 1 + indent, marginRight: 1 }, children: _jsxs("text", { style: { fg: theme.markdownText }, children: [_jsx("span", { fg: theme.markdownListItem, children: bullet }), checkboxPrefix !== "" && (_jsx("span", { fg: checked ? theme.accent : theme.textMuted, children: checkboxPrefix })), hasContent &&
156
+ (inlineTokens.length > 0 ? (_jsx(InlineTokens, { tokens: inlineTokens, theme: theme })) : hasText ? (("text" in token ? token.text : "")) : null)] }) }));
157
+ }
158
+ // ---------------------------------------------------------------------------
159
+ // Block renderers
160
+ // ---------------------------------------------------------------------------
161
+ function HeadingRenderer({ token, theme, indent, }) {
51
162
  const headingColors = {
52
163
  1: theme.markdownHeading,
53
164
  2: theme.secondary,
@@ -64,18 +175,17 @@ function HeadingRenderer({ token, theme }) {
64
175
  5: "##### ",
65
176
  6: "###### ",
66
177
  };
67
- const headingText = getPlainText(token.tokens || []);
68
- return (_jsx("box", { style: { marginTop: 1, marginBottom: 1 }, children: _jsxs("text", { style: { fg: headingColors[token.depth] || theme.text }, children: [_jsx("span", { fg: theme.textMuted, children: prefixes[token.depth] }), _jsx("strong", { children: headingText })] }) }));
178
+ return (_jsx("box", { style: { marginTop: 1, marginBottom: 1, marginLeft: indent }, children: _jsxs("text", { style: { fg: headingColors[token.depth] || theme.text }, children: [_jsx("span", { fg: theme.textMuted, children: prefixes[token.depth] }), _jsx("strong", { children: _jsx(InlineTokens, { tokens: token.tokens || [], theme: theme }) })] }) }));
69
179
  }
70
- function ParagraphRenderer({ token, theme }) {
71
- return (_jsx("box", { style: { marginBottom: 1, marginLeft: 1, marginRight: 1 }, children: _jsx("text", { style: { fg: theme.markdownText }, children: _jsx(InlineTokens, { tokens: token.tokens || [], theme: theme }) }) }));
180
+ function ParagraphRenderer({ token, theme, indent, }) {
181
+ return (_jsx("box", { style: { marginBottom: 1, marginLeft: 1 + indent, marginRight: 1 }, children: _jsx("text", { style: { fg: theme.markdownText }, children: _jsx(InlineTokens, { tokens: token.tokens || [], theme: theme }) }) }));
72
182
  }
73
- function CodeBlockRenderer({ token, theme, syntax, }) {
183
+ function CodeBlockRenderer({ token, theme, syntax, indent, }) {
74
184
  const lineCount = token.text.split("\n").length;
75
185
  return (_jsx("box", { style: {
76
186
  marginTop: 0,
77
187
  marginBottom: 1,
78
- marginLeft: 1,
188
+ marginLeft: 1 + indent,
79
189
  marginRight: 1,
80
190
  border: true,
81
191
  borderColor: theme.border,
@@ -83,69 +193,56 @@ function CodeBlockRenderer({ token, theme, syntax, }) {
83
193
  flexDirection: "column",
84
194
  }, children: _jsx("code", { content: token.text, filetype: token.lang, syntaxStyle: syntax, style: { height: lineCount } }) }));
85
195
  }
86
- function BlockquoteRenderer({ token, theme }) {
87
- const quoteText = token.tokens
88
- ? token.tokens
89
- .map((t) => {
90
- const innerTokens = "tokens" in t ? t.tokens : undefined;
91
- const textContent = "text" in t ? t.text : "";
92
- return getPlainText(innerTokens || []) || textContent || "";
93
- })
94
- .join("\n")
95
- : "";
96
- return (_jsxs("box", { style: { marginTop: 0, marginBottom: 1, marginLeft: 1, marginRight: 1, paddingLeft: 2 }, children: [_jsx("text", { style: { fg: theme.markdownBlockQuote }, content: "\u2502 " }), _jsx("text", { style: { fg: theme.textMuted }, content: quoteText })] }));
97
- }
98
- function ListRenderer({ token, theme }) {
99
- return (_jsx("box", { style: { marginBottom: 1, marginLeft: 3, marginRight: 1, flexDirection: "column" }, children: token.items.map((item, index) => (_jsx(ListItemRenderer, { item: item, ordered: token.ordered, index: index + (token.start || 1), theme: theme }, index))) }));
100
- }
101
- function ListItemRenderer({ item, ordered, index, theme, }) {
102
- const bullet = ordered ? `${index}. ` : "- ";
103
- const itemContent = item.tokens || [];
104
- return (_jsxs("box", { style: { flexDirection: "row" }, children: [_jsx("text", { style: { fg: theme.markdownListItem }, content: bullet }), _jsx("box", { style: { flexShrink: 1, flexDirection: "column" }, children: itemContent.map((token, idx) => {
105
- if (token.type === "text" && "tokens" in token && token.tokens) {
106
- return (_jsx("text", { style: { fg: theme.markdownText }, children: _jsx(InlineTokens, { tokens: token.tokens, theme: theme }) }, idx));
107
- }
108
- if (token.type === "paragraph" && token.tokens) {
109
- return (_jsx("text", { style: { fg: theme.markdownText }, children: _jsx(InlineTokens, { tokens: token.tokens, theme: theme }) }, idx));
110
- }
111
- if (token.type === "list") {
112
- return _jsx(ListRenderer, { token: token, theme: theme }, idx);
113
- }
114
- if ("text" in token && typeof token.text === "string") {
115
- return _jsx("text", { style: { fg: theme.markdownText }, content: token.text }, idx);
116
- }
117
- return null;
118
- }) })] }));
196
+ function BlockquoteRenderer({ token, theme, indent, }) {
197
+ // Collect inline tokens from blockquote's child paragraphs/text
198
+ const inlineTokens = [];
199
+ if (token.tokens) {
200
+ for (const child of token.tokens) {
201
+ if ("tokens" in child && Array.isArray(child.tokens)) {
202
+ if (inlineTokens.length > 0) {
203
+ inlineTokens.push({ type: "text", raw: "\n", text: "\n" });
204
+ }
205
+ inlineTokens.push(...child.tokens);
206
+ }
207
+ else if ("text" in child && typeof child.text === "string") {
208
+ inlineTokens.push(child);
209
+ }
210
+ }
211
+ }
212
+ return (_jsxs("box", { style: {
213
+ marginTop: 0,
214
+ marginBottom: 1,
215
+ marginLeft: 1 + indent,
216
+ marginRight: 1,
217
+ paddingLeft: 2,
218
+ }, children: [_jsx("text", { style: { fg: theme.markdownBlockQuote }, content: "\u2502 " }), _jsx("text", { style: { fg: theme.textMuted }, children: _jsx(InlineTokens, { tokens: inlineTokens, theme: theme }) })] }));
119
219
  }
120
- function MarkdownTableRenderer({ token }) {
220
+ function MarkdownTableRenderer({ token, indent }) {
121
221
  const { theme } = useTheme();
122
222
  const content = useMemo(() => {
123
- const headerRow = token.header.map((cell) => [
124
- boldChunk(getPlainText(cell.tokens).trim()),
125
- ]);
126
- const dataRows = token.rows.map((row) => row.map((cell) => [{ __isChunk: true, text: getPlainText(cell.tokens) }]));
223
+ const headerRow = token.header.map((cell) => {
224
+ const chunks = inlineTokensToChunks(cell.tokens, theme);
225
+ // Wrap header chunks in bold
226
+ return chunks.length > 0
227
+ ? chunks.map((c) => boldChunk(c))
228
+ : [boldChunk(getPlainText(cell.tokens).trim())];
229
+ });
230
+ const dataRows = token.rows.map((row) => row.map((cell) => {
231
+ const chunks = inlineTokensToChunks(cell.tokens, theme);
232
+ return chunks.length > 0
233
+ ? chunks
234
+ : [{ __isChunk: true, text: getPlainText(cell.tokens) }];
235
+ }));
127
236
  return [headerRow, ...dataRows];
128
- }, [token]);
129
- return (_jsx("box", { style: { marginLeft: 1, marginRight: 1, marginBottom: 1 }, children: _jsx("text-table", { content: content, wrapMode: "word", columnWidthMode: "content", cellPadding: 0, border: true, borderStyle: "single", borderColor: theme.border, fg: theme.text }) }));
237
+ }, [token, theme]);
238
+ return (_jsx("box", { style: { marginLeft: 1 + indent, marginRight: 1, marginBottom: 1 }, children: _jsx("text-table", { content: content, wrapMode: "word", columnWidthMode: "content", cellPadding: 0, border: true, borderStyle: "single", borderColor: theme.border, fg: theme.text }) }));
130
239
  }
131
- function HorizontalRule({ theme }) {
132
- return (_jsx("box", { style: { marginTop: 0, marginBottom: 1, marginLeft: 1, marginRight: 1 }, children: _jsx("text", { style: { fg: theme.markdownHorizontalRule }, content: "─".repeat(40) }) }));
133
- }
134
- function getPlainText(tokens) {
135
- return tokens
136
- .map((token) => {
137
- if (token.type === "text")
138
- return token.text;
139
- if (token.type === "codespan")
140
- return token.text;
141
- if ("tokens" in token && token.tokens)
142
- return getPlainText(token.tokens);
143
- if ("text" in token)
144
- return token.text;
145
- return "";
146
- })
147
- .join("");
240
+ function HorizontalRule({ theme, indent }) {
241
+ return (_jsx("box", { style: { marginTop: 0, marginBottom: 1, marginLeft: 1 + indent, marginRight: 1 }, children: _jsx("text", { style: { fg: theme.markdownHorizontalRule }, content: "─".repeat(40) }) }));
148
242
  }
243
+ // ---------------------------------------------------------------------------
244
+ // Inline token rendering (React elements)
245
+ // ---------------------------------------------------------------------------
149
246
  function InlineTokens({ tokens, theme }) {
150
247
  const result = [];
151
248
  for (let i = 0; i < tokens.length; i++) {
@@ -158,17 +255,25 @@ function InlineTokens({ tokens, theme }) {
158
255
  result.push(token.text);
159
256
  break;
160
257
  case "strong":
161
- result.push(_jsx("strong", { children: getPlainText(token.tokens || []) }, key));
258
+ result.push(_jsx("strong", { children: _jsx(InlineTokens, { tokens: token.tokens || [], theme: theme }) }, key));
162
259
  break;
163
260
  case "em":
164
- result.push(_jsx("em", { children: getPlainText(token.tokens || []) }, key));
261
+ result.push(_jsx("em", { children: _jsx(InlineTokens, { tokens: token.tokens || [], theme: theme }) }, key));
165
262
  break;
166
263
  case "codespan":
167
264
  result.push(_jsx("span", { fg: theme.markdownCode, bg: theme.backgroundPanel, children: ` ${token.text} ` }, key));
168
265
  break;
169
266
  case "link": {
170
267
  const linkToken = token;
171
- result.push(_jsx("u", { children: _jsx("a", { href: linkToken.href, fg: theme.markdownLink, children: getPlainText(linkToken.tokens || []) }) }, key));
268
+ result.push(_jsx("u", { children: _jsx("a", { href: linkToken.href, fg: theme.markdownLink, children: _jsx(InlineTokens, { tokens: linkToken.tokens || [], theme: theme }) }) }, key));
269
+ break;
270
+ }
271
+ case "del":
272
+ result.push(_jsxs("span", { fg: theme.textMuted, children: ["~", _jsx(InlineTokens, { tokens: token.tokens || [], theme: theme }), "~"] }, key));
273
+ break;
274
+ case "image": {
275
+ const imgToken = token;
276
+ result.push(_jsx("span", { fg: theme.textMuted, children: imgToken.text || imgToken.href }, key));
172
277
  break;
173
278
  }
174
279
  case "br":
@@ -189,4 +294,69 @@ function InlineTokens({ tokens, theme }) {
189
294
  }
190
295
  return _jsx(_Fragment, { children: result });
191
296
  }
297
+ // ---------------------------------------------------------------------------
298
+ // Inline token rendering (TextChunks — for text-table cells)
299
+ // ---------------------------------------------------------------------------
300
+ function inlineTokensToChunks(tokens, theme) {
301
+ const chunks = [];
302
+ for (const token of tokens) {
303
+ switch (token.type) {
304
+ case "text":
305
+ chunks.push({ __isChunk: true, text: token.text });
306
+ break;
307
+ case "strong":
308
+ for (const sub of inlineTokensToChunks(token.tokens || [], theme)) {
309
+ chunks.push(boldChunk(sub));
310
+ }
311
+ break;
312
+ case "em":
313
+ for (const sub of inlineTokensToChunks(token.tokens || [], theme)) {
314
+ chunks.push(italicChunk(sub));
315
+ }
316
+ break;
317
+ case "codespan":
318
+ chunks.push({
319
+ __isChunk: true,
320
+ text: ` ${token.text} `,
321
+ fg: parseColor(theme.markdownCode),
322
+ bg: parseColor(theme.backgroundPanel),
323
+ });
324
+ break;
325
+ case "link": {
326
+ const linkToken = token;
327
+ for (const sub of inlineTokensToChunks(linkToken.tokens || [], theme)) {
328
+ chunks.push(underlineChunk({ ...sub, fg: parseColor(theme.markdownLink) }));
329
+ }
330
+ break;
331
+ }
332
+ case "escape":
333
+ chunks.push({ __isChunk: true, text: token.text });
334
+ break;
335
+ default:
336
+ if ("text" in token && typeof token.text === "string") {
337
+ chunks.push({ __isChunk: true, text: token.text });
338
+ }
339
+ break;
340
+ }
341
+ }
342
+ return chunks;
343
+ }
344
+ // ---------------------------------------------------------------------------
345
+ // Plain text extraction (only for width computation, not rendering)
346
+ // ---------------------------------------------------------------------------
347
+ function getPlainText(tokens) {
348
+ return tokens
349
+ .map((token) => {
350
+ if (token.type === "text")
351
+ return token.text;
352
+ if (token.type === "codespan")
353
+ return token.text;
354
+ if ("tokens" in token && token.tokens)
355
+ return getPlainText(token.tokens);
356
+ if ("text" in token)
357
+ return token.text;
358
+ return "";
359
+ })
360
+ .join("");
361
+ }
192
362
  //# sourceMappingURL=MarkdownView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownView.js","sourceRoot":"","sources":["../src/MarkdownView.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MarkdownView.js","sourceRoot":"","sources":["../src/MarkdownView.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { MarkdownView } from "./MarkdownView.js";
1
+ export { MarkdownView, flattenTokens } from "./MarkdownView.js";
2
+ export type { FlatBlock } from "./MarkdownView.js";
2
3
  export { CodeView } from "./CodeView.js";
3
4
  export { ImageView } from "./ImageView.js";
4
5
  export { Table, computeColumnWidths, isNumeric, sampleRows } from "./Table.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC9E,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAChE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AACrF,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAA;AAC1E,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,4BAA4B,CAAA;AACnC,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC/D,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC9E,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAChE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AACrF,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAA;AAC1E,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,4BAA4B,CAAA;AACnC,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { MarkdownView } from "./MarkdownView.js";
1
+ export { MarkdownView, flattenTokens } from "./MarkdownView.js";
2
2
  export { CodeView } from "./CodeView.js";
3
3
  export { ImageView } from "./ImageView.js";
4
4
  export { Table, computeColumnWidths, isNumeric, sampleRows } from "./Table.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG9E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAErF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAA;AAM1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAE/D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG9E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAErF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAA;AAM1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tooee/renderers",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "Content renderers (markdown, code, image, table) for Tooee",
5
5
  "keywords": [
6
6
  "cli",
@@ -37,9 +37,9 @@
37
37
  "typecheck": "tsc --noEmit"
38
38
  },
39
39
  "dependencies": {
40
- "@tooee/fuzzy": "0.1.12",
41
- "@tooee/marks": "0.1.12",
42
- "@tooee/themes": "0.1.12",
40
+ "@tooee/fuzzy": "0.1.14",
41
+ "@tooee/marks": "0.1.14",
42
+ "@tooee/themes": "0.1.14",
43
43
  "marked": "^17.0.4"
44
44
  },
45
45
  "devDependencies": {
@@ -1,14 +1,28 @@
1
1
  import { marked, type Token, type Tokens } from "marked"
2
2
  import { useMemo, type ReactNode, type RefObject } from "react"
3
3
  import { useTheme, type ResolvedTheme } from "@tooee/themes"
4
- import { bold as boldChunk } from "@opentui/core"
5
- import type { SyntaxStyle, TextTableContent, TextTableCellContent } from "@opentui/core"
4
+ import {
5
+ bold as boldChunk,
6
+ italic as italicChunk,
7
+ underline as underlineChunk,
8
+ parseColor,
9
+ } from "@opentui/core"
10
+ import type {
11
+ SyntaxStyle,
12
+ TextTableContent,
13
+ TextTableCellContent,
14
+ TextChunk,
15
+ } from "@opentui/core"
6
16
  import type { MarkState } from "@tooee/marks"
7
17
  import type { RowDocumentRenderable } from "./RowDocumentRenderable.js"
8
18
  import { useGutterPalette } from "./useGutterPalette.js"
9
19
  import "./row-document.js"
10
20
  import "./text-table.js"
11
21
 
22
+ // ---------------------------------------------------------------------------
23
+ // Types
24
+ // ---------------------------------------------------------------------------
25
+
12
26
  interface MarkdownViewProps {
13
27
  content: string
14
28
  showLineNumbers?: boolean
@@ -16,14 +30,124 @@ interface MarkdownViewProps {
16
30
  docRef?: RefObject<RowDocumentRenderable | null>
17
31
  }
18
32
 
33
+ /**
34
+ * A flattened block — all blocks exist at the top level with an indent.
35
+ * Nested structures (lists containing code blocks, etc.) are flattened
36
+ * into sibling blocks with appropriate indentation.
37
+ */
38
+ export interface FlatBlock {
39
+ token: Token
40
+ indent: number
41
+ bullet?: string // "- " or "1. " for list item lines
42
+ checked?: boolean // undefined = not a checkbox, true/false = checkbox state
43
+ }
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Token flattening
47
+ // ---------------------------------------------------------------------------
48
+
49
+ export function flattenTokens(tokens: Token[]): FlatBlock[] {
50
+ const result: FlatBlock[] = []
51
+ flattenTokenList(tokens, 0, result)
52
+ return result
53
+ }
54
+
55
+ function flattenTokenList(tokens: Token[], indent: number, result: FlatBlock[]): void {
56
+ for (const token of tokens) {
57
+ if (token.type === "space") continue
58
+
59
+ if (token.type === "list") {
60
+ const list = token as Tokens.List
61
+ for (let i = 0; i < list.items.length; i++) {
62
+ const item = list.items[i]
63
+ const bullet = list.ordered ? `${i + (list.start || 1)}. ` : "- "
64
+ flattenListItem(item, indent, bullet, result)
65
+ }
66
+ } else {
67
+ result.push({ token, indent })
68
+ }
69
+ }
70
+ }
71
+
72
+ function flattenListItem(
73
+ item: Tokens.ListItem,
74
+ indent: number,
75
+ bullet: string,
76
+ result: FlatBlock[],
77
+ ): void {
78
+ const checked = item.checked != null ? item.checked : undefined
79
+ const childTokens = item.tokens || []
80
+ let bulletUsed = false
81
+
82
+ for (const token of childTokens) {
83
+ if (token.type === "space" || token.type === "checkbox") continue
84
+
85
+ if (token.type === "text" || token.type === "paragraph") {
86
+ // Inline content — attach the bullet to the first one
87
+ result.push({
88
+ token,
89
+ indent,
90
+ bullet: bulletUsed ? undefined : bullet,
91
+ checked: bulletUsed ? undefined : checked,
92
+ })
93
+ bulletUsed = true
94
+ } else if (token.type === "list") {
95
+ // Emit bullet line if nothing preceded this nested list
96
+ if (!bulletUsed) {
97
+ result.push({
98
+ token: { type: "text", raw: "", text: "", tokens: [] } as unknown as Token,
99
+ indent,
100
+ bullet,
101
+ checked,
102
+ })
103
+ bulletUsed = true
104
+ }
105
+ // Nested list — increase indent to align with content after bullet
106
+ const list = token as Tokens.List
107
+ for (let i = 0; i < list.items.length; i++) {
108
+ const subItem = list.items[i]
109
+ const subBullet = list.ordered ? `${i + (list.start || 1)}. ` : "- "
110
+ flattenListItem(subItem, indent + bullet.length, subBullet, result)
111
+ }
112
+ } else {
113
+ // Block content (code, table, blockquote, hr, etc.)
114
+ if (!bulletUsed) {
115
+ result.push({
116
+ token: { type: "text", raw: "", text: "", tokens: [] } as unknown as Token,
117
+ indent,
118
+ bullet,
119
+ checked,
120
+ })
121
+ bulletUsed = true
122
+ }
123
+ // Emit the block indented to align with content after the bullet
124
+ result.push({ token, indent: indent + bullet.length })
125
+ }
126
+ }
127
+
128
+ // List item had no content tokens — still emit the bullet
129
+ if (!bulletUsed) {
130
+ result.push({
131
+ token: { type: "text", raw: "", text: "", tokens: [] } as unknown as Token,
132
+ indent,
133
+ bullet,
134
+ checked,
135
+ })
136
+ }
137
+ }
138
+
139
+ // ---------------------------------------------------------------------------
140
+ // Component
141
+ // ---------------------------------------------------------------------------
142
+
19
143
  export function MarkdownView({ content, showLineNumbers = true, marks, docRef }: MarkdownViewProps) {
20
144
  const { theme, syntax } = useTheme()
21
145
  const palette = useGutterPalette()
22
146
  const tokens = marked.lexer(content)
23
- const blocks = tokens.filter((t) => t.type !== "space")
147
+ const blocks = flattenTokens(tokens)
24
148
 
25
- const blockElements = blocks.map((token, index) => (
26
- <TokenRenderer key={index} token={token} theme={theme} syntax={syntax} />
149
+ const blockElements = blocks.map((block, index) => (
150
+ <FlatBlockRenderer key={index} block={block} theme={theme} syntax={syntax} />
27
151
  ))
28
152
 
29
153
  return (
@@ -40,32 +164,50 @@ export function MarkdownView({ content, showLineNumbers = true, marks, docRef }:
40
164
  )
41
165
  }
42
166
 
43
- function TokenRenderer({
44
- token,
167
+ // ---------------------------------------------------------------------------
168
+ // Block renderer (flat)
169
+ // ---------------------------------------------------------------------------
170
+
171
+ function FlatBlockRenderer({
172
+ block,
45
173
  theme,
46
174
  syntax,
47
175
  }: {
48
- token: Token
176
+ block: FlatBlock
49
177
  theme: ResolvedTheme
50
178
  syntax: SyntaxStyle
51
179
  }): ReactNode {
180
+ const { token, indent, bullet } = block
181
+
182
+ // List item line (has bullet)
183
+ if (bullet !== undefined) {
184
+ return <ListLineRenderer block={block} theme={theme} />
185
+ }
186
+
187
+ // Regular block token
52
188
  switch (token.type) {
53
189
  case "heading":
54
- return <HeadingRenderer token={token as Tokens.Heading} theme={theme} />
190
+ return <HeadingRenderer token={token as Tokens.Heading} theme={theme} indent={indent} />
55
191
  case "paragraph":
56
- return <ParagraphRenderer token={token as Tokens.Paragraph} theme={theme} />
192
+ return <ParagraphRenderer token={token as Tokens.Paragraph} theme={theme} indent={indent} />
57
193
  case "code":
58
- return <CodeBlockRenderer token={token as Tokens.Code} theme={theme} syntax={syntax} />
194
+ return (
195
+ <CodeBlockRenderer
196
+ token={token as Tokens.Code}
197
+ theme={theme}
198
+ syntax={syntax}
199
+ indent={indent}
200
+ />
201
+ )
59
202
  case "blockquote":
60
- return <BlockquoteRenderer token={token as Tokens.Blockquote} theme={theme} />
61
- case "list":
62
- return <ListRenderer token={token as Tokens.List} theme={theme} />
203
+ return (
204
+ <BlockquoteRenderer token={token as Tokens.Blockquote} theme={theme} indent={indent} />
205
+ )
63
206
  case "table":
64
- return <MarkdownTableRenderer token={token as Tokens.Table} />
207
+ return <MarkdownTableRenderer token={token as Tokens.Table} indent={indent} />
65
208
  case "hr":
66
- return <HorizontalRule theme={theme} />
209
+ return <HorizontalRule theme={theme} indent={indent} />
67
210
  case "space":
68
- return null
69
211
  case "html":
70
212
  return null
71
213
  default:
@@ -77,7 +219,7 @@ function TokenRenderer({
77
219
  fg: theme.markdownText,
78
220
  marginBottom: 1,
79
221
  marginTop: 0,
80
- marginLeft: 1,
222
+ marginLeft: 1 + indent,
81
223
  marginRight: 1,
82
224
  }}
83
225
  />
@@ -87,7 +229,52 @@ function TokenRenderer({
87
229
  }
88
230
  }
89
231
 
90
- function HeadingRenderer({ token, theme }: { token: Tokens.Heading; theme: ResolvedTheme }) {
232
+ // ---------------------------------------------------------------------------
233
+ // List line renderer
234
+ // ---------------------------------------------------------------------------
235
+
236
+ function ListLineRenderer({ block, theme }: { block: FlatBlock; theme: ResolvedTheme }) {
237
+ const { token, indent, bullet, checked } = block
238
+ const checkboxPrefix = checked !== undefined ? (checked ? "[x] " : "[ ] ") : ""
239
+
240
+ // Get inline tokens from the text/paragraph token
241
+ const inlineTokens: Token[] =
242
+ "tokens" in token && Array.isArray(token.tokens) ? token.tokens : []
243
+
244
+ const hasText = "text" in token && typeof token.text === "string" && token.text.length > 0
245
+ const hasContent = inlineTokens.length > 0 || hasText
246
+
247
+ return (
248
+ <box style={{ marginLeft: 1 + indent, marginRight: 1 }}>
249
+ <text style={{ fg: theme.markdownText }}>
250
+ <span fg={theme.markdownListItem}>{bullet}</span>
251
+ {checkboxPrefix !== "" && (
252
+ <span fg={checked ? theme.accent : theme.textMuted}>{checkboxPrefix}</span>
253
+ )}
254
+ {hasContent &&
255
+ (inlineTokens.length > 0 ? (
256
+ <InlineTokens tokens={inlineTokens} theme={theme} />
257
+ ) : hasText ? (
258
+ ("text" in token ? (token as { text: string }).text : "")
259
+ ) : null)}
260
+ </text>
261
+ </box>
262
+ )
263
+ }
264
+
265
+ // ---------------------------------------------------------------------------
266
+ // Block renderers
267
+ // ---------------------------------------------------------------------------
268
+
269
+ function HeadingRenderer({
270
+ token,
271
+ theme,
272
+ indent,
273
+ }: {
274
+ token: Tokens.Heading
275
+ theme: ResolvedTheme
276
+ indent: number
277
+ }) {
91
278
  const headingColors: Record<number, string> = {
92
279
  1: theme.markdownHeading,
93
280
  2: theme.secondary,
@@ -106,21 +293,29 @@ function HeadingRenderer({ token, theme }: { token: Tokens.Heading; theme: Resol
106
293
  6: "###### ",
107
294
  }
108
295
 
109
- const headingText = getPlainText(token.tokens || [])
110
-
111
296
  return (
112
- <box style={{ marginTop: 1, marginBottom: 1 }}>
297
+ <box style={{ marginTop: 1, marginBottom: 1, marginLeft: indent }}>
113
298
  <text style={{ fg: headingColors[token.depth] || theme.text }}>
114
299
  <span fg={theme.textMuted}>{prefixes[token.depth]}</span>
115
- <strong>{headingText}</strong>
300
+ <strong>
301
+ <InlineTokens tokens={token.tokens || []} theme={theme} />
302
+ </strong>
116
303
  </text>
117
304
  </box>
118
305
  )
119
306
  }
120
307
 
121
- function ParagraphRenderer({ token, theme }: { token: Tokens.Paragraph; theme: ResolvedTheme }) {
308
+ function ParagraphRenderer({
309
+ token,
310
+ theme,
311
+ indent,
312
+ }: {
313
+ token: Tokens.Paragraph
314
+ theme: ResolvedTheme
315
+ indent: number
316
+ }) {
122
317
  return (
123
- <box style={{ marginBottom: 1, marginLeft: 1, marginRight: 1 }}>
318
+ <box style={{ marginBottom: 1, marginLeft: 1 + indent, marginRight: 1 }}>
124
319
  <text style={{ fg: theme.markdownText }}>
125
320
  <InlineTokens tokens={token.tokens || []} theme={theme} />
126
321
  </text>
@@ -132,10 +327,12 @@ function CodeBlockRenderer({
132
327
  token,
133
328
  theme,
134
329
  syntax,
330
+ indent,
135
331
  }: {
136
332
  token: Tokens.Code
137
333
  theme: ResolvedTheme
138
334
  syntax: SyntaxStyle
335
+ indent: number
139
336
  }) {
140
337
  const lineCount = token.text.split("\n").length
141
338
  return (
@@ -143,7 +340,7 @@ function CodeBlockRenderer({
143
340
  style={{
144
341
  marginTop: 0,
145
342
  marginBottom: 1,
146
- marginLeft: 1,
343
+ marginLeft: 1 + indent,
147
344
  marginRight: 1,
148
345
  border: true,
149
346
  borderColor: theme.border,
@@ -161,105 +358,72 @@ function CodeBlockRenderer({
161
358
  )
162
359
  }
163
360
 
164
- function BlockquoteRenderer({ token, theme }: { token: Tokens.Blockquote; theme: ResolvedTheme }) {
165
- const quoteText = token.tokens
166
- ? token.tokens
167
- .map((t) => {
168
- const innerTokens = "tokens" in t ? (t as { tokens?: Token[] }).tokens : undefined
169
- const textContent = "text" in t ? (t as { text?: string }).text : ""
170
- return getPlainText(innerTokens || []) || textContent || ""
171
- })
172
- .join("\n")
173
- : ""
174
-
175
- return (
176
- <box style={{ marginTop: 0, marginBottom: 1, marginLeft: 1, marginRight: 1, paddingLeft: 2 }}>
177
- <text style={{ fg: theme.markdownBlockQuote }} content="│ " />
178
- <text style={{ fg: theme.textMuted }} content={quoteText} />
179
- </box>
180
- )
181
- }
182
-
183
- function ListRenderer({ token, theme }: { token: Tokens.List; theme: ResolvedTheme }) {
184
- return (
185
- <box style={{ marginBottom: 1, marginLeft: 3, marginRight: 1, flexDirection: "column" }}>
186
- {token.items.map((item, index) => (
187
- <ListItemRenderer
188
- key={index}
189
- item={item}
190
- ordered={token.ordered}
191
- index={index + (token.start || 1)}
192
- theme={theme}
193
- />
194
- ))}
195
- </box>
196
- )
197
- }
198
-
199
- function ListItemRenderer({
200
- item,
201
- ordered,
202
- index,
361
+ function BlockquoteRenderer({
362
+ token,
203
363
  theme,
364
+ indent,
204
365
  }: {
205
- item: Tokens.ListItem
206
- ordered: boolean
207
- index: number
366
+ token: Tokens.Blockquote
208
367
  theme: ResolvedTheme
368
+ indent: number
209
369
  }) {
210
- const bullet = ordered ? `${index}. ` : "- "
211
- const itemContent = item.tokens || []
370
+ // Collect inline tokens from blockquote's child paragraphs/text
371
+ const inlineTokens: Token[] = []
372
+ if (token.tokens) {
373
+ for (const child of token.tokens) {
374
+ if ("tokens" in child && Array.isArray(child.tokens)) {
375
+ if (inlineTokens.length > 0) {
376
+ inlineTokens.push({ type: "text", raw: "\n", text: "\n" } as Token)
377
+ }
378
+ inlineTokens.push(...(child.tokens as Token[]))
379
+ } else if ("text" in child && typeof child.text === "string") {
380
+ inlineTokens.push(child)
381
+ }
382
+ }
383
+ }
212
384
 
213
385
  return (
214
- <box style={{ flexDirection: "row" }}>
215
- <text style={{ fg: theme.markdownListItem }} content={bullet} />
216
- <box style={{ flexShrink: 1, flexDirection: "column" }}>
217
- {itemContent.map((token, idx) => {
218
- if (token.type === "text" && "tokens" in token && token.tokens) {
219
- return (
220
- <text key={idx} style={{ fg: theme.markdownText }}>
221
- <InlineTokens tokens={token.tokens} theme={theme} />
222
- </text>
223
- )
224
- }
225
- if (token.type === "paragraph" && token.tokens) {
226
- return (
227
- <text key={idx} style={{ fg: theme.markdownText }}>
228
- <InlineTokens tokens={token.tokens} theme={theme} />
229
- </text>
230
- )
231
- }
232
- if (token.type === "list") {
233
- return <ListRenderer key={idx} token={token as Tokens.List} theme={theme} />
234
- }
235
- if ("text" in token && typeof token.text === "string") {
236
- return <text key={idx} style={{ fg: theme.markdownText }} content={token.text} />
237
- }
238
- return null
239
- })}
240
- </box>
386
+ <box
387
+ style={{
388
+ marginTop: 0,
389
+ marginBottom: 1,
390
+ marginLeft: 1 + indent,
391
+ marginRight: 1,
392
+ paddingLeft: 2,
393
+ }}
394
+ >
395
+ <text style={{ fg: theme.markdownBlockQuote }} content="│ " />
396
+ <text style={{ fg: theme.textMuted }}>
397
+ <InlineTokens tokens={inlineTokens} theme={theme} />
398
+ </text>
241
399
  </box>
242
400
  )
243
401
  }
244
402
 
245
- function MarkdownTableRenderer({ token }: { token: Tokens.Table }) {
403
+ function MarkdownTableRenderer({ token, indent }: { token: Tokens.Table; indent: number }) {
246
404
  const { theme } = useTheme()
247
405
 
248
406
  const content: TextTableContent = useMemo(() => {
249
- const headerRow: TextTableCellContent[] = token.header.map((cell) => [
250
- boldChunk(getPlainText(cell.tokens).trim()),
251
- ])
407
+ const headerRow: TextTableCellContent[] = token.header.map((cell) => {
408
+ const chunks = inlineTokensToChunks(cell.tokens, theme)
409
+ // Wrap header chunks in bold
410
+ return chunks.length > 0
411
+ ? chunks.map((c) => boldChunk(c))
412
+ : [boldChunk(getPlainText(cell.tokens).trim())]
413
+ })
252
414
  const dataRows = token.rows.map((row) =>
253
- row.map(
254
- (cell) =>
255
- [{ __isChunk: true as const, text: getPlainText(cell.tokens) }] as TextTableCellContent,
256
- ),
415
+ row.map((cell) => {
416
+ const chunks = inlineTokensToChunks(cell.tokens, theme)
417
+ return chunks.length > 0
418
+ ? chunks
419
+ : ([{ __isChunk: true as const, text: getPlainText(cell.tokens) }] as TextTableCellContent)
420
+ }),
257
421
  )
258
422
  return [headerRow, ...dataRows]
259
- }, [token])
423
+ }, [token, theme])
260
424
 
261
425
  return (
262
- <box style={{ marginLeft: 1, marginRight: 1, marginBottom: 1 }}>
426
+ <box style={{ marginLeft: 1 + indent, marginRight: 1, marginBottom: 1 }}>
263
427
  <text-table
264
428
  content={content}
265
429
  wrapMode="word"
@@ -274,25 +438,17 @@ function MarkdownTableRenderer({ token }: { token: Tokens.Table }) {
274
438
  )
275
439
  }
276
440
 
277
- function HorizontalRule({ theme }: { theme: ResolvedTheme }) {
441
+ function HorizontalRule({ theme, indent }: { theme: ResolvedTheme; indent: number }) {
278
442
  return (
279
- <box style={{ marginTop: 0, marginBottom: 1, marginLeft: 1, marginRight: 1 }}>
443
+ <box style={{ marginTop: 0, marginBottom: 1, marginLeft: 1 + indent, marginRight: 1 }}>
280
444
  <text style={{ fg: theme.markdownHorizontalRule }} content={"─".repeat(40)} />
281
445
  </box>
282
446
  )
283
447
  }
284
448
 
285
- function getPlainText(tokens: Token[]): string {
286
- return tokens
287
- .map((token) => {
288
- if (token.type === "text") return token.text
289
- if (token.type === "codespan") return (token as Tokens.Codespan).text
290
- if ("tokens" in token && token.tokens) return getPlainText(token.tokens as Token[])
291
- if ("text" in token) return (token as { text: string }).text
292
- return ""
293
- })
294
- .join("")
295
- }
449
+ // ---------------------------------------------------------------------------
450
+ // Inline token rendering (React elements)
451
+ // ---------------------------------------------------------------------------
296
452
 
297
453
  function InlineTokens({ tokens, theme }: { tokens: Token[]; theme: ResolvedTheme }): ReactNode {
298
454
  const result: ReactNode[] = []
@@ -308,11 +464,17 @@ function InlineTokens({ tokens, theme }: { tokens: Token[]; theme: ResolvedTheme
308
464
  break
309
465
  case "strong":
310
466
  result.push(
311
- <strong key={key}>{getPlainText((token as Tokens.Strong).tokens || [])}</strong>,
467
+ <strong key={key}>
468
+ <InlineTokens tokens={(token as Tokens.Strong).tokens || []} theme={theme} />
469
+ </strong>,
312
470
  )
313
471
  break
314
472
  case "em":
315
- result.push(<em key={key}>{getPlainText((token as Tokens.Em).tokens || [])}</em>)
473
+ result.push(
474
+ <em key={key}>
475
+ <InlineTokens tokens={(token as Tokens.Em).tokens || []} theme={theme} />
476
+ </em>,
477
+ )
316
478
  break
317
479
  case "codespan":
318
480
  result.push(
@@ -326,12 +488,30 @@ function InlineTokens({ tokens, theme }: { tokens: Token[]; theme: ResolvedTheme
326
488
  result.push(
327
489
  <u key={key}>
328
490
  <a href={linkToken.href} fg={theme.markdownLink}>
329
- {getPlainText(linkToken.tokens || [])}
491
+ <InlineTokens tokens={linkToken.tokens || []} theme={theme} />
330
492
  </a>
331
493
  </u>,
332
494
  )
333
495
  break
334
496
  }
497
+ case "del":
498
+ result.push(
499
+ <span key={key} fg={theme.textMuted}>
500
+ {"~"}
501
+ <InlineTokens tokens={(token as Tokens.Del).tokens || []} theme={theme} />
502
+ {"~"}
503
+ </span>,
504
+ )
505
+ break
506
+ case "image": {
507
+ const imgToken = token as Tokens.Image
508
+ result.push(
509
+ <span key={key} fg={theme.textMuted}>
510
+ {imgToken.text || imgToken.href}
511
+ </span>,
512
+ )
513
+ break
514
+ }
335
515
  case "br":
336
516
  result.push("\n")
337
517
  break
@@ -351,3 +531,73 @@ function InlineTokens({ tokens, theme }: { tokens: Token[]; theme: ResolvedTheme
351
531
 
352
532
  return <>{result}</>
353
533
  }
534
+
535
+ // ---------------------------------------------------------------------------
536
+ // Inline token rendering (TextChunks — for text-table cells)
537
+ // ---------------------------------------------------------------------------
538
+
539
+ function inlineTokensToChunks(tokens: Token[], theme: ResolvedTheme): TextChunk[] {
540
+ const chunks: TextChunk[] = []
541
+
542
+ for (const token of tokens) {
543
+ switch (token.type) {
544
+ case "text":
545
+ chunks.push({ __isChunk: true as const, text: (token as Tokens.Text).text })
546
+ break
547
+ case "strong":
548
+ for (const sub of inlineTokensToChunks(
549
+ (token as Tokens.Strong).tokens || [],
550
+ theme,
551
+ )) {
552
+ chunks.push(boldChunk(sub))
553
+ }
554
+ break
555
+ case "em":
556
+ for (const sub of inlineTokensToChunks((token as Tokens.Em).tokens || [], theme)) {
557
+ chunks.push(italicChunk(sub))
558
+ }
559
+ break
560
+ case "codespan":
561
+ chunks.push({
562
+ __isChunk: true as const,
563
+ text: ` ${(token as Tokens.Codespan).text} `,
564
+ fg: parseColor(theme.markdownCode),
565
+ bg: parseColor(theme.backgroundPanel),
566
+ })
567
+ break
568
+ case "link": {
569
+ const linkToken = token as Tokens.Link
570
+ for (const sub of inlineTokensToChunks(linkToken.tokens || [], theme)) {
571
+ chunks.push(underlineChunk({ ...sub, fg: parseColor(theme.markdownLink) }))
572
+ }
573
+ break
574
+ }
575
+ case "escape":
576
+ chunks.push({ __isChunk: true as const, text: (token as Tokens.Escape).text })
577
+ break
578
+ default:
579
+ if ("text" in token && typeof (token as { text?: string }).text === "string") {
580
+ chunks.push({ __isChunk: true as const, text: (token as { text: string }).text })
581
+ }
582
+ break
583
+ }
584
+ }
585
+
586
+ return chunks
587
+ }
588
+
589
+ // ---------------------------------------------------------------------------
590
+ // Plain text extraction (only for width computation, not rendering)
591
+ // ---------------------------------------------------------------------------
592
+
593
+ function getPlainText(tokens: Token[]): string {
594
+ return tokens
595
+ .map((token) => {
596
+ if (token.type === "text") return token.text
597
+ if (token.type === "codespan") return (token as Tokens.Codespan).text
598
+ if ("tokens" in token && token.tokens) return getPlainText(token.tokens as Token[])
599
+ if ("text" in token) return (token as { text: string }).text
600
+ return ""
601
+ })
602
+ .join("")
603
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { MarkdownView } from "./MarkdownView.js"
1
+ export { MarkdownView, flattenTokens } from "./MarkdownView.js"
2
+ export type { FlatBlock } from "./MarkdownView.js"
2
3
  export { CodeView } from "./CodeView.js"
3
4
  export { ImageView } from "./ImageView.js"
4
5
  export { Table, computeColumnWidths, isNumeric, sampleRows } from "./Table.js"