@mariozechner/pi-tui 0.7.17 → 0.7.18

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,29 +1,43 @@
1
1
  import type { Component } from "../tui.js";
2
- type Color = "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white" | "gray" | "bgBlack" | "bgRed" | "bgGreen" | "bgYellow" | "bgBlue" | "bgMagenta" | "bgCyan" | "bgWhite" | "bgGray";
2
+ /**
3
+ * Default text styling for markdown content.
4
+ * Applied to all text unless overridden by markdown formatting.
5
+ */
6
+ export interface DefaultTextStyle {
7
+ /** Foreground color - named color or hex string like "#ff0000" */
8
+ color?: string;
9
+ /** Background color - named color or hex string like "#ff0000" */
10
+ bgColor?: string;
11
+ /** Bold text */
12
+ bold?: boolean;
13
+ /** Italic text */
14
+ italic?: boolean;
15
+ /** Strikethrough text */
16
+ strikethrough?: boolean;
17
+ /** Underline text */
18
+ underline?: boolean;
19
+ }
3
20
  export declare class Markdown implements Component {
4
21
  private text;
5
- private bgColor?;
6
- private fgColor?;
7
- private customBgRgb?;
8
22
  private paddingX;
9
23
  private paddingY;
24
+ private defaultTextStyle?;
10
25
  private cachedText?;
11
26
  private cachedWidth?;
12
27
  private cachedLines?;
13
- constructor(text?: string, bgColor?: Color, fgColor?: Color, customBgRgb?: {
14
- r: number;
15
- g: number;
16
- b: number;
17
- }, paddingX?: number, paddingY?: number);
28
+ constructor(text?: string, paddingX?: number, paddingY?: number, defaultTextStyle?: DefaultTextStyle);
18
29
  setText(text: string): void;
19
- setBgColor(bgColor?: Color): void;
20
- setFgColor(fgColor?: Color): void;
21
- setCustomBgRgb(customBgRgb?: {
22
- r: number;
23
- g: number;
24
- b: number;
25
- }): void;
26
30
  render(width: number): string[];
31
+ /**
32
+ * Apply only background color from default style.
33
+ * Used for padding lines that don't have text content.
34
+ */
35
+ private applyBgColor;
36
+ /**
37
+ * Apply default text style to a string.
38
+ * This is the base styling applied to all text content.
39
+ */
40
+ private applyDefaultStyle;
27
41
  private renderToken;
28
42
  private renderInlineTokens;
29
43
  private wrapLine;
@@ -42,5 +56,4 @@ export declare class Markdown implements Component {
42
56
  */
43
57
  private renderTable;
44
58
  }
45
- export {};
46
59
  //# sourceMappingURL=markdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/components/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C,KAAK,KAAK,GACP,OAAO,GACP,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,MAAM,GACN,OAAO,GACP,MAAM,GACN,SAAS,GACT,OAAO,GACP,SAAS,GACT,UAAU,GACV,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,SAAS,GACT,QAAQ,CAAC;AAEZ,qBAAa,QAAS,YAAW,SAAS;IACzC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,OAAO,CAAC,CAAQ;IACxB,OAAO,CAAC,OAAO,CAAC,CAAQ;IACxB,OAAO,CAAC,WAAW,CAAC,CAAsC;IAC1D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IAGzB,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAC,CAAW;IAE/B,YACC,IAAI,GAAE,MAAW,EACjB,OAAO,CAAC,EAAE,KAAK,EACf,OAAO,CAAC,EAAE,KAAK,EACf,WAAW,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EACjD,QAAQ,GAAE,MAAU,EACpB,QAAQ,GAAE,MAAU,EAQpB;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM1B;IAED,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,IAAI,CAMhC;IAED,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,IAAI,CAMhC;IAED,cAAc,CAAC,WAAW,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAMtE;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAwG9B;IAED,OAAO,CAAC,WAAW;IAyFnB,OAAO,CAAC,kBAAkB;IAwD1B,OAAO,CAAC,QAAQ;IA0BhB,OAAO,CAAC,cAAc;IAmFtB;;OAEG;IACH,OAAO,CAAC,UAAU;IA8ClB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAsCtB;;OAEG;IACH,OAAO,CAAC,WAAW;CAqDnB","sourcesContent":["import chalk from \"chalk\";\nimport { marked, type Token } from \"marked\";\nimport type { Component } from \"../tui.js\";\nimport { visibleWidth } from \"../utils.js\";\n\ntype Color =\n\t| \"black\"\n\t| \"red\"\n\t| \"green\"\n\t| \"yellow\"\n\t| \"blue\"\n\t| \"magenta\"\n\t| \"cyan\"\n\t| \"white\"\n\t| \"gray\"\n\t| \"bgBlack\"\n\t| \"bgRed\"\n\t| \"bgGreen\"\n\t| \"bgYellow\"\n\t| \"bgBlue\"\n\t| \"bgMagenta\"\n\t| \"bgCyan\"\n\t| \"bgWhite\"\n\t| \"bgGray\";\n\nexport class Markdown implements Component {\n\tprivate text: string;\n\tprivate bgColor?: Color;\n\tprivate fgColor?: Color;\n\tprivate customBgRgb?: { r: number; g: number; b: number };\n\tprivate paddingX: number; // Left/right padding\n\tprivate paddingY: number; // Top/bottom padding\n\n\t// Cache for rendered output\n\tprivate cachedText?: string;\n\tprivate cachedWidth?: number;\n\tprivate cachedLines?: string[];\n\n\tconstructor(\n\t\ttext: string = \"\",\n\t\tbgColor?: Color,\n\t\tfgColor?: Color,\n\t\tcustomBgRgb?: { r: number; g: number; b: number },\n\t\tpaddingX: number = 1,\n\t\tpaddingY: number = 1,\n\t) {\n\t\tthis.text = text;\n\t\tthis.bgColor = bgColor;\n\t\tthis.fgColor = fgColor;\n\t\tthis.customBgRgb = customBgRgb;\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t}\n\n\tsetText(text: string): void {\n\t\tthis.text = text;\n\t\t// Invalidate cache when text changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tsetBgColor(bgColor?: Color): void {\n\t\tthis.bgColor = bgColor;\n\t\t// Invalidate cache when color changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tsetFgColor(fgColor?: Color): void {\n\t\tthis.fgColor = fgColor;\n\t\t// Invalidate cache when color changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tsetCustomBgRgb(customBgRgb?: { r: number; g: number; b: number }): void {\n\t\tthis.customBgRgb = customBgRgb;\n\t\t// Invalidate cache when color changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\t// Check cache\n\t\tif (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\t// Calculate available width for content (subtract horizontal padding)\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\n\t\t// Don't render anything if there's no actual text\n\t\tif (!this.text || this.text.trim() === \"\") {\n\t\t\tconst result: string[] = [];\n\t\t\t// Update cache\n\t\t\tthis.cachedText = this.text;\n\t\t\tthis.cachedWidth = width;\n\t\t\tthis.cachedLines = result;\n\t\t\treturn result;\n\t\t}\n\n\t\t// Replace tabs with 3 spaces for consistent rendering\n\t\tconst normalizedText = this.text.replace(/\\t/g, \" \");\n\n\t\t// Parse markdown to HTML-like tokens\n\t\tconst tokens = marked.lexer(normalizedText);\n\n\t\t// Convert tokens to styled terminal output\n\t\tconst renderedLines: string[] = [];\n\n\t\tfor (let i = 0; i < tokens.length; i++) {\n\t\t\tconst token = tokens[i];\n\t\t\tconst nextToken = tokens[i + 1];\n\t\t\tconst tokenLines = this.renderToken(token, contentWidth, nextToken?.type);\n\t\t\trenderedLines.push(...tokenLines);\n\t\t}\n\n\t\t// Wrap lines to fit content width\n\t\tconst wrappedLines: string[] = [];\n\t\tfor (const line of renderedLines) {\n\t\t\twrappedLines.push(...this.wrapLine(line, contentWidth));\n\t\t}\n\n\t\t// Add padding and apply colors\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\t\tconst paddedLines: string[] = [];\n\n\t\tfor (const line of wrappedLines) {\n\t\t\t// Calculate visible length\n\t\t\tconst visibleLength = visibleWidth(line);\n\t\t\t// Right padding to fill to width (accounting for left padding and content)\n\t\t\tconst rightPadLength = Math.max(0, width - this.paddingX - visibleLength);\n\t\t\tconst rightPad = \" \".repeat(rightPadLength);\n\n\t\t\t// Add left padding, content, and right padding\n\t\t\tlet paddedLine = leftPad + line + rightPad;\n\n\t\t\t// Apply foreground color if specified\n\t\t\tif (this.fgColor) {\n\t\t\t\tpaddedLine = (chalk as any)[this.fgColor](paddedLine);\n\t\t\t}\n\n\t\t\t// Apply background color if specified\n\t\t\tif (this.customBgRgb) {\n\t\t\t\tpaddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(paddedLine);\n\t\t\t} else if (this.bgColor) {\n\t\t\t\tpaddedLine = (chalk as any)[this.bgColor](paddedLine);\n\t\t\t}\n\n\t\t\tpaddedLines.push(paddedLine);\n\t\t}\n\n\t\t// Add top padding (empty lines)\n\t\tconst emptyLine = \" \".repeat(width);\n\t\tconst topPadding: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tlet emptyPaddedLine = emptyLine;\n\t\t\tif (this.customBgRgb) {\n\t\t\t\temptyPaddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(emptyPaddedLine);\n\t\t\t} else if (this.bgColor) {\n\t\t\t\temptyPaddedLine = (chalk as any)[this.bgColor](emptyPaddedLine);\n\t\t\t}\n\t\t\ttopPadding.push(emptyPaddedLine);\n\t\t}\n\n\t\t// Add bottom padding (empty lines)\n\t\tconst bottomPadding: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tlet emptyPaddedLine = emptyLine;\n\t\t\tif (this.customBgRgb) {\n\t\t\t\temptyPaddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(emptyPaddedLine);\n\t\t\t} else if (this.bgColor) {\n\t\t\t\temptyPaddedLine = (chalk as any)[this.bgColor](emptyPaddedLine);\n\t\t\t}\n\t\t\tbottomPadding.push(emptyPaddedLine);\n\t\t}\n\n\t\t// Combine top padding, content, and bottom padding\n\t\tconst result = [...topPadding, ...paddedLines, ...bottomPadding];\n\n\t\t// Update cache\n\t\tthis.cachedText = this.text;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedLines = result;\n\n\t\treturn result.length > 0 ? result : [\"\"];\n\t}\n\n\tprivate renderToken(token: Token, width: number, nextTokenType?: string): string[] {\n\t\tconst lines: string[] = [];\n\n\t\tswitch (token.type) {\n\t\t\tcase \"heading\": {\n\t\t\t\tconst headingLevel = token.depth;\n\t\t\t\tconst headingPrefix = \"#\".repeat(headingLevel) + \" \";\n\t\t\t\tconst headingText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tif (headingLevel === 1) {\n\t\t\t\t\tlines.push(chalk.bold.underline.yellow(headingText));\n\t\t\t\t} else if (headingLevel === 2) {\n\t\t\t\t\tlines.push(chalk.bold.yellow(headingText));\n\t\t\t\t} else {\n\t\t\t\t\tlines.push(chalk.bold(headingPrefix + headingText));\n\t\t\t\t}\n\t\t\t\tlines.push(\"\"); // Add spacing after headings\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"paragraph\": {\n\t\t\t\tconst paragraphText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tlines.push(paragraphText);\n\t\t\t\t// Don't add spacing if next token is space or list\n\t\t\t\tif (nextTokenType && nextTokenType !== \"list\" && nextTokenType !== \"space\") {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"code\": {\n\t\t\t\tlines.push(chalk.gray(\"```\" + (token.lang || \"\")));\n\t\t\t\t// Split code by newlines and style each line\n\t\t\t\tconst codeLines = token.text.split(\"\\n\");\n\t\t\t\tfor (const codeLine of codeLines) {\n\t\t\t\t\tlines.push(chalk.dim(\" \") + chalk.green(codeLine));\n\t\t\t\t}\n\t\t\t\tlines.push(chalk.gray(\"```\"));\n\t\t\t\tlines.push(\"\"); // Add spacing after code blocks\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"list\": {\n\t\t\t\tconst listLines = this.renderList(token as any, 0);\n\t\t\t\tlines.push(...listLines);\n\t\t\t\t// Don't add spacing after lists if a space token follows\n\t\t\t\t// (the space token will handle it)\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"table\": {\n\t\t\t\tconst tableLines = this.renderTable(token as any);\n\t\t\t\tlines.push(...tableLines);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"blockquote\": {\n\t\t\t\tconst quoteText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tconst quoteLines = quoteText.split(\"\\n\");\n\t\t\t\tfor (const quoteLine of quoteLines) {\n\t\t\t\t\tlines.push(chalk.gray(\"│ \") + chalk.italic(quoteLine));\n\t\t\t\t}\n\t\t\t\tlines.push(\"\"); // Add spacing after blockquotes\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"hr\":\n\t\t\t\tlines.push(chalk.gray(\"─\".repeat(Math.min(width, 80))));\n\t\t\t\tlines.push(\"\"); // Add spacing after horizontal rules\n\t\t\t\tbreak;\n\n\t\t\tcase \"html\":\n\t\t\t\t// Skip HTML for terminal output\n\t\t\t\tbreak;\n\n\t\t\tcase \"space\":\n\t\t\t\t// Space tokens represent blank lines in markdown\n\t\t\t\tlines.push(\"\");\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// Handle any other token types as plain text\n\t\t\t\tif (\"text\" in token && typeof token.text === \"string\") {\n\t\t\t\t\tlines.push(token.text);\n\t\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\tprivate renderInlineTokens(tokens: Token[]): string {\n\t\tlet result = \"\";\n\n\t\tfor (const token of tokens) {\n\t\t\tswitch (token.type) {\n\t\t\t\tcase \"text\":\n\t\t\t\t\t// Text tokens in list items can have nested tokens for inline formatting\n\t\t\t\t\tif (token.tokens && token.tokens.length > 0) {\n\t\t\t\t\t\tresult += this.renderInlineTokens(token.tokens);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += token.text;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"strong\":\n\t\t\t\t\tresult += chalk.bold(this.renderInlineTokens(token.tokens || []));\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"em\":\n\t\t\t\t\tresult += chalk.italic(this.renderInlineTokens(token.tokens || []));\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"codespan\":\n\t\t\t\t\tresult += chalk.gray(\"`\") + chalk.cyan(token.text) + chalk.gray(\"`\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"link\": {\n\t\t\t\t\tconst linkText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\t// If link text matches href, only show the link once\n\t\t\t\t\tif (linkText === token.href) {\n\t\t\t\t\t\tresult += chalk.underline.blue(linkText);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += chalk.underline.blue(linkText) + chalk.gray(` (${token.href})`);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"br\":\n\t\t\t\t\tresult += \"\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"del\":\n\t\t\t\t\tresult += chalk.strikethrough(this.renderInlineTokens(token.tokens || []));\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\t// Handle any other inline token types as plain text\n\t\t\t\t\tif (\"text\" in token && typeof token.text === \"string\") {\n\t\t\t\t\t\tresult += token.text;\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate wrapLine(line: string, width: number): string[] {\n\t\t// Handle ANSI escape codes properly when wrapping\n\t\tconst wrapped: string[] = [];\n\n\t\t// Handle undefined or null lines\n\t\tif (!line) {\n\t\t\treturn [\"\"];\n\t\t}\n\n\t\t// Split by newlines first - wrap each line individually\n\t\tconst splitLines = line.split(\"\\n\");\n\t\tfor (const splitLine of splitLines) {\n\t\t\tconst visibleLength = visibleWidth(splitLine);\n\n\t\t\tif (visibleLength <= width) {\n\t\t\t\twrapped.push(splitLine);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// This line needs wrapping\n\t\t\twrapped.push(...this.wrapSingleLine(splitLine, width));\n\t\t}\n\n\t\treturn wrapped.length > 0 ? wrapped : [\"\"];\n\t}\n\n\tprivate wrapSingleLine(line: string, width: number): string[] {\n\t\tconst wrapped: string[] = [];\n\n\t\t// Track active ANSI codes to preserve them across wrapped lines\n\t\tconst activeAnsiCodes: string[] = [];\n\t\tlet currentLine = \"\";\n\t\tlet currentLength = 0;\n\t\tlet i = 0;\n\n\t\twhile (i < line.length) {\n\t\t\tif (line[i] === \"\\x1b\" && line[i + 1] === \"[\") {\n\t\t\t\t// ANSI escape sequence - parse and track it\n\t\t\t\tlet j = i + 2;\n\t\t\t\twhile (j < line.length && line[j] && !/[mGKHJ]/.test(line[j]!)) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (j < line.length) {\n\t\t\t\t\tconst ansiCode = line.substring(i, j + 1);\n\t\t\t\t\tcurrentLine += ansiCode;\n\n\t\t\t\t\t// Track styling codes (ending with 'm')\n\t\t\t\t\tif (line[j] === \"m\") {\n\t\t\t\t\t\t// Reset code\n\t\t\t\t\t\tif (ansiCode === \"\\x1b[0m\" || ansiCode === \"\\x1b[m\") {\n\t\t\t\t\t\t\tactiveAnsiCodes.length = 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Add to active codes (replacing similar ones)\n\t\t\t\t\t\t\tactiveAnsiCodes.push(ansiCode);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\ti = j + 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Incomplete ANSI sequence at end - don't include it\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Regular character - extract full grapheme cluster\n\t\t\t\t// Handle multi-byte characters (emoji, surrogate pairs, etc.)\n\t\t\t\tlet char: string;\n\t\t\t\tlet charByteLength: number;\n\n\t\t\t\t// Check for surrogate pair (emoji and other multi-byte chars)\n\t\t\t\tconst codePoint = line.charCodeAt(i);\n\t\t\t\tif (codePoint >= 0xd800 && codePoint <= 0xdbff && i + 1 < line.length) {\n\t\t\t\t\t// High surrogate - get the pair\n\t\t\t\t\tchar = line.substring(i, i + 2);\n\t\t\t\t\tcharByteLength = 2;\n\t\t\t\t} else {\n\t\t\t\t\t// Regular character\n\t\t\t\t\tchar = line[i];\n\t\t\t\t\tcharByteLength = 1;\n\t\t\t\t}\n\n\t\t\t\tconst charWidth = visibleWidth(char);\n\n\t\t\t\t// Check if adding this character would exceed width\n\t\t\t\tif (currentLength + charWidth > width) {\n\t\t\t\t\t// Need to wrap - close current line with reset if needed\n\t\t\t\t\tif (activeAnsiCodes.length > 0) {\n\t\t\t\t\t\twrapped.push(currentLine + \"\\x1b[0m\");\n\t\t\t\t\t\t// Start new line with active codes\n\t\t\t\t\t\tcurrentLine = activeAnsiCodes.join(\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\twrapped.push(currentLine);\n\t\t\t\t\t\tcurrentLine = \"\";\n\t\t\t\t\t}\n\t\t\t\t\tcurrentLength = 0;\n\t\t\t\t}\n\n\t\t\t\tcurrentLine += char;\n\t\t\t\tcurrentLength += charWidth;\n\t\t\t\ti += charByteLength;\n\t\t\t}\n\t\t}\n\n\t\tif (currentLine) {\n\t\t\twrapped.push(currentLine);\n\t\t}\n\n\t\treturn wrapped.length > 0 ? wrapped : [\"\"];\n\t}\n\n\t/**\n\t * Render a list with proper nesting support\n\t */\n\tprivate renderList(token: Token & { items: any[]; ordered: boolean }, depth: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst indent = \" \".repeat(depth);\n\n\t\tfor (let i = 0; i < token.items.length; i++) {\n\t\t\tconst item = token.items[i];\n\t\t\tconst bullet = token.ordered ? `${i + 1}. ` : \"- \";\n\n\t\t\t// Process item tokens to handle nested lists\n\t\t\tconst itemLines = this.renderListItem(item.tokens || [], depth);\n\n\t\t\tif (itemLines.length > 0) {\n\t\t\t\t// First line - check if it's a nested list\n\t\t\t\t// A nested list will start with indent (spaces) followed by cyan bullet\n\t\t\t\tconst firstLine = itemLines[0];\n\t\t\t\tconst isNestedList = /^\\s+\\x1b\\[36m[-\\d]/.test(firstLine); // starts with spaces + cyan + bullet char\n\n\t\t\t\tif (isNestedList) {\n\t\t\t\t\t// This is a nested list, just add it as-is (already has full indent)\n\t\t\t\t\tlines.push(firstLine);\n\t\t\t\t} else {\n\t\t\t\t\t// Regular text content - add indent and bullet\n\t\t\t\t\tlines.push(indent + chalk.cyan(bullet) + firstLine);\n\t\t\t\t}\n\n\t\t\t\t// Rest of the lines\n\t\t\t\tfor (let j = 1; j < itemLines.length; j++) {\n\t\t\t\t\tconst line = itemLines[j];\n\t\t\t\t\tconst isNestedListLine = /^\\s+\\x1b\\[36m[-\\d]/.test(line); // starts with spaces + cyan + bullet char\n\n\t\t\t\t\tif (isNestedListLine) {\n\t\t\t\t\t\t// Nested list line - already has full indent\n\t\t\t\t\t\tlines.push(line);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Regular content - add parent indent + 2 spaces for continuation\n\t\t\t\t\t\tlines.push(indent + \" \" + line);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlines.push(indent + chalk.cyan(bullet));\n\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Render list item tokens, handling nested lists\n\t * Returns lines WITHOUT the parent indent (renderList will add it)\n\t */\n\tprivate renderListItem(tokens: Token[], parentDepth: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\tfor (const token of tokens) {\n\t\t\tif (token.type === \"list\") {\n\t\t\t\t// Nested list - render with one additional indent level\n\t\t\t\t// These lines will have their own indent, so we just add them as-is\n\t\t\t\tconst nestedLines = this.renderList(token as any, parentDepth + 1);\n\t\t\t\tlines.push(...nestedLines);\n\t\t\t} else if (token.type === \"text\") {\n\t\t\t\t// Text content (may have inline tokens)\n\t\t\t\tconst text =\n\t\t\t\t\ttoken.tokens && token.tokens.length > 0 ? this.renderInlineTokens(token.tokens) : token.text || \"\";\n\t\t\t\tlines.push(text);\n\t\t\t} else if (token.type === \"paragraph\") {\n\t\t\t\t// Paragraph in list item\n\t\t\t\tconst text = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tlines.push(text);\n\t\t\t} else if (token.type === \"code\") {\n\t\t\t\t// Code block in list item\n\t\t\t\tlines.push(chalk.gray(\"```\" + (token.lang || \"\")));\n\t\t\t\tconst codeLines = token.text.split(\"\\n\");\n\t\t\t\tfor (const codeLine of codeLines) {\n\t\t\t\t\tlines.push(chalk.dim(\" \") + chalk.green(codeLine));\n\t\t\t\t}\n\t\t\t\tlines.push(chalk.gray(\"```\"));\n\t\t\t} else {\n\t\t\t\t// Other token types - try to render as inline\n\t\t\t\tconst text = this.renderInlineTokens([token]);\n\t\t\t\tif (text) {\n\t\t\t\t\tlines.push(text);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Render a table\n\t */\n\tprivate renderTable(token: Token & { header: any[]; rows: any[][] }): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Calculate column widths\n\t\tconst columnWidths: number[] = [];\n\n\t\t// Check header\n\t\tfor (let i = 0; i < token.header.length; i++) {\n\t\t\tconst headerText = this.renderInlineTokens(token.header[i].tokens || []);\n\t\t\tconst width = visibleWidth(headerText);\n\t\t\tcolumnWidths[i] = Math.max(columnWidths[i] || 0, width);\n\t\t}\n\n\t\t// Check rows\n\t\tfor (const row of token.rows) {\n\t\t\tfor (let i = 0; i < row.length; i++) {\n\t\t\t\tconst cellText = this.renderInlineTokens(row[i].tokens || []);\n\t\t\t\tconst width = visibleWidth(cellText);\n\t\t\t\tcolumnWidths[i] = Math.max(columnWidths[i] || 0, width);\n\t\t\t}\n\t\t}\n\n\t\t// Limit column widths to reasonable max\n\t\tconst maxColWidth = 40;\n\t\tfor (let i = 0; i < columnWidths.length; i++) {\n\t\t\tcolumnWidths[i] = Math.min(columnWidths[i], maxColWidth);\n\t\t}\n\n\t\t// Render header\n\t\tconst headerCells = token.header.map((cell, i) => {\n\t\t\tconst text = this.renderInlineTokens(cell.tokens || []);\n\t\t\treturn chalk.bold(text.padEnd(columnWidths[i]));\n\t\t});\n\t\tlines.push(\"│ \" + headerCells.join(\" │ \") + \" │\");\n\n\t\t// Render separator\n\t\tconst separatorCells = columnWidths.map((width) => \"─\".repeat(width));\n\t\tlines.push(\"├─\" + separatorCells.join(\"─┼─\") + \"─┤\");\n\n\t\t// Render rows\n\t\tfor (const row of token.rows) {\n\t\t\tconst rowCells = row.map((cell, i) => {\n\t\t\t\tconst text = this.renderInlineTokens(cell.tokens || []);\n\t\t\t\tconst visWidth = visibleWidth(text);\n\t\t\t\tconst padding = \" \".repeat(Math.max(0, columnWidths[i] - visWidth));\n\t\t\t\treturn text + padding;\n\t\t\t});\n\t\t\tlines.push(\"│ \" + rowCells.join(\" │ \") + \" │\");\n\t\t}\n\n\t\tlines.push(\"\"); // Add spacing after table\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/components/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAM3C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kBAAkB;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yBAAyB;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,QAAS,YAAW,SAAS;IACzC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAG5C,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAC,CAAW;IAE/B,YAAY,IAAI,GAAE,MAAW,EAAE,QAAQ,GAAE,MAAU,EAAE,QAAQ,GAAE,MAAU,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,EAK7G;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM1B;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAuF9B;IAED;;;OAGG;IACH,OAAO,CAAC,YAAY;IAiBpB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAsDzB,OAAO,CAAC,WAAW;IAyFnB,OAAO,CAAC,kBAAkB;IAyE1B,OAAO,CAAC,QAAQ;IA0BhB,OAAO,CAAC,cAAc;IAmFtB;;OAEG;IACH,OAAO,CAAC,UAAU;IA8ClB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAsCtB;;OAEG;IACH,OAAO,CAAC,WAAW;CAqDnB","sourcesContent":["import { Chalk } from \"chalk\";\nimport { marked, type Token } from \"marked\";\nimport type { Component } from \"../tui.js\";\nimport { visibleWidth } from \"../utils.js\";\n\n// Use a chalk instance with color level 3 for consistent ANSI output\nconst colorChalk = new Chalk({ level: 3 });\n\n/**\n * Default text styling for markdown content.\n * Applied to all text unless overridden by markdown formatting.\n */\nexport interface DefaultTextStyle {\n\t/** Foreground color - named color or hex string like \"#ff0000\" */\n\tcolor?: string;\n\t/** Background color - named color or hex string like \"#ff0000\" */\n\tbgColor?: string;\n\t/** Bold text */\n\tbold?: boolean;\n\t/** Italic text */\n\titalic?: boolean;\n\t/** Strikethrough text */\n\tstrikethrough?: boolean;\n\t/** Underline text */\n\tunderline?: boolean;\n}\n\nexport class Markdown implements Component {\n\tprivate text: string;\n\tprivate paddingX: number; // Left/right padding\n\tprivate paddingY: number; // Top/bottom padding\n\tprivate defaultTextStyle?: DefaultTextStyle;\n\n\t// Cache for rendered output\n\tprivate cachedText?: string;\n\tprivate cachedWidth?: number;\n\tprivate cachedLines?: string[];\n\n\tconstructor(text: string = \"\", paddingX: number = 1, paddingY: number = 1, defaultTextStyle?: DefaultTextStyle) {\n\t\tthis.text = text;\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.defaultTextStyle = defaultTextStyle;\n\t}\n\n\tsetText(text: string): void {\n\t\tthis.text = text;\n\t\t// Invalidate cache when text changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\t// Check cache\n\t\tif (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\t// Calculate available width for content (subtract horizontal padding)\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\n\t\t// Don't render anything if there's no actual text\n\t\tif (!this.text || this.text.trim() === \"\") {\n\t\t\tconst result: string[] = [];\n\t\t\t// Update cache\n\t\t\tthis.cachedText = this.text;\n\t\t\tthis.cachedWidth = width;\n\t\t\tthis.cachedLines = result;\n\t\t\treturn result;\n\t\t}\n\n\t\t// Replace tabs with 3 spaces for consistent rendering\n\t\tconst normalizedText = this.text.replace(/\\t/g, \" \");\n\n\t\t// Parse markdown to HTML-like tokens\n\t\tconst tokens = marked.lexer(normalizedText);\n\n\t\t// Convert tokens to styled terminal output\n\t\tconst renderedLines: string[] = [];\n\n\t\tfor (let i = 0; i < tokens.length; i++) {\n\t\t\tconst token = tokens[i];\n\t\t\tconst nextToken = tokens[i + 1];\n\t\t\tconst tokenLines = this.renderToken(token, contentWidth, nextToken?.type);\n\t\t\trenderedLines.push(...tokenLines);\n\t\t}\n\n\t\t// Wrap lines to fit content width\n\t\tconst wrappedLines: string[] = [];\n\t\tfor (const line of renderedLines) {\n\t\t\twrappedLines.push(...this.wrapLine(line, contentWidth));\n\t\t}\n\n\t\t// Add padding and apply background color if specified\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\t\tconst paddedLines: string[] = [];\n\n\t\tfor (const line of wrappedLines) {\n\t\t\t// Calculate visible length\n\t\t\tconst visibleLength = visibleWidth(line);\n\t\t\t// Right padding to fill to width (accounting for left padding and content)\n\t\t\tconst rightPadLength = Math.max(0, width - this.paddingX - visibleLength);\n\t\t\tconst rightPad = \" \".repeat(rightPadLength);\n\n\t\t\t// Add left padding, content, and right padding\n\t\t\tlet paddedLine = leftPad + line + rightPad;\n\n\t\t\t// Apply background color to entire line if specified\n\t\t\tif (this.defaultTextStyle?.bgColor) {\n\t\t\t\tpaddedLine = this.applyBgColor(paddedLine);\n\t\t\t}\n\n\t\t\tpaddedLines.push(paddedLine);\n\t\t}\n\n\t\t// Add top padding (empty lines)\n\t\tconst emptyLine = \" \".repeat(width);\n\t\tconst topPadding: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tconst paddedEmptyLine = this.defaultTextStyle?.bgColor ? this.applyBgColor(emptyLine) : emptyLine;\n\t\t\ttopPadding.push(paddedEmptyLine);\n\t\t}\n\n\t\t// Add bottom padding (empty lines)\n\t\tconst bottomPadding: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tconst paddedEmptyLine = this.defaultTextStyle?.bgColor ? this.applyBgColor(emptyLine) : emptyLine;\n\t\t\tbottomPadding.push(paddedEmptyLine);\n\t\t}\n\n\t\t// Combine top padding, content, and bottom padding\n\t\tconst result = [...topPadding, ...paddedLines, ...bottomPadding];\n\n\t\t// Update cache\n\t\tthis.cachedText = this.text;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedLines = result;\n\n\t\treturn result.length > 0 ? result : [\"\"];\n\t}\n\n\t/**\n\t * Apply only background color from default style.\n\t * Used for padding lines that don't have text content.\n\t */\n\tprivate applyBgColor(text: string): string {\n\t\tif (!this.defaultTextStyle?.bgColor) {\n\t\t\treturn text;\n\t\t}\n\n\t\tif (this.defaultTextStyle.bgColor.startsWith(\"#\")) {\n\t\t\t// Hex color\n\t\t\tconst hex = this.defaultTextStyle.bgColor.substring(1);\n\t\t\tconst r = Number.parseInt(hex.substring(0, 2), 16);\n\t\t\tconst g = Number.parseInt(hex.substring(2, 4), 16);\n\t\t\tconst b = Number.parseInt(hex.substring(4, 6), 16);\n\t\t\treturn colorChalk.bgRgb(r, g, b)(text);\n\t\t}\n\t\t// Named background color (bgRed, bgBlue, etc.)\n\t\treturn (colorChalk as any)[this.defaultTextStyle.bgColor](text);\n\t}\n\n\t/**\n\t * Apply default text style to a string.\n\t * This is the base styling applied to all text content.\n\t */\n\tprivate applyDefaultStyle(text: string): string {\n\t\tif (!this.defaultTextStyle) {\n\t\t\treturn text;\n\t\t}\n\n\t\tlet styled = text;\n\n\t\t// Apply color\n\t\tif (this.defaultTextStyle.color) {\n\t\t\tif (this.defaultTextStyle.color.startsWith(\"#\")) {\n\t\t\t\t// Hex color\n\t\t\t\tconst hex = this.defaultTextStyle.color.substring(1);\n\t\t\t\tconst r = Number.parseInt(hex.substring(0, 2), 16);\n\t\t\t\tconst g = Number.parseInt(hex.substring(2, 4), 16);\n\t\t\t\tconst b = Number.parseInt(hex.substring(4, 6), 16);\n\t\t\t\tstyled = colorChalk.rgb(r, g, b)(styled);\n\t\t\t} else {\n\t\t\t\t// Named color\n\t\t\t\tstyled = (colorChalk as any)[this.defaultTextStyle.color](styled);\n\t\t\t}\n\t\t}\n\n\t\t// Apply background color\n\t\tif (this.defaultTextStyle.bgColor) {\n\t\t\tif (this.defaultTextStyle.bgColor.startsWith(\"#\")) {\n\t\t\t\t// Hex color\n\t\t\t\tconst hex = this.defaultTextStyle.bgColor.substring(1);\n\t\t\t\tconst r = Number.parseInt(hex.substring(0, 2), 16);\n\t\t\t\tconst g = Number.parseInt(hex.substring(2, 4), 16);\n\t\t\t\tconst b = Number.parseInt(hex.substring(4, 6), 16);\n\t\t\t\tstyled = colorChalk.bgRgb(r, g, b)(styled);\n\t\t\t} else {\n\t\t\t\t// Named background color (bgRed, bgBlue, etc.)\n\t\t\t\tstyled = (colorChalk as any)[this.defaultTextStyle.bgColor](styled);\n\t\t\t}\n\t\t}\n\n\t\t// Apply text decorations\n\t\tif (this.defaultTextStyle.bold) {\n\t\t\tstyled = colorChalk.bold(styled);\n\t\t}\n\t\tif (this.defaultTextStyle.italic) {\n\t\t\tstyled = colorChalk.italic(styled);\n\t\t}\n\t\tif (this.defaultTextStyle.strikethrough) {\n\t\t\tstyled = colorChalk.strikethrough(styled);\n\t\t}\n\t\tif (this.defaultTextStyle.underline) {\n\t\t\tstyled = colorChalk.underline(styled);\n\t\t}\n\n\t\treturn styled;\n\t}\n\n\tprivate renderToken(token: Token, width: number, nextTokenType?: string): string[] {\n\t\tconst lines: string[] = [];\n\n\t\tswitch (token.type) {\n\t\t\tcase \"heading\": {\n\t\t\t\tconst headingLevel = token.depth;\n\t\t\t\tconst headingPrefix = \"#\".repeat(headingLevel) + \" \";\n\t\t\t\tconst headingText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tif (headingLevel === 1) {\n\t\t\t\t\tlines.push(colorChalk.bold.underline.yellow(headingText));\n\t\t\t\t} else if (headingLevel === 2) {\n\t\t\t\t\tlines.push(colorChalk.bold.yellow(headingText));\n\t\t\t\t} else {\n\t\t\t\t\tlines.push(colorChalk.bold(headingPrefix + headingText));\n\t\t\t\t}\n\t\t\t\tlines.push(\"\"); // Add spacing after headings\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"paragraph\": {\n\t\t\t\tconst paragraphText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tlines.push(paragraphText);\n\t\t\t\t// Don't add spacing if next token is space or list\n\t\t\t\tif (nextTokenType && nextTokenType !== \"list\" && nextTokenType !== \"space\") {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"code\": {\n\t\t\t\tlines.push(colorChalk.gray(\"```\" + (token.lang || \"\")));\n\t\t\t\t// Split code by newlines and style each line\n\t\t\t\tconst codeLines = token.text.split(\"\\n\");\n\t\t\t\tfor (const codeLine of codeLines) {\n\t\t\t\t\tlines.push(colorChalk.dim(\" \") + colorChalk.green(codeLine));\n\t\t\t\t}\n\t\t\t\tlines.push(colorChalk.gray(\"```\"));\n\t\t\t\tlines.push(\"\"); // Add spacing after code blocks\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"list\": {\n\t\t\t\tconst listLines = this.renderList(token as any, 0);\n\t\t\t\tlines.push(...listLines);\n\t\t\t\t// Don't add spacing after lists if a space token follows\n\t\t\t\t// (the space token will handle it)\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"table\": {\n\t\t\t\tconst tableLines = this.renderTable(token as any);\n\t\t\t\tlines.push(...tableLines);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"blockquote\": {\n\t\t\t\tconst quoteText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tconst quoteLines = quoteText.split(\"\\n\");\n\t\t\t\tfor (const quoteLine of quoteLines) {\n\t\t\t\t\tlines.push(colorChalk.gray(\"│ \") + colorChalk.italic(quoteLine));\n\t\t\t\t}\n\t\t\t\tlines.push(\"\"); // Add spacing after blockquotes\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"hr\":\n\t\t\t\tlines.push(colorChalk.gray(\"─\".repeat(Math.min(width, 80))));\n\t\t\t\tlines.push(\"\"); // Add spacing after horizontal rules\n\t\t\t\tbreak;\n\n\t\t\tcase \"html\":\n\t\t\t\t// Skip HTML for terminal output\n\t\t\t\tbreak;\n\n\t\t\tcase \"space\":\n\t\t\t\t// Space tokens represent blank lines in markdown\n\t\t\t\tlines.push(\"\");\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// Handle any other token types as plain text\n\t\t\t\tif (\"text\" in token && typeof token.text === \"string\") {\n\t\t\t\t\tlines.push(token.text);\n\t\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\tprivate renderInlineTokens(tokens: Token[]): string {\n\t\tlet result = \"\";\n\n\t\tfor (const token of tokens) {\n\t\t\tswitch (token.type) {\n\t\t\t\tcase \"text\":\n\t\t\t\t\t// Text tokens in list items can have nested tokens for inline formatting\n\t\t\t\t\tif (token.tokens && token.tokens.length > 0) {\n\t\t\t\t\t\tresult += this.renderInlineTokens(token.tokens);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Apply default style to plain text\n\t\t\t\t\t\tresult += this.applyDefaultStyle(token.text);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"strong\": {\n\t\t\t\t\t// Apply bold, then reapply default style after\n\t\t\t\t\tconst boldContent = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\tresult += colorChalk.bold(boldContent) + this.applyDefaultStyle(\"\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"em\": {\n\t\t\t\t\t// Apply italic, then reapply default style after\n\t\t\t\t\tconst italicContent = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\tresult += colorChalk.italic(italicContent) + this.applyDefaultStyle(\"\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"codespan\":\n\t\t\t\t\t// Apply code styling, then reapply default style after\n\t\t\t\t\tresult +=\n\t\t\t\t\t\tcolorChalk.gray(\"`\") +\n\t\t\t\t\t\tcolorChalk.cyan(token.text) +\n\t\t\t\t\t\tcolorChalk.gray(\"`\") +\n\t\t\t\t\t\tthis.applyDefaultStyle(\"\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"link\": {\n\t\t\t\t\tconst linkText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\t// If link text matches href, only show the link once\n\t\t\t\t\tif (linkText === token.href) {\n\t\t\t\t\t\tresult += colorChalk.underline.blue(linkText) + this.applyDefaultStyle(\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult +=\n\t\t\t\t\t\t\tcolorChalk.underline.blue(linkText) +\n\t\t\t\t\t\t\tcolorChalk.gray(` (${token.href})`) +\n\t\t\t\t\t\t\tthis.applyDefaultStyle(\"\");\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"br\":\n\t\t\t\t\tresult += \"\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"del\": {\n\t\t\t\t\tconst delContent = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\tresult += colorChalk.strikethrough(delContent) + this.applyDefaultStyle(\"\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\t// Handle any other inline token types as plain text\n\t\t\t\t\tif (\"text\" in token && typeof token.text === \"string\") {\n\t\t\t\t\t\tresult += this.applyDefaultStyle(token.text);\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate wrapLine(line: string, width: number): string[] {\n\t\t// Handle ANSI escape codes properly when wrapping\n\t\tconst wrapped: string[] = [];\n\n\t\t// Handle undefined or null lines\n\t\tif (!line) {\n\t\t\treturn [\"\"];\n\t\t}\n\n\t\t// Split by newlines first - wrap each line individually\n\t\tconst splitLines = line.split(\"\\n\");\n\t\tfor (const splitLine of splitLines) {\n\t\t\tconst visibleLength = visibleWidth(splitLine);\n\n\t\t\tif (visibleLength <= width) {\n\t\t\t\twrapped.push(splitLine);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// This line needs wrapping\n\t\t\twrapped.push(...this.wrapSingleLine(splitLine, width));\n\t\t}\n\n\t\treturn wrapped.length > 0 ? wrapped : [\"\"];\n\t}\n\n\tprivate wrapSingleLine(line: string, width: number): string[] {\n\t\tconst wrapped: string[] = [];\n\n\t\t// Track active ANSI codes to preserve them across wrapped lines\n\t\tconst activeAnsiCodes: string[] = [];\n\t\tlet currentLine = \"\";\n\t\tlet currentLength = 0;\n\t\tlet i = 0;\n\n\t\twhile (i < line.length) {\n\t\t\tif (line[i] === \"\\x1b\" && line[i + 1] === \"[\") {\n\t\t\t\t// ANSI escape sequence - parse and track it\n\t\t\t\tlet j = i + 2;\n\t\t\t\twhile (j < line.length && line[j] && !/[mGKHJ]/.test(line[j]!)) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (j < line.length) {\n\t\t\t\t\tconst ansiCode = line.substring(i, j + 1);\n\t\t\t\t\tcurrentLine += ansiCode;\n\n\t\t\t\t\t// Track styling codes (ending with 'm')\n\t\t\t\t\tif (line[j] === \"m\") {\n\t\t\t\t\t\t// Reset code\n\t\t\t\t\t\tif (ansiCode === \"\\x1b[0m\" || ansiCode === \"\\x1b[m\") {\n\t\t\t\t\t\t\tactiveAnsiCodes.length = 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Add to active codes (replacing similar ones)\n\t\t\t\t\t\t\tactiveAnsiCodes.push(ansiCode);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\ti = j + 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Incomplete ANSI sequence at end - don't include it\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Regular character - extract full grapheme cluster\n\t\t\t\t// Handle multi-byte characters (emoji, surrogate pairs, etc.)\n\t\t\t\tlet char: string;\n\t\t\t\tlet charByteLength: number;\n\n\t\t\t\t// Check for surrogate pair (emoji and other multi-byte chars)\n\t\t\t\tconst codePoint = line.charCodeAt(i);\n\t\t\t\tif (codePoint >= 0xd800 && codePoint <= 0xdbff && i + 1 < line.length) {\n\t\t\t\t\t// High surrogate - get the pair\n\t\t\t\t\tchar = line.substring(i, i + 2);\n\t\t\t\t\tcharByteLength = 2;\n\t\t\t\t} else {\n\t\t\t\t\t// Regular character\n\t\t\t\t\tchar = line[i];\n\t\t\t\t\tcharByteLength = 1;\n\t\t\t\t}\n\n\t\t\t\tconst charWidth = visibleWidth(char);\n\n\t\t\t\t// Check if adding this character would exceed width\n\t\t\t\tif (currentLength + charWidth > width) {\n\t\t\t\t\t// Need to wrap - close current line with reset if needed\n\t\t\t\t\tif (activeAnsiCodes.length > 0) {\n\t\t\t\t\t\twrapped.push(currentLine + \"\\x1b[0m\");\n\t\t\t\t\t\t// Start new line with active codes\n\t\t\t\t\t\tcurrentLine = activeAnsiCodes.join(\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\twrapped.push(currentLine);\n\t\t\t\t\t\tcurrentLine = \"\";\n\t\t\t\t\t}\n\t\t\t\t\tcurrentLength = 0;\n\t\t\t\t}\n\n\t\t\t\tcurrentLine += char;\n\t\t\t\tcurrentLength += charWidth;\n\t\t\t\ti += charByteLength;\n\t\t\t}\n\t\t}\n\n\t\tif (currentLine) {\n\t\t\twrapped.push(currentLine);\n\t\t}\n\n\t\treturn wrapped.length > 0 ? wrapped : [\"\"];\n\t}\n\n\t/**\n\t * Render a list with proper nesting support\n\t */\n\tprivate renderList(token: Token & { items: any[]; ordered: boolean }, depth: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst indent = \" \".repeat(depth);\n\n\t\tfor (let i = 0; i < token.items.length; i++) {\n\t\t\tconst item = token.items[i];\n\t\t\tconst bullet = token.ordered ? `${i + 1}. ` : \"- \";\n\n\t\t\t// Process item tokens to handle nested lists\n\t\t\tconst itemLines = this.renderListItem(item.tokens || [], depth);\n\n\t\t\tif (itemLines.length > 0) {\n\t\t\t\t// First line - check if it's a nested list\n\t\t\t\t// A nested list will start with indent (spaces) followed by cyan bullet\n\t\t\t\tconst firstLine = itemLines[0];\n\t\t\t\tconst isNestedList = /^\\s+\\x1b\\[36m[-\\d]/.test(firstLine); // starts with spaces + cyan + bullet char\n\n\t\t\t\tif (isNestedList) {\n\t\t\t\t\t// This is a nested list, just add it as-is (already has full indent)\n\t\t\t\t\tlines.push(firstLine);\n\t\t\t\t} else {\n\t\t\t\t\t// Regular text content - add indent and bullet\n\t\t\t\t\tlines.push(indent + colorChalk.cyan(bullet) + firstLine);\n\t\t\t\t}\n\n\t\t\t\t// Rest of the lines\n\t\t\t\tfor (let j = 1; j < itemLines.length; j++) {\n\t\t\t\t\tconst line = itemLines[j];\n\t\t\t\t\tconst isNestedListLine = /^\\s+\\x1b\\[36m[-\\d]/.test(line); // starts with spaces + cyan + bullet char\n\n\t\t\t\t\tif (isNestedListLine) {\n\t\t\t\t\t\t// Nested list line - already has full indent\n\t\t\t\t\t\tlines.push(line);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Regular content - add parent indent + 2 spaces for continuation\n\t\t\t\t\t\tlines.push(indent + \" \" + line);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlines.push(indent + colorChalk.cyan(bullet));\n\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Render list item tokens, handling nested lists\n\t * Returns lines WITHOUT the parent indent (renderList will add it)\n\t */\n\tprivate renderListItem(tokens: Token[], parentDepth: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\tfor (const token of tokens) {\n\t\t\tif (token.type === \"list\") {\n\t\t\t\t// Nested list - render with one additional indent level\n\t\t\t\t// These lines will have their own indent, so we just add them as-is\n\t\t\t\tconst nestedLines = this.renderList(token as any, parentDepth + 1);\n\t\t\t\tlines.push(...nestedLines);\n\t\t\t} else if (token.type === \"text\") {\n\t\t\t\t// Text content (may have inline tokens)\n\t\t\t\tconst text =\n\t\t\t\t\ttoken.tokens && token.tokens.length > 0 ? this.renderInlineTokens(token.tokens) : token.text || \"\";\n\t\t\t\tlines.push(text);\n\t\t\t} else if (token.type === \"paragraph\") {\n\t\t\t\t// Paragraph in list item\n\t\t\t\tconst text = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tlines.push(text);\n\t\t\t} else if (token.type === \"code\") {\n\t\t\t\t// Code block in list item\n\t\t\t\tlines.push(colorChalk.gray(\"```\" + (token.lang || \"\")));\n\t\t\t\tconst codeLines = token.text.split(\"\\n\");\n\t\t\t\tfor (const codeLine of codeLines) {\n\t\t\t\t\tlines.push(colorChalk.dim(\" \") + colorChalk.green(codeLine));\n\t\t\t\t}\n\t\t\t\tlines.push(colorChalk.gray(\"```\"));\n\t\t\t} else {\n\t\t\t\t// Other token types - try to render as inline\n\t\t\t\tconst text = this.renderInlineTokens([token]);\n\t\t\t\tif (text) {\n\t\t\t\t\tlines.push(text);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Render a table\n\t */\n\tprivate renderTable(token: Token & { header: any[]; rows: any[][] }): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Calculate column widths\n\t\tconst columnWidths: number[] = [];\n\n\t\t// Check header\n\t\tfor (let i = 0; i < token.header.length; i++) {\n\t\t\tconst headerText = this.renderInlineTokens(token.header[i].tokens || []);\n\t\t\tconst width = visibleWidth(headerText);\n\t\t\tcolumnWidths[i] = Math.max(columnWidths[i] || 0, width);\n\t\t}\n\n\t\t// Check rows\n\t\tfor (const row of token.rows) {\n\t\t\tfor (let i = 0; i < row.length; i++) {\n\t\t\t\tconst cellText = this.renderInlineTokens(row[i].tokens || []);\n\t\t\t\tconst width = visibleWidth(cellText);\n\t\t\t\tcolumnWidths[i] = Math.max(columnWidths[i] || 0, width);\n\t\t\t}\n\t\t}\n\n\t\t// Limit column widths to reasonable max\n\t\tconst maxColWidth = 40;\n\t\tfor (let i = 0; i < columnWidths.length; i++) {\n\t\t\tcolumnWidths[i] = Math.min(columnWidths[i], maxColWidth);\n\t\t}\n\n\t\t// Render header\n\t\tconst headerCells = token.header.map((cell, i) => {\n\t\t\tconst text = this.renderInlineTokens(cell.tokens || []);\n\t\t\treturn colorChalk.bold(text.padEnd(columnWidths[i]));\n\t\t});\n\t\tlines.push(\"│ \" + headerCells.join(\" │ \") + \" │\");\n\n\t\t// Render separator\n\t\tconst separatorCells = columnWidths.map((width) => \"─\".repeat(width));\n\t\tlines.push(\"├─\" + separatorCells.join(\"─┼─\") + \"─┤\");\n\n\t\t// Render rows\n\t\tfor (const row of token.rows) {\n\t\t\tconst rowCells = row.map((cell, i) => {\n\t\t\t\tconst text = this.renderInlineTokens(cell.tokens || []);\n\t\t\t\tconst visWidth = visibleWidth(text);\n\t\t\t\tconst padding = \" \".repeat(Math.max(0, columnWidths[i] - visWidth));\n\t\t\t\treturn text + padding;\n\t\t\t});\n\t\t\tlines.push(\"│ \" + rowCells.join(\" │ \") + \" │\");\n\t\t}\n\n\t\tlines.push(\"\"); // Add spacing after table\n\t\treturn lines;\n\t}\n}\n"]}
@@ -1,24 +1,22 @@
1
- import chalk from "chalk";
1
+ import { Chalk } from "chalk";
2
2
  import { marked } from "marked";
3
3
  import { visibleWidth } from "../utils.js";
4
+ // Use a chalk instance with color level 3 for consistent ANSI output
5
+ const colorChalk = new Chalk({ level: 3 });
4
6
  export class Markdown {
5
7
  text;
6
- bgColor;
7
- fgColor;
8
- customBgRgb;
9
8
  paddingX; // Left/right padding
10
9
  paddingY; // Top/bottom padding
10
+ defaultTextStyle;
11
11
  // Cache for rendered output
12
12
  cachedText;
13
13
  cachedWidth;
14
14
  cachedLines;
15
- constructor(text = "", bgColor, fgColor, customBgRgb, paddingX = 1, paddingY = 1) {
15
+ constructor(text = "", paddingX = 1, paddingY = 1, defaultTextStyle) {
16
16
  this.text = text;
17
- this.bgColor = bgColor;
18
- this.fgColor = fgColor;
19
- this.customBgRgb = customBgRgb;
20
17
  this.paddingX = paddingX;
21
18
  this.paddingY = paddingY;
19
+ this.defaultTextStyle = defaultTextStyle;
22
20
  }
23
21
  setText(text) {
24
22
  this.text = text;
@@ -27,27 +25,6 @@ export class Markdown {
27
25
  this.cachedWidth = undefined;
28
26
  this.cachedLines = undefined;
29
27
  }
30
- setBgColor(bgColor) {
31
- this.bgColor = bgColor;
32
- // Invalidate cache when color changes
33
- this.cachedText = undefined;
34
- this.cachedWidth = undefined;
35
- this.cachedLines = undefined;
36
- }
37
- setFgColor(fgColor) {
38
- this.fgColor = fgColor;
39
- // Invalidate cache when color changes
40
- this.cachedText = undefined;
41
- this.cachedWidth = undefined;
42
- this.cachedLines = undefined;
43
- }
44
- setCustomBgRgb(customBgRgb) {
45
- this.customBgRgb = customBgRgb;
46
- // Invalidate cache when color changes
47
- this.cachedText = undefined;
48
- this.cachedWidth = undefined;
49
- this.cachedLines = undefined;
50
- }
51
28
  render(width) {
52
29
  // Check cache
53
30
  if (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) {
@@ -81,7 +58,7 @@ export class Markdown {
81
58
  for (const line of renderedLines) {
82
59
  wrappedLines.push(...this.wrapLine(line, contentWidth));
83
60
  }
84
- // Add padding and apply colors
61
+ // Add padding and apply background color if specified
85
62
  const leftPad = " ".repeat(this.paddingX);
86
63
  const paddedLines = [];
87
64
  for (const line of wrappedLines) {
@@ -92,16 +69,9 @@ export class Markdown {
92
69
  const rightPad = " ".repeat(rightPadLength);
93
70
  // Add left padding, content, and right padding
94
71
  let paddedLine = leftPad + line + rightPad;
95
- // Apply foreground color if specified
96
- if (this.fgColor) {
97
- paddedLine = chalk[this.fgColor](paddedLine);
98
- }
99
- // Apply background color if specified
100
- if (this.customBgRgb) {
101
- paddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(paddedLine);
102
- }
103
- else if (this.bgColor) {
104
- paddedLine = chalk[this.bgColor](paddedLine);
72
+ // Apply background color to entire line if specified
73
+ if (this.defaultTextStyle?.bgColor) {
74
+ paddedLine = this.applyBgColor(paddedLine);
105
75
  }
106
76
  paddedLines.push(paddedLine);
107
77
  }
@@ -109,26 +79,14 @@ export class Markdown {
109
79
  const emptyLine = " ".repeat(width);
110
80
  const topPadding = [];
111
81
  for (let i = 0; i < this.paddingY; i++) {
112
- let emptyPaddedLine = emptyLine;
113
- if (this.customBgRgb) {
114
- emptyPaddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(emptyPaddedLine);
115
- }
116
- else if (this.bgColor) {
117
- emptyPaddedLine = chalk[this.bgColor](emptyPaddedLine);
118
- }
119
- topPadding.push(emptyPaddedLine);
82
+ const paddedEmptyLine = this.defaultTextStyle?.bgColor ? this.applyBgColor(emptyLine) : emptyLine;
83
+ topPadding.push(paddedEmptyLine);
120
84
  }
121
85
  // Add bottom padding (empty lines)
122
86
  const bottomPadding = [];
123
87
  for (let i = 0; i < this.paddingY; i++) {
124
- let emptyPaddedLine = emptyLine;
125
- if (this.customBgRgb) {
126
- emptyPaddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(emptyPaddedLine);
127
- }
128
- else if (this.bgColor) {
129
- emptyPaddedLine = chalk[this.bgColor](emptyPaddedLine);
130
- }
131
- bottomPadding.push(emptyPaddedLine);
88
+ const paddedEmptyLine = this.defaultTextStyle?.bgColor ? this.applyBgColor(emptyLine) : emptyLine;
89
+ bottomPadding.push(paddedEmptyLine);
132
90
  }
133
91
  // Combine top padding, content, and bottom padding
134
92
  const result = [...topPadding, ...paddedLines, ...bottomPadding];
@@ -138,6 +96,79 @@ export class Markdown {
138
96
  this.cachedLines = result;
139
97
  return result.length > 0 ? result : [""];
140
98
  }
99
+ /**
100
+ * Apply only background color from default style.
101
+ * Used for padding lines that don't have text content.
102
+ */
103
+ applyBgColor(text) {
104
+ if (!this.defaultTextStyle?.bgColor) {
105
+ return text;
106
+ }
107
+ if (this.defaultTextStyle.bgColor.startsWith("#")) {
108
+ // Hex color
109
+ const hex = this.defaultTextStyle.bgColor.substring(1);
110
+ const r = Number.parseInt(hex.substring(0, 2), 16);
111
+ const g = Number.parseInt(hex.substring(2, 4), 16);
112
+ const b = Number.parseInt(hex.substring(4, 6), 16);
113
+ return colorChalk.bgRgb(r, g, b)(text);
114
+ }
115
+ // Named background color (bgRed, bgBlue, etc.)
116
+ return colorChalk[this.defaultTextStyle.bgColor](text);
117
+ }
118
+ /**
119
+ * Apply default text style to a string.
120
+ * This is the base styling applied to all text content.
121
+ */
122
+ applyDefaultStyle(text) {
123
+ if (!this.defaultTextStyle) {
124
+ return text;
125
+ }
126
+ let styled = text;
127
+ // Apply color
128
+ if (this.defaultTextStyle.color) {
129
+ if (this.defaultTextStyle.color.startsWith("#")) {
130
+ // Hex color
131
+ const hex = this.defaultTextStyle.color.substring(1);
132
+ const r = Number.parseInt(hex.substring(0, 2), 16);
133
+ const g = Number.parseInt(hex.substring(2, 4), 16);
134
+ const b = Number.parseInt(hex.substring(4, 6), 16);
135
+ styled = colorChalk.rgb(r, g, b)(styled);
136
+ }
137
+ else {
138
+ // Named color
139
+ styled = colorChalk[this.defaultTextStyle.color](styled);
140
+ }
141
+ }
142
+ // Apply background color
143
+ if (this.defaultTextStyle.bgColor) {
144
+ if (this.defaultTextStyle.bgColor.startsWith("#")) {
145
+ // Hex color
146
+ const hex = this.defaultTextStyle.bgColor.substring(1);
147
+ const r = Number.parseInt(hex.substring(0, 2), 16);
148
+ const g = Number.parseInt(hex.substring(2, 4), 16);
149
+ const b = Number.parseInt(hex.substring(4, 6), 16);
150
+ styled = colorChalk.bgRgb(r, g, b)(styled);
151
+ }
152
+ else {
153
+ // Named background color (bgRed, bgBlue, etc.)
154
+ styled = colorChalk[this.defaultTextStyle.bgColor](styled);
155
+ }
156
+ }
157
+ // Apply text decorations
158
+ if (this.defaultTextStyle.bold) {
159
+ styled = colorChalk.bold(styled);
160
+ }
161
+ if (this.defaultTextStyle.italic) {
162
+ styled = colorChalk.italic(styled);
163
+ }
164
+ if (this.defaultTextStyle.strikethrough) {
165
+ styled = colorChalk.strikethrough(styled);
166
+ }
167
+ if (this.defaultTextStyle.underline) {
168
+ styled = colorChalk.underline(styled);
169
+ }
170
+ return styled;
171
+ }
141
172
  renderToken(token, width, nextTokenType) {
142
173
  const lines = [];
143
174
  switch (token.type) {
@@ -146,13 +177,13 @@ export class Markdown {
146
177
  const headingPrefix = "#".repeat(headingLevel) + " ";
147
178
  const headingText = this.renderInlineTokens(token.tokens || []);
148
179
  if (headingLevel === 1) {
149
- lines.push(chalk.bold.underline.yellow(headingText));
180
+ lines.push(colorChalk.bold.underline.yellow(headingText));
150
181
  }
151
182
  else if (headingLevel === 2) {
152
- lines.push(chalk.bold.yellow(headingText));
183
+ lines.push(colorChalk.bold.yellow(headingText));
153
184
  }
154
185
  else {
155
- lines.push(chalk.bold(headingPrefix + headingText));
186
+ lines.push(colorChalk.bold(headingPrefix + headingText));
156
187
  }
157
188
  lines.push(""); // Add spacing after headings
158
189
  break;
@@ -167,13 +198,13 @@ export class Markdown {
167
198
  break;
168
199
  }
169
200
  case "code": {
170
- lines.push(chalk.gray("```" + (token.lang || "")));
201
+ lines.push(colorChalk.gray("```" + (token.lang || "")));
171
202
  // Split code by newlines and style each line
172
203
  const codeLines = token.text.split("\n");
173
204
  for (const codeLine of codeLines) {
174
- lines.push(chalk.dim(" ") + chalk.green(codeLine));
205
+ lines.push(colorChalk.dim(" ") + colorChalk.green(codeLine));
175
206
  }
176
- lines.push(chalk.gray("```"));
207
+ lines.push(colorChalk.gray("```"));
177
208
  lines.push(""); // Add spacing after code blocks
178
209
  break;
179
210
  }
@@ -193,13 +224,13 @@ export class Markdown {
193
224
  const quoteText = this.renderInlineTokens(token.tokens || []);
194
225
  const quoteLines = quoteText.split("\n");
195
226
  for (const quoteLine of quoteLines) {
196
- lines.push(chalk.gray("│ ") + chalk.italic(quoteLine));
227
+ lines.push(colorChalk.gray("│ ") + colorChalk.italic(quoteLine));
197
228
  }
198
229
  lines.push(""); // Add spacing after blockquotes
199
230
  break;
200
231
  }
201
232
  case "hr":
202
- lines.push(chalk.gray("─".repeat(Math.min(width, 80))));
233
+ lines.push(colorChalk.gray("─".repeat(Math.min(width, 80))));
203
234
  lines.push(""); // Add spacing after horizontal rules
204
235
  break;
205
236
  case "html":
@@ -227,39 +258,56 @@ export class Markdown {
227
258
  result += this.renderInlineTokens(token.tokens);
228
259
  }
229
260
  else {
230
- result += token.text;
261
+ // Apply default style to plain text
262
+ result += this.applyDefaultStyle(token.text);
231
263
  }
232
264
  break;
233
- case "strong":
234
- result += chalk.bold(this.renderInlineTokens(token.tokens || []));
265
+ case "strong": {
266
+ // Apply bold, then reapply default style after
267
+ const boldContent = this.renderInlineTokens(token.tokens || []);
268
+ result += colorChalk.bold(boldContent) + this.applyDefaultStyle("");
235
269
  break;
236
- case "em":
237
- result += chalk.italic(this.renderInlineTokens(token.tokens || []));
270
+ }
271
+ case "em": {
272
+ // Apply italic, then reapply default style after
273
+ const italicContent = this.renderInlineTokens(token.tokens || []);
274
+ result += colorChalk.italic(italicContent) + this.applyDefaultStyle("");
238
275
  break;
276
+ }
239
277
  case "codespan":
240
- result += chalk.gray("`") + chalk.cyan(token.text) + chalk.gray("`");
278
+ // Apply code styling, then reapply default style after
279
+ result +=
280
+ colorChalk.gray("`") +
281
+ colorChalk.cyan(token.text) +
282
+ colorChalk.gray("`") +
283
+ this.applyDefaultStyle("");
241
284
  break;
242
285
  case "link": {
243
286
  const linkText = this.renderInlineTokens(token.tokens || []);
244
287
  // If link text matches href, only show the link once
245
288
  if (linkText === token.href) {
246
- result += chalk.underline.blue(linkText);
289
+ result += colorChalk.underline.blue(linkText) + this.applyDefaultStyle("");
247
290
  }
248
291
  else {
249
- result += chalk.underline.blue(linkText) + chalk.gray(` (${token.href})`);
292
+ result +=
293
+ colorChalk.underline.blue(linkText) +
294
+ colorChalk.gray(` (${token.href})`) +
295
+ this.applyDefaultStyle("");
250
296
  }
251
297
  break;
252
298
  }
253
299
  case "br":
254
300
  result += "\n";
255
301
  break;
256
- case "del":
257
- result += chalk.strikethrough(this.renderInlineTokens(token.tokens || []));
302
+ case "del": {
303
+ const delContent = this.renderInlineTokens(token.tokens || []);
304
+ result += colorChalk.strikethrough(delContent) + this.applyDefaultStyle("");
258
305
  break;
306
+ }
259
307
  default:
260
308
  // Handle any other inline token types as plain text
261
309
  if ("text" in token && typeof token.text === "string") {
262
- result += token.text;
310
+ result += this.applyDefaultStyle(token.text);
263
311
  }
264
312
  }
265
313
  }
@@ -384,7 +432,7 @@ export class Markdown {
384
432
  }
385
433
  else {
386
434
  // Regular text content - add indent and bullet
387
- lines.push(indent + chalk.cyan(bullet) + firstLine);
435
+ lines.push(indent + colorChalk.cyan(bullet) + firstLine);
388
436
  }
389
437
  // Rest of the lines
390
438
  for (let j = 1; j < itemLines.length; j++) {
@@ -401,7 +449,7 @@ export class Markdown {
401
449
  }
402
450
  }
403
451
  else {
404
- lines.push(indent + chalk.cyan(bullet));
452
+ lines.push(indent + colorChalk.cyan(bullet));
405
453
  }
406
454
  }
407
455
  return lines;
@@ -431,12 +479,12 @@ export class Markdown {
431
479
  }
432
480
  else if (token.type === "code") {
433
481
  // Code block in list item
434
- lines.push(chalk.gray("```" + (token.lang || "")));
482
+ lines.push(colorChalk.gray("```" + (token.lang || "")));
435
483
  const codeLines = token.text.split("\n");
436
484
  for (const codeLine of codeLines) {
437
- lines.push(chalk.dim(" ") + chalk.green(codeLine));
485
+ lines.push(colorChalk.dim(" ") + colorChalk.green(codeLine));
438
486
  }
439
- lines.push(chalk.gray("```"));
487
+ lines.push(colorChalk.gray("```"));
440
488
  }
441
489
  else {
442
490
  // Other token types - try to render as inline
@@ -477,7 +525,7 @@ export class Markdown {
477
525
  // Render header
478
526
  const headerCells = token.header.map((cell, i) => {
479
527
  const text = this.renderInlineTokens(cell.tokens || []);
480
- return chalk.bold(text.padEnd(columnWidths[i]));
528
+ return colorChalk.bold(text.padEnd(columnWidths[i]));
481
529
  });
482
530
  lines.push("│ " + headerCells.join(" │ ") + " │");
483
531
  // Render separator
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/components/markdown.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from \"chalk\";\nimport { marked, type Token } from \"marked\";\nimport type { Component } from \"../tui.js\";\nimport { visibleWidth } from \"../utils.js\";\n\ntype Color =\n\t| \"black\"\n\t| \"red\"\n\t| \"green\"\n\t| \"yellow\"\n\t| \"blue\"\n\t| \"magenta\"\n\t| \"cyan\"\n\t| \"white\"\n\t| \"gray\"\n\t| \"bgBlack\"\n\t| \"bgRed\"\n\t| \"bgGreen\"\n\t| \"bgYellow\"\n\t| \"bgBlue\"\n\t| \"bgMagenta\"\n\t| \"bgCyan\"\n\t| \"bgWhite\"\n\t| \"bgGray\";\n\nexport class Markdown implements Component {\n\tprivate text: string;\n\tprivate bgColor?: Color;\n\tprivate fgColor?: Color;\n\tprivate customBgRgb?: { r: number; g: number; b: number };\n\tprivate paddingX: number; // Left/right padding\n\tprivate paddingY: number; // Top/bottom padding\n\n\t// Cache for rendered output\n\tprivate cachedText?: string;\n\tprivate cachedWidth?: number;\n\tprivate cachedLines?: string[];\n\n\tconstructor(\n\t\ttext: string = \"\",\n\t\tbgColor?: Color,\n\t\tfgColor?: Color,\n\t\tcustomBgRgb?: { r: number; g: number; b: number },\n\t\tpaddingX: number = 1,\n\t\tpaddingY: number = 1,\n\t) {\n\t\tthis.text = text;\n\t\tthis.bgColor = bgColor;\n\t\tthis.fgColor = fgColor;\n\t\tthis.customBgRgb = customBgRgb;\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t}\n\n\tsetText(text: string): void {\n\t\tthis.text = text;\n\t\t// Invalidate cache when text changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tsetBgColor(bgColor?: Color): void {\n\t\tthis.bgColor = bgColor;\n\t\t// Invalidate cache when color changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tsetFgColor(fgColor?: Color): void {\n\t\tthis.fgColor = fgColor;\n\t\t// Invalidate cache when color changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tsetCustomBgRgb(customBgRgb?: { r: number; g: number; b: number }): void {\n\t\tthis.customBgRgb = customBgRgb;\n\t\t// Invalidate cache when color changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\t// Check cache\n\t\tif (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\t// Calculate available width for content (subtract horizontal padding)\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\n\t\t// Don't render anything if there's no actual text\n\t\tif (!this.text || this.text.trim() === \"\") {\n\t\t\tconst result: string[] = [];\n\t\t\t// Update cache\n\t\t\tthis.cachedText = this.text;\n\t\t\tthis.cachedWidth = width;\n\t\t\tthis.cachedLines = result;\n\t\t\treturn result;\n\t\t}\n\n\t\t// Replace tabs with 3 spaces for consistent rendering\n\t\tconst normalizedText = this.text.replace(/\\t/g, \" \");\n\n\t\t// Parse markdown to HTML-like tokens\n\t\tconst tokens = marked.lexer(normalizedText);\n\n\t\t// Convert tokens to styled terminal output\n\t\tconst renderedLines: string[] = [];\n\n\t\tfor (let i = 0; i < tokens.length; i++) {\n\t\t\tconst token = tokens[i];\n\t\t\tconst nextToken = tokens[i + 1];\n\t\t\tconst tokenLines = this.renderToken(token, contentWidth, nextToken?.type);\n\t\t\trenderedLines.push(...tokenLines);\n\t\t}\n\n\t\t// Wrap lines to fit content width\n\t\tconst wrappedLines: string[] = [];\n\t\tfor (const line of renderedLines) {\n\t\t\twrappedLines.push(...this.wrapLine(line, contentWidth));\n\t\t}\n\n\t\t// Add padding and apply colors\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\t\tconst paddedLines: string[] = [];\n\n\t\tfor (const line of wrappedLines) {\n\t\t\t// Calculate visible length\n\t\t\tconst visibleLength = visibleWidth(line);\n\t\t\t// Right padding to fill to width (accounting for left padding and content)\n\t\t\tconst rightPadLength = Math.max(0, width - this.paddingX - visibleLength);\n\t\t\tconst rightPad = \" \".repeat(rightPadLength);\n\n\t\t\t// Add left padding, content, and right padding\n\t\t\tlet paddedLine = leftPad + line + rightPad;\n\n\t\t\t// Apply foreground color if specified\n\t\t\tif (this.fgColor) {\n\t\t\t\tpaddedLine = (chalk as any)[this.fgColor](paddedLine);\n\t\t\t}\n\n\t\t\t// Apply background color if specified\n\t\t\tif (this.customBgRgb) {\n\t\t\t\tpaddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(paddedLine);\n\t\t\t} else if (this.bgColor) {\n\t\t\t\tpaddedLine = (chalk as any)[this.bgColor](paddedLine);\n\t\t\t}\n\n\t\t\tpaddedLines.push(paddedLine);\n\t\t}\n\n\t\t// Add top padding (empty lines)\n\t\tconst emptyLine = \" \".repeat(width);\n\t\tconst topPadding: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tlet emptyPaddedLine = emptyLine;\n\t\t\tif (this.customBgRgb) {\n\t\t\t\temptyPaddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(emptyPaddedLine);\n\t\t\t} else if (this.bgColor) {\n\t\t\t\temptyPaddedLine = (chalk as any)[this.bgColor](emptyPaddedLine);\n\t\t\t}\n\t\t\ttopPadding.push(emptyPaddedLine);\n\t\t}\n\n\t\t// Add bottom padding (empty lines)\n\t\tconst bottomPadding: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tlet emptyPaddedLine = emptyLine;\n\t\t\tif (this.customBgRgb) {\n\t\t\t\temptyPaddedLine = chalk.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(emptyPaddedLine);\n\t\t\t} else if (this.bgColor) {\n\t\t\t\temptyPaddedLine = (chalk as any)[this.bgColor](emptyPaddedLine);\n\t\t\t}\n\t\t\tbottomPadding.push(emptyPaddedLine);\n\t\t}\n\n\t\t// Combine top padding, content, and bottom padding\n\t\tconst result = [...topPadding, ...paddedLines, ...bottomPadding];\n\n\t\t// Update cache\n\t\tthis.cachedText = this.text;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedLines = result;\n\n\t\treturn result.length > 0 ? result : [\"\"];\n\t}\n\n\tprivate renderToken(token: Token, width: number, nextTokenType?: string): string[] {\n\t\tconst lines: string[] = [];\n\n\t\tswitch (token.type) {\n\t\t\tcase \"heading\": {\n\t\t\t\tconst headingLevel = token.depth;\n\t\t\t\tconst headingPrefix = \"#\".repeat(headingLevel) + \" \";\n\t\t\t\tconst headingText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tif (headingLevel === 1) {\n\t\t\t\t\tlines.push(chalk.bold.underline.yellow(headingText));\n\t\t\t\t} else if (headingLevel === 2) {\n\t\t\t\t\tlines.push(chalk.bold.yellow(headingText));\n\t\t\t\t} else {\n\t\t\t\t\tlines.push(chalk.bold(headingPrefix + headingText));\n\t\t\t\t}\n\t\t\t\tlines.push(\"\"); // Add spacing after headings\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"paragraph\": {\n\t\t\t\tconst paragraphText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tlines.push(paragraphText);\n\t\t\t\t// Don't add spacing if next token is space or list\n\t\t\t\tif (nextTokenType && nextTokenType !== \"list\" && nextTokenType !== \"space\") {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"code\": {\n\t\t\t\tlines.push(chalk.gray(\"```\" + (token.lang || \"\")));\n\t\t\t\t// Split code by newlines and style each line\n\t\t\t\tconst codeLines = token.text.split(\"\\n\");\n\t\t\t\tfor (const codeLine of codeLines) {\n\t\t\t\t\tlines.push(chalk.dim(\" \") + chalk.green(codeLine));\n\t\t\t\t}\n\t\t\t\tlines.push(chalk.gray(\"```\"));\n\t\t\t\tlines.push(\"\"); // Add spacing after code blocks\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"list\": {\n\t\t\t\tconst listLines = this.renderList(token as any, 0);\n\t\t\t\tlines.push(...listLines);\n\t\t\t\t// Don't add spacing after lists if a space token follows\n\t\t\t\t// (the space token will handle it)\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"table\": {\n\t\t\t\tconst tableLines = this.renderTable(token as any);\n\t\t\t\tlines.push(...tableLines);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"blockquote\": {\n\t\t\t\tconst quoteText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tconst quoteLines = quoteText.split(\"\\n\");\n\t\t\t\tfor (const quoteLine of quoteLines) {\n\t\t\t\t\tlines.push(chalk.gray(\"│ \") + chalk.italic(quoteLine));\n\t\t\t\t}\n\t\t\t\tlines.push(\"\"); // Add spacing after blockquotes\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"hr\":\n\t\t\t\tlines.push(chalk.gray(\"─\".repeat(Math.min(width, 80))));\n\t\t\t\tlines.push(\"\"); // Add spacing after horizontal rules\n\t\t\t\tbreak;\n\n\t\t\tcase \"html\":\n\t\t\t\t// Skip HTML for terminal output\n\t\t\t\tbreak;\n\n\t\t\tcase \"space\":\n\t\t\t\t// Space tokens represent blank lines in markdown\n\t\t\t\tlines.push(\"\");\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// Handle any other token types as plain text\n\t\t\t\tif (\"text\" in token && typeof token.text === \"string\") {\n\t\t\t\t\tlines.push(token.text);\n\t\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\tprivate renderInlineTokens(tokens: Token[]): string {\n\t\tlet result = \"\";\n\n\t\tfor (const token of tokens) {\n\t\t\tswitch (token.type) {\n\t\t\t\tcase \"text\":\n\t\t\t\t\t// Text tokens in list items can have nested tokens for inline formatting\n\t\t\t\t\tif (token.tokens && token.tokens.length > 0) {\n\t\t\t\t\t\tresult += this.renderInlineTokens(token.tokens);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += token.text;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"strong\":\n\t\t\t\t\tresult += chalk.bold(this.renderInlineTokens(token.tokens || []));\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"em\":\n\t\t\t\t\tresult += chalk.italic(this.renderInlineTokens(token.tokens || []));\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"codespan\":\n\t\t\t\t\tresult += chalk.gray(\"`\") + chalk.cyan(token.text) + chalk.gray(\"`\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"link\": {\n\t\t\t\t\tconst linkText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\t// If link text matches href, only show the link once\n\t\t\t\t\tif (linkText === token.href) {\n\t\t\t\t\t\tresult += chalk.underline.blue(linkText);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += chalk.underline.blue(linkText) + chalk.gray(` (${token.href})`);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"br\":\n\t\t\t\t\tresult += \"\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"del\":\n\t\t\t\t\tresult += chalk.strikethrough(this.renderInlineTokens(token.tokens || []));\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\t// Handle any other inline token types as plain text\n\t\t\t\t\tif (\"text\" in token && typeof token.text === \"string\") {\n\t\t\t\t\t\tresult += token.text;\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate wrapLine(line: string, width: number): string[] {\n\t\t// Handle ANSI escape codes properly when wrapping\n\t\tconst wrapped: string[] = [];\n\n\t\t// Handle undefined or null lines\n\t\tif (!line) {\n\t\t\treturn [\"\"];\n\t\t}\n\n\t\t// Split by newlines first - wrap each line individually\n\t\tconst splitLines = line.split(\"\\n\");\n\t\tfor (const splitLine of splitLines) {\n\t\t\tconst visibleLength = visibleWidth(splitLine);\n\n\t\t\tif (visibleLength <= width) {\n\t\t\t\twrapped.push(splitLine);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// This line needs wrapping\n\t\t\twrapped.push(...this.wrapSingleLine(splitLine, width));\n\t\t}\n\n\t\treturn wrapped.length > 0 ? wrapped : [\"\"];\n\t}\n\n\tprivate wrapSingleLine(line: string, width: number): string[] {\n\t\tconst wrapped: string[] = [];\n\n\t\t// Track active ANSI codes to preserve them across wrapped lines\n\t\tconst activeAnsiCodes: string[] = [];\n\t\tlet currentLine = \"\";\n\t\tlet currentLength = 0;\n\t\tlet i = 0;\n\n\t\twhile (i < line.length) {\n\t\t\tif (line[i] === \"\\x1b\" && line[i + 1] === \"[\") {\n\t\t\t\t// ANSI escape sequence - parse and track it\n\t\t\t\tlet j = i + 2;\n\t\t\t\twhile (j < line.length && line[j] && !/[mGKHJ]/.test(line[j]!)) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (j < line.length) {\n\t\t\t\t\tconst ansiCode = line.substring(i, j + 1);\n\t\t\t\t\tcurrentLine += ansiCode;\n\n\t\t\t\t\t// Track styling codes (ending with 'm')\n\t\t\t\t\tif (line[j] === \"m\") {\n\t\t\t\t\t\t// Reset code\n\t\t\t\t\t\tif (ansiCode === \"\\x1b[0m\" || ansiCode === \"\\x1b[m\") {\n\t\t\t\t\t\t\tactiveAnsiCodes.length = 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Add to active codes (replacing similar ones)\n\t\t\t\t\t\t\tactiveAnsiCodes.push(ansiCode);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\ti = j + 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Incomplete ANSI sequence at end - don't include it\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Regular character - extract full grapheme cluster\n\t\t\t\t// Handle multi-byte characters (emoji, surrogate pairs, etc.)\n\t\t\t\tlet char: string;\n\t\t\t\tlet charByteLength: number;\n\n\t\t\t\t// Check for surrogate pair (emoji and other multi-byte chars)\n\t\t\t\tconst codePoint = line.charCodeAt(i);\n\t\t\t\tif (codePoint >= 0xd800 && codePoint <= 0xdbff && i + 1 < line.length) {\n\t\t\t\t\t// High surrogate - get the pair\n\t\t\t\t\tchar = line.substring(i, i + 2);\n\t\t\t\t\tcharByteLength = 2;\n\t\t\t\t} else {\n\t\t\t\t\t// Regular character\n\t\t\t\t\tchar = line[i];\n\t\t\t\t\tcharByteLength = 1;\n\t\t\t\t}\n\n\t\t\t\tconst charWidth = visibleWidth(char);\n\n\t\t\t\t// Check if adding this character would exceed width\n\t\t\t\tif (currentLength + charWidth > width) {\n\t\t\t\t\t// Need to wrap - close current line with reset if needed\n\t\t\t\t\tif (activeAnsiCodes.length > 0) {\n\t\t\t\t\t\twrapped.push(currentLine + \"\\x1b[0m\");\n\t\t\t\t\t\t// Start new line with active codes\n\t\t\t\t\t\tcurrentLine = activeAnsiCodes.join(\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\twrapped.push(currentLine);\n\t\t\t\t\t\tcurrentLine = \"\";\n\t\t\t\t\t}\n\t\t\t\t\tcurrentLength = 0;\n\t\t\t\t}\n\n\t\t\t\tcurrentLine += char;\n\t\t\t\tcurrentLength += charWidth;\n\t\t\t\ti += charByteLength;\n\t\t\t}\n\t\t}\n\n\t\tif (currentLine) {\n\t\t\twrapped.push(currentLine);\n\t\t}\n\n\t\treturn wrapped.length > 0 ? wrapped : [\"\"];\n\t}\n\n\t/**\n\t * Render a list with proper nesting support\n\t */\n\tprivate renderList(token: Token & { items: any[]; ordered: boolean }, depth: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst indent = \" \".repeat(depth);\n\n\t\tfor (let i = 0; i < token.items.length; i++) {\n\t\t\tconst item = token.items[i];\n\t\t\tconst bullet = token.ordered ? `${i + 1}. ` : \"- \";\n\n\t\t\t// Process item tokens to handle nested lists\n\t\t\tconst itemLines = this.renderListItem(item.tokens || [], depth);\n\n\t\t\tif (itemLines.length > 0) {\n\t\t\t\t// First line - check if it's a nested list\n\t\t\t\t// A nested list will start with indent (spaces) followed by cyan bullet\n\t\t\t\tconst firstLine = itemLines[0];\n\t\t\t\tconst isNestedList = /^\\s+\\x1b\\[36m[-\\d]/.test(firstLine); // starts with spaces + cyan + bullet char\n\n\t\t\t\tif (isNestedList) {\n\t\t\t\t\t// This is a nested list, just add it as-is (already has full indent)\n\t\t\t\t\tlines.push(firstLine);\n\t\t\t\t} else {\n\t\t\t\t\t// Regular text content - add indent and bullet\n\t\t\t\t\tlines.push(indent + chalk.cyan(bullet) + firstLine);\n\t\t\t\t}\n\n\t\t\t\t// Rest of the lines\n\t\t\t\tfor (let j = 1; j < itemLines.length; j++) {\n\t\t\t\t\tconst line = itemLines[j];\n\t\t\t\t\tconst isNestedListLine = /^\\s+\\x1b\\[36m[-\\d]/.test(line); // starts with spaces + cyan + bullet char\n\n\t\t\t\t\tif (isNestedListLine) {\n\t\t\t\t\t\t// Nested list line - already has full indent\n\t\t\t\t\t\tlines.push(line);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Regular content - add parent indent + 2 spaces for continuation\n\t\t\t\t\t\tlines.push(indent + \" \" + line);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlines.push(indent + chalk.cyan(bullet));\n\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Render list item tokens, handling nested lists\n\t * Returns lines WITHOUT the parent indent (renderList will add it)\n\t */\n\tprivate renderListItem(tokens: Token[], parentDepth: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\tfor (const token of tokens) {\n\t\t\tif (token.type === \"list\") {\n\t\t\t\t// Nested list - render with one additional indent level\n\t\t\t\t// These lines will have their own indent, so we just add them as-is\n\t\t\t\tconst nestedLines = this.renderList(token as any, parentDepth + 1);\n\t\t\t\tlines.push(...nestedLines);\n\t\t\t} else if (token.type === \"text\") {\n\t\t\t\t// Text content (may have inline tokens)\n\t\t\t\tconst text =\n\t\t\t\t\ttoken.tokens && token.tokens.length > 0 ? this.renderInlineTokens(token.tokens) : token.text || \"\";\n\t\t\t\tlines.push(text);\n\t\t\t} else if (token.type === \"paragraph\") {\n\t\t\t\t// Paragraph in list item\n\t\t\t\tconst text = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tlines.push(text);\n\t\t\t} else if (token.type === \"code\") {\n\t\t\t\t// Code block in list item\n\t\t\t\tlines.push(chalk.gray(\"```\" + (token.lang || \"\")));\n\t\t\t\tconst codeLines = token.text.split(\"\\n\");\n\t\t\t\tfor (const codeLine of codeLines) {\n\t\t\t\t\tlines.push(chalk.dim(\" \") + chalk.green(codeLine));\n\t\t\t\t}\n\t\t\t\tlines.push(chalk.gray(\"```\"));\n\t\t\t} else {\n\t\t\t\t// Other token types - try to render as inline\n\t\t\t\tconst text = this.renderInlineTokens([token]);\n\t\t\t\tif (text) {\n\t\t\t\t\tlines.push(text);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Render a table\n\t */\n\tprivate renderTable(token: Token & { header: any[]; rows: any[][] }): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Calculate column widths\n\t\tconst columnWidths: number[] = [];\n\n\t\t// Check header\n\t\tfor (let i = 0; i < token.header.length; i++) {\n\t\t\tconst headerText = this.renderInlineTokens(token.header[i].tokens || []);\n\t\t\tconst width = visibleWidth(headerText);\n\t\t\tcolumnWidths[i] = Math.max(columnWidths[i] || 0, width);\n\t\t}\n\n\t\t// Check rows\n\t\tfor (const row of token.rows) {\n\t\t\tfor (let i = 0; i < row.length; i++) {\n\t\t\t\tconst cellText = this.renderInlineTokens(row[i].tokens || []);\n\t\t\t\tconst width = visibleWidth(cellText);\n\t\t\t\tcolumnWidths[i] = Math.max(columnWidths[i] || 0, width);\n\t\t\t}\n\t\t}\n\n\t\t// Limit column widths to reasonable max\n\t\tconst maxColWidth = 40;\n\t\tfor (let i = 0; i < columnWidths.length; i++) {\n\t\t\tcolumnWidths[i] = Math.min(columnWidths[i], maxColWidth);\n\t\t}\n\n\t\t// Render header\n\t\tconst headerCells = token.header.map((cell, i) => {\n\t\t\tconst text = this.renderInlineTokens(cell.tokens || []);\n\t\t\treturn chalk.bold(text.padEnd(columnWidths[i]));\n\t\t});\n\t\tlines.push(\"│ \" + headerCells.join(\" │ \") + \" │\");\n\n\t\t// Render separator\n\t\tconst separatorCells = columnWidths.map((width) => \"─\".repeat(width));\n\t\tlines.push(\"├─\" + separatorCells.join(\"─┼─\") + \"─┤\");\n\n\t\t// Render rows\n\t\tfor (const row of token.rows) {\n\t\t\tconst rowCells = row.map((cell, i) => {\n\t\t\t\tconst text = this.renderInlineTokens(cell.tokens || []);\n\t\t\t\tconst visWidth = visibleWidth(text);\n\t\t\t\tconst padding = \" \".repeat(Math.max(0, columnWidths[i] - visWidth));\n\t\t\t\treturn text + padding;\n\t\t\t});\n\t\t\tlines.push(\"│ \" + rowCells.join(\" │ \") + \" │\");\n\t\t}\n\n\t\tlines.push(\"\"); // Add spacing after table\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/components/markdown.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chalk } from \"chalk\";\nimport { marked, type Token } from \"marked\";\nimport type { Component } from \"../tui.js\";\nimport { visibleWidth } from \"../utils.js\";\n\n// Use a chalk instance with color level 3 for consistent ANSI output\nconst colorChalk = new Chalk({ level: 3 });\n\n/**\n * Default text styling for markdown content.\n * Applied to all text unless overridden by markdown formatting.\n */\nexport interface DefaultTextStyle {\n\t/** Foreground color - named color or hex string like \"#ff0000\" */\n\tcolor?: string;\n\t/** Background color - named color or hex string like \"#ff0000\" */\n\tbgColor?: string;\n\t/** Bold text */\n\tbold?: boolean;\n\t/** Italic text */\n\titalic?: boolean;\n\t/** Strikethrough text */\n\tstrikethrough?: boolean;\n\t/** Underline text */\n\tunderline?: boolean;\n}\n\nexport class Markdown implements Component {\n\tprivate text: string;\n\tprivate paddingX: number; // Left/right padding\n\tprivate paddingY: number; // Top/bottom padding\n\tprivate defaultTextStyle?: DefaultTextStyle;\n\n\t// Cache for rendered output\n\tprivate cachedText?: string;\n\tprivate cachedWidth?: number;\n\tprivate cachedLines?: string[];\n\n\tconstructor(text: string = \"\", paddingX: number = 1, paddingY: number = 1, defaultTextStyle?: DefaultTextStyle) {\n\t\tthis.text = text;\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.defaultTextStyle = defaultTextStyle;\n\t}\n\n\tsetText(text: string): void {\n\t\tthis.text = text;\n\t\t// Invalidate cache when text changes\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\t// Check cache\n\t\tif (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\t// Calculate available width for content (subtract horizontal padding)\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\n\t\t// Don't render anything if there's no actual text\n\t\tif (!this.text || this.text.trim() === \"\") {\n\t\t\tconst result: string[] = [];\n\t\t\t// Update cache\n\t\t\tthis.cachedText = this.text;\n\t\t\tthis.cachedWidth = width;\n\t\t\tthis.cachedLines = result;\n\t\t\treturn result;\n\t\t}\n\n\t\t// Replace tabs with 3 spaces for consistent rendering\n\t\tconst normalizedText = this.text.replace(/\\t/g, \" \");\n\n\t\t// Parse markdown to HTML-like tokens\n\t\tconst tokens = marked.lexer(normalizedText);\n\n\t\t// Convert tokens to styled terminal output\n\t\tconst renderedLines: string[] = [];\n\n\t\tfor (let i = 0; i < tokens.length; i++) {\n\t\t\tconst token = tokens[i];\n\t\t\tconst nextToken = tokens[i + 1];\n\t\t\tconst tokenLines = this.renderToken(token, contentWidth, nextToken?.type);\n\t\t\trenderedLines.push(...tokenLines);\n\t\t}\n\n\t\t// Wrap lines to fit content width\n\t\tconst wrappedLines: string[] = [];\n\t\tfor (const line of renderedLines) {\n\t\t\twrappedLines.push(...this.wrapLine(line, contentWidth));\n\t\t}\n\n\t\t// Add padding and apply background color if specified\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\t\tconst paddedLines: string[] = [];\n\n\t\tfor (const line of wrappedLines) {\n\t\t\t// Calculate visible length\n\t\t\tconst visibleLength = visibleWidth(line);\n\t\t\t// Right padding to fill to width (accounting for left padding and content)\n\t\t\tconst rightPadLength = Math.max(0, width - this.paddingX - visibleLength);\n\t\t\tconst rightPad = \" \".repeat(rightPadLength);\n\n\t\t\t// Add left padding, content, and right padding\n\t\t\tlet paddedLine = leftPad + line + rightPad;\n\n\t\t\t// Apply background color to entire line if specified\n\t\t\tif (this.defaultTextStyle?.bgColor) {\n\t\t\t\tpaddedLine = this.applyBgColor(paddedLine);\n\t\t\t}\n\n\t\t\tpaddedLines.push(paddedLine);\n\t\t}\n\n\t\t// Add top padding (empty lines)\n\t\tconst emptyLine = \" \".repeat(width);\n\t\tconst topPadding: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tconst paddedEmptyLine = this.defaultTextStyle?.bgColor ? this.applyBgColor(emptyLine) : emptyLine;\n\t\t\ttopPadding.push(paddedEmptyLine);\n\t\t}\n\n\t\t// Add bottom padding (empty lines)\n\t\tconst bottomPadding: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tconst paddedEmptyLine = this.defaultTextStyle?.bgColor ? this.applyBgColor(emptyLine) : emptyLine;\n\t\t\tbottomPadding.push(paddedEmptyLine);\n\t\t}\n\n\t\t// Combine top padding, content, and bottom padding\n\t\tconst result = [...topPadding, ...paddedLines, ...bottomPadding];\n\n\t\t// Update cache\n\t\tthis.cachedText = this.text;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedLines = result;\n\n\t\treturn result.length > 0 ? result : [\"\"];\n\t}\n\n\t/**\n\t * Apply only background color from default style.\n\t * Used for padding lines that don't have text content.\n\t */\n\tprivate applyBgColor(text: string): string {\n\t\tif (!this.defaultTextStyle?.bgColor) {\n\t\t\treturn text;\n\t\t}\n\n\t\tif (this.defaultTextStyle.bgColor.startsWith(\"#\")) {\n\t\t\t// Hex color\n\t\t\tconst hex = this.defaultTextStyle.bgColor.substring(1);\n\t\t\tconst r = Number.parseInt(hex.substring(0, 2), 16);\n\t\t\tconst g = Number.parseInt(hex.substring(2, 4), 16);\n\t\t\tconst b = Number.parseInt(hex.substring(4, 6), 16);\n\t\t\treturn colorChalk.bgRgb(r, g, b)(text);\n\t\t}\n\t\t// Named background color (bgRed, bgBlue, etc.)\n\t\treturn (colorChalk as any)[this.defaultTextStyle.bgColor](text);\n\t}\n\n\t/**\n\t * Apply default text style to a string.\n\t * This is the base styling applied to all text content.\n\t */\n\tprivate applyDefaultStyle(text: string): string {\n\t\tif (!this.defaultTextStyle) {\n\t\t\treturn text;\n\t\t}\n\n\t\tlet styled = text;\n\n\t\t// Apply color\n\t\tif (this.defaultTextStyle.color) {\n\t\t\tif (this.defaultTextStyle.color.startsWith(\"#\")) {\n\t\t\t\t// Hex color\n\t\t\t\tconst hex = this.defaultTextStyle.color.substring(1);\n\t\t\t\tconst r = Number.parseInt(hex.substring(0, 2), 16);\n\t\t\t\tconst g = Number.parseInt(hex.substring(2, 4), 16);\n\t\t\t\tconst b = Number.parseInt(hex.substring(4, 6), 16);\n\t\t\t\tstyled = colorChalk.rgb(r, g, b)(styled);\n\t\t\t} else {\n\t\t\t\t// Named color\n\t\t\t\tstyled = (colorChalk as any)[this.defaultTextStyle.color](styled);\n\t\t\t}\n\t\t}\n\n\t\t// Apply background color\n\t\tif (this.defaultTextStyle.bgColor) {\n\t\t\tif (this.defaultTextStyle.bgColor.startsWith(\"#\")) {\n\t\t\t\t// Hex color\n\t\t\t\tconst hex = this.defaultTextStyle.bgColor.substring(1);\n\t\t\t\tconst r = Number.parseInt(hex.substring(0, 2), 16);\n\t\t\t\tconst g = Number.parseInt(hex.substring(2, 4), 16);\n\t\t\t\tconst b = Number.parseInt(hex.substring(4, 6), 16);\n\t\t\t\tstyled = colorChalk.bgRgb(r, g, b)(styled);\n\t\t\t} else {\n\t\t\t\t// Named background color (bgRed, bgBlue, etc.)\n\t\t\t\tstyled = (colorChalk as any)[this.defaultTextStyle.bgColor](styled);\n\t\t\t}\n\t\t}\n\n\t\t// Apply text decorations\n\t\tif (this.defaultTextStyle.bold) {\n\t\t\tstyled = colorChalk.bold(styled);\n\t\t}\n\t\tif (this.defaultTextStyle.italic) {\n\t\t\tstyled = colorChalk.italic(styled);\n\t\t}\n\t\tif (this.defaultTextStyle.strikethrough) {\n\t\t\tstyled = colorChalk.strikethrough(styled);\n\t\t}\n\t\tif (this.defaultTextStyle.underline) {\n\t\t\tstyled = colorChalk.underline(styled);\n\t\t}\n\n\t\treturn styled;\n\t}\n\n\tprivate renderToken(token: Token, width: number, nextTokenType?: string): string[] {\n\t\tconst lines: string[] = [];\n\n\t\tswitch (token.type) {\n\t\t\tcase \"heading\": {\n\t\t\t\tconst headingLevel = token.depth;\n\t\t\t\tconst headingPrefix = \"#\".repeat(headingLevel) + \" \";\n\t\t\t\tconst headingText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tif (headingLevel === 1) {\n\t\t\t\t\tlines.push(colorChalk.bold.underline.yellow(headingText));\n\t\t\t\t} else if (headingLevel === 2) {\n\t\t\t\t\tlines.push(colorChalk.bold.yellow(headingText));\n\t\t\t\t} else {\n\t\t\t\t\tlines.push(colorChalk.bold(headingPrefix + headingText));\n\t\t\t\t}\n\t\t\t\tlines.push(\"\"); // Add spacing after headings\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"paragraph\": {\n\t\t\t\tconst paragraphText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tlines.push(paragraphText);\n\t\t\t\t// Don't add spacing if next token is space or list\n\t\t\t\tif (nextTokenType && nextTokenType !== \"list\" && nextTokenType !== \"space\") {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"code\": {\n\t\t\t\tlines.push(colorChalk.gray(\"```\" + (token.lang || \"\")));\n\t\t\t\t// Split code by newlines and style each line\n\t\t\t\tconst codeLines = token.text.split(\"\\n\");\n\t\t\t\tfor (const codeLine of codeLines) {\n\t\t\t\t\tlines.push(colorChalk.dim(\" \") + colorChalk.green(codeLine));\n\t\t\t\t}\n\t\t\t\tlines.push(colorChalk.gray(\"```\"));\n\t\t\t\tlines.push(\"\"); // Add spacing after code blocks\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"list\": {\n\t\t\t\tconst listLines = this.renderList(token as any, 0);\n\t\t\t\tlines.push(...listLines);\n\t\t\t\t// Don't add spacing after lists if a space token follows\n\t\t\t\t// (the space token will handle it)\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"table\": {\n\t\t\t\tconst tableLines = this.renderTable(token as any);\n\t\t\t\tlines.push(...tableLines);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"blockquote\": {\n\t\t\t\tconst quoteText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tconst quoteLines = quoteText.split(\"\\n\");\n\t\t\t\tfor (const quoteLine of quoteLines) {\n\t\t\t\t\tlines.push(colorChalk.gray(\"│ \") + colorChalk.italic(quoteLine));\n\t\t\t\t}\n\t\t\t\tlines.push(\"\"); // Add spacing after blockquotes\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"hr\":\n\t\t\t\tlines.push(colorChalk.gray(\"─\".repeat(Math.min(width, 80))));\n\t\t\t\tlines.push(\"\"); // Add spacing after horizontal rules\n\t\t\t\tbreak;\n\n\t\t\tcase \"html\":\n\t\t\t\t// Skip HTML for terminal output\n\t\t\t\tbreak;\n\n\t\t\tcase \"space\":\n\t\t\t\t// Space tokens represent blank lines in markdown\n\t\t\t\tlines.push(\"\");\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// Handle any other token types as plain text\n\t\t\t\tif (\"text\" in token && typeof token.text === \"string\") {\n\t\t\t\t\tlines.push(token.text);\n\t\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\tprivate renderInlineTokens(tokens: Token[]): string {\n\t\tlet result = \"\";\n\n\t\tfor (const token of tokens) {\n\t\t\tswitch (token.type) {\n\t\t\t\tcase \"text\":\n\t\t\t\t\t// Text tokens in list items can have nested tokens for inline formatting\n\t\t\t\t\tif (token.tokens && token.tokens.length > 0) {\n\t\t\t\t\t\tresult += this.renderInlineTokens(token.tokens);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Apply default style to plain text\n\t\t\t\t\t\tresult += this.applyDefaultStyle(token.text);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"strong\": {\n\t\t\t\t\t// Apply bold, then reapply default style after\n\t\t\t\t\tconst boldContent = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\tresult += colorChalk.bold(boldContent) + this.applyDefaultStyle(\"\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"em\": {\n\t\t\t\t\t// Apply italic, then reapply default style after\n\t\t\t\t\tconst italicContent = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\tresult += colorChalk.italic(italicContent) + this.applyDefaultStyle(\"\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"codespan\":\n\t\t\t\t\t// Apply code styling, then reapply default style after\n\t\t\t\t\tresult +=\n\t\t\t\t\t\tcolorChalk.gray(\"`\") +\n\t\t\t\t\t\tcolorChalk.cyan(token.text) +\n\t\t\t\t\t\tcolorChalk.gray(\"`\") +\n\t\t\t\t\t\tthis.applyDefaultStyle(\"\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"link\": {\n\t\t\t\t\tconst linkText = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\t// If link text matches href, only show the link once\n\t\t\t\t\tif (linkText === token.href) {\n\t\t\t\t\t\tresult += colorChalk.underline.blue(linkText) + this.applyDefaultStyle(\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult +=\n\t\t\t\t\t\t\tcolorChalk.underline.blue(linkText) +\n\t\t\t\t\t\t\tcolorChalk.gray(` (${token.href})`) +\n\t\t\t\t\t\t\tthis.applyDefaultStyle(\"\");\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"br\":\n\t\t\t\t\tresult += \"\\n\";\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"del\": {\n\t\t\t\t\tconst delContent = this.renderInlineTokens(token.tokens || []);\n\t\t\t\t\tresult += colorChalk.strikethrough(delContent) + this.applyDefaultStyle(\"\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\t// Handle any other inline token types as plain text\n\t\t\t\t\tif (\"text\" in token && typeof token.text === \"string\") {\n\t\t\t\t\t\tresult += this.applyDefaultStyle(token.text);\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate wrapLine(line: string, width: number): string[] {\n\t\t// Handle ANSI escape codes properly when wrapping\n\t\tconst wrapped: string[] = [];\n\n\t\t// Handle undefined or null lines\n\t\tif (!line) {\n\t\t\treturn [\"\"];\n\t\t}\n\n\t\t// Split by newlines first - wrap each line individually\n\t\tconst splitLines = line.split(\"\\n\");\n\t\tfor (const splitLine of splitLines) {\n\t\t\tconst visibleLength = visibleWidth(splitLine);\n\n\t\t\tif (visibleLength <= width) {\n\t\t\t\twrapped.push(splitLine);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// This line needs wrapping\n\t\t\twrapped.push(...this.wrapSingleLine(splitLine, width));\n\t\t}\n\n\t\treturn wrapped.length > 0 ? wrapped : [\"\"];\n\t}\n\n\tprivate wrapSingleLine(line: string, width: number): string[] {\n\t\tconst wrapped: string[] = [];\n\n\t\t// Track active ANSI codes to preserve them across wrapped lines\n\t\tconst activeAnsiCodes: string[] = [];\n\t\tlet currentLine = \"\";\n\t\tlet currentLength = 0;\n\t\tlet i = 0;\n\n\t\twhile (i < line.length) {\n\t\t\tif (line[i] === \"\\x1b\" && line[i + 1] === \"[\") {\n\t\t\t\t// ANSI escape sequence - parse and track it\n\t\t\t\tlet j = i + 2;\n\t\t\t\twhile (j < line.length && line[j] && !/[mGKHJ]/.test(line[j]!)) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (j < line.length) {\n\t\t\t\t\tconst ansiCode = line.substring(i, j + 1);\n\t\t\t\t\tcurrentLine += ansiCode;\n\n\t\t\t\t\t// Track styling codes (ending with 'm')\n\t\t\t\t\tif (line[j] === \"m\") {\n\t\t\t\t\t\t// Reset code\n\t\t\t\t\t\tif (ansiCode === \"\\x1b[0m\" || ansiCode === \"\\x1b[m\") {\n\t\t\t\t\t\t\tactiveAnsiCodes.length = 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Add to active codes (replacing similar ones)\n\t\t\t\t\t\t\tactiveAnsiCodes.push(ansiCode);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\ti = j + 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Incomplete ANSI sequence at end - don't include it\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Regular character - extract full grapheme cluster\n\t\t\t\t// Handle multi-byte characters (emoji, surrogate pairs, etc.)\n\t\t\t\tlet char: string;\n\t\t\t\tlet charByteLength: number;\n\n\t\t\t\t// Check for surrogate pair (emoji and other multi-byte chars)\n\t\t\t\tconst codePoint = line.charCodeAt(i);\n\t\t\t\tif (codePoint >= 0xd800 && codePoint <= 0xdbff && i + 1 < line.length) {\n\t\t\t\t\t// High surrogate - get the pair\n\t\t\t\t\tchar = line.substring(i, i + 2);\n\t\t\t\t\tcharByteLength = 2;\n\t\t\t\t} else {\n\t\t\t\t\t// Regular character\n\t\t\t\t\tchar = line[i];\n\t\t\t\t\tcharByteLength = 1;\n\t\t\t\t}\n\n\t\t\t\tconst charWidth = visibleWidth(char);\n\n\t\t\t\t// Check if adding this character would exceed width\n\t\t\t\tif (currentLength + charWidth > width) {\n\t\t\t\t\t// Need to wrap - close current line with reset if needed\n\t\t\t\t\tif (activeAnsiCodes.length > 0) {\n\t\t\t\t\t\twrapped.push(currentLine + \"\\x1b[0m\");\n\t\t\t\t\t\t// Start new line with active codes\n\t\t\t\t\t\tcurrentLine = activeAnsiCodes.join(\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\twrapped.push(currentLine);\n\t\t\t\t\t\tcurrentLine = \"\";\n\t\t\t\t\t}\n\t\t\t\t\tcurrentLength = 0;\n\t\t\t\t}\n\n\t\t\t\tcurrentLine += char;\n\t\t\t\tcurrentLength += charWidth;\n\t\t\t\ti += charByteLength;\n\t\t\t}\n\t\t}\n\n\t\tif (currentLine) {\n\t\t\twrapped.push(currentLine);\n\t\t}\n\n\t\treturn wrapped.length > 0 ? wrapped : [\"\"];\n\t}\n\n\t/**\n\t * Render a list with proper nesting support\n\t */\n\tprivate renderList(token: Token & { items: any[]; ordered: boolean }, depth: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst indent = \" \".repeat(depth);\n\n\t\tfor (let i = 0; i < token.items.length; i++) {\n\t\t\tconst item = token.items[i];\n\t\t\tconst bullet = token.ordered ? `${i + 1}. ` : \"- \";\n\n\t\t\t// Process item tokens to handle nested lists\n\t\t\tconst itemLines = this.renderListItem(item.tokens || [], depth);\n\n\t\t\tif (itemLines.length > 0) {\n\t\t\t\t// First line - check if it's a nested list\n\t\t\t\t// A nested list will start with indent (spaces) followed by cyan bullet\n\t\t\t\tconst firstLine = itemLines[0];\n\t\t\t\tconst isNestedList = /^\\s+\\x1b\\[36m[-\\d]/.test(firstLine); // starts with spaces + cyan + bullet char\n\n\t\t\t\tif (isNestedList) {\n\t\t\t\t\t// This is a nested list, just add it as-is (already has full indent)\n\t\t\t\t\tlines.push(firstLine);\n\t\t\t\t} else {\n\t\t\t\t\t// Regular text content - add indent and bullet\n\t\t\t\t\tlines.push(indent + colorChalk.cyan(bullet) + firstLine);\n\t\t\t\t}\n\n\t\t\t\t// Rest of the lines\n\t\t\t\tfor (let j = 1; j < itemLines.length; j++) {\n\t\t\t\t\tconst line = itemLines[j];\n\t\t\t\t\tconst isNestedListLine = /^\\s+\\x1b\\[36m[-\\d]/.test(line); // starts with spaces + cyan + bullet char\n\n\t\t\t\t\tif (isNestedListLine) {\n\t\t\t\t\t\t// Nested list line - already has full indent\n\t\t\t\t\t\tlines.push(line);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Regular content - add parent indent + 2 spaces for continuation\n\t\t\t\t\t\tlines.push(indent + \" \" + line);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlines.push(indent + colorChalk.cyan(bullet));\n\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Render list item tokens, handling nested lists\n\t * Returns lines WITHOUT the parent indent (renderList will add it)\n\t */\n\tprivate renderListItem(tokens: Token[], parentDepth: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\tfor (const token of tokens) {\n\t\t\tif (token.type === \"list\") {\n\t\t\t\t// Nested list - render with one additional indent level\n\t\t\t\t// These lines will have their own indent, so we just add them as-is\n\t\t\t\tconst nestedLines = this.renderList(token as any, parentDepth + 1);\n\t\t\t\tlines.push(...nestedLines);\n\t\t\t} else if (token.type === \"text\") {\n\t\t\t\t// Text content (may have inline tokens)\n\t\t\t\tconst text =\n\t\t\t\t\ttoken.tokens && token.tokens.length > 0 ? this.renderInlineTokens(token.tokens) : token.text || \"\";\n\t\t\t\tlines.push(text);\n\t\t\t} else if (token.type === \"paragraph\") {\n\t\t\t\t// Paragraph in list item\n\t\t\t\tconst text = this.renderInlineTokens(token.tokens || []);\n\t\t\t\tlines.push(text);\n\t\t\t} else if (token.type === \"code\") {\n\t\t\t\t// Code block in list item\n\t\t\t\tlines.push(colorChalk.gray(\"```\" + (token.lang || \"\")));\n\t\t\t\tconst codeLines = token.text.split(\"\\n\");\n\t\t\t\tfor (const codeLine of codeLines) {\n\t\t\t\t\tlines.push(colorChalk.dim(\" \") + colorChalk.green(codeLine));\n\t\t\t\t}\n\t\t\t\tlines.push(colorChalk.gray(\"```\"));\n\t\t\t} else {\n\t\t\t\t// Other token types - try to render as inline\n\t\t\t\tconst text = this.renderInlineTokens([token]);\n\t\t\t\tif (text) {\n\t\t\t\t\tlines.push(text);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Render a table\n\t */\n\tprivate renderTable(token: Token & { header: any[]; rows: any[][] }): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Calculate column widths\n\t\tconst columnWidths: number[] = [];\n\n\t\t// Check header\n\t\tfor (let i = 0; i < token.header.length; i++) {\n\t\t\tconst headerText = this.renderInlineTokens(token.header[i].tokens || []);\n\t\t\tconst width = visibleWidth(headerText);\n\t\t\tcolumnWidths[i] = Math.max(columnWidths[i] || 0, width);\n\t\t}\n\n\t\t// Check rows\n\t\tfor (const row of token.rows) {\n\t\t\tfor (let i = 0; i < row.length; i++) {\n\t\t\t\tconst cellText = this.renderInlineTokens(row[i].tokens || []);\n\t\t\t\tconst width = visibleWidth(cellText);\n\t\t\t\tcolumnWidths[i] = Math.max(columnWidths[i] || 0, width);\n\t\t\t}\n\t\t}\n\n\t\t// Limit column widths to reasonable max\n\t\tconst maxColWidth = 40;\n\t\tfor (let i = 0; i < columnWidths.length; i++) {\n\t\t\tcolumnWidths[i] = Math.min(columnWidths[i], maxColWidth);\n\t\t}\n\n\t\t// Render header\n\t\tconst headerCells = token.header.map((cell, i) => {\n\t\t\tconst text = this.renderInlineTokens(cell.tokens || []);\n\t\t\treturn colorChalk.bold(text.padEnd(columnWidths[i]));\n\t\t});\n\t\tlines.push(\"│ \" + headerCells.join(\" │ \") + \" │\");\n\n\t\t// Render separator\n\t\tconst separatorCells = columnWidths.map((width) => \"─\".repeat(width));\n\t\tlines.push(\"├─\" + separatorCells.join(\"─┼─\") + \"─┤\");\n\n\t\t// Render rows\n\t\tfor (const row of token.rows) {\n\t\t\tconst rowCells = row.map((cell, i) => {\n\t\t\t\tconst text = this.renderInlineTokens(cell.tokens || []);\n\t\t\t\tconst visWidth = visibleWidth(text);\n\t\t\t\tconst padding = \" \".repeat(Math.max(0, columnWidths[i] - visWidth));\n\t\t\t\treturn text + padding;\n\t\t\t});\n\t\t\tlines.push(\"│ \" + rowCells.join(\" │ \") + \" │\");\n\t\t}\n\n\t\tlines.push(\"\"); // Add spacing after table\n\t\treturn lines;\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mariozechner/pi-tui",
3
- "version": "0.7.17",
3
+ "version": "0.7.18",
4
4
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",