MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / renderTable

Method renderTable

packages/pi-tui/src/components/markdown.ts:685–857  ·  view source on GitHub ↗

* Render a table with width-aware cell wrapping. * Cells that don't fit are wrapped to multiple lines.

(
		token: Tokens.Table,
		availableWidth: number,
		nextTokenType?: string,
		styleContext?: InlineStyleContext,
	)

Source from the content-addressed store, hash-verified

683 * Cells that don't fit are wrapped to multiple lines.
684 */
685 private renderTable(
686 token: Tokens.Table,
687 availableWidth: number,
688 nextTokenType?: string,
689 styleContext?: InlineStyleContext,
690 ): string[] {
691 const lines: string[] = [];
692 const numCols = token.header.length;
693
694 if (numCols === 0) {
695 return lines;
696 }
697
698 // Calculate border overhead: "│ " + (n-1) * " │ " + " │"
699 // = 2 + (n-1) * 3 + 2 = 3n + 1
700 const borderOverhead = 3 * numCols + 1;
701 const availableForCells = availableWidth - borderOverhead;
702 if (availableForCells < numCols) {
703 // Too narrow to render a stable table. Fall back to raw markdown.
704 const fallbackLines = token.raw ? wrapTextWithAnsi(token.raw, availableWidth) : [];
705 if (nextTokenType && nextTokenType !== "space") {
706 fallbackLines.push("");
707 }
708 return fallbackLines;
709 }
710
711 const maxUnbrokenWordWidth = 30;
712
713 // Calculate natural column widths (what each column needs without constraints)
714 const naturalWidths: number[] = [];
715 const minWordWidths: number[] = [];
716 for (let i = 0; i < numCols; i++) {
717 const headerText = this.renderInlineTokens(token.header[i]!.tokens || [], styleContext);
718 naturalWidths[i] = visibleWidth(headerText);
719 minWordWidths[i] = Math.max(1, this.getLongestWordWidth(headerText, maxUnbrokenWordWidth));
720 }
721 for (const row of token.rows) {
722 for (let i = 0; i < row.length; i++) {
723 const cellText = this.renderInlineTokens(row[i]!.tokens || [], styleContext);
724 naturalWidths[i] = Math.max(naturalWidths[i] || 0, visibleWidth(cellText));
725 minWordWidths[i] = Math.max(
726 minWordWidths[i] || 1,
727 this.getLongestWordWidth(cellText, maxUnbrokenWordWidth),
728 );
729 }
730 }
731
732 let minColumnWidths = minWordWidths;
733 let minCellsWidth = minColumnWidths.reduce((a, b) => a + b, 0);
734
735 if (minCellsWidth > availableForCells) {
736 minColumnWidths = new Array(numCols).fill(1);
737 const remaining = availableForCells - numCols;
738
739 if (remaining > 0) {
740 const totalWeight = minWordWidths.reduce((total, width) => total + Math.max(0, width - 1), 0);
741 const growth = minWordWidths.map((width) => {
742 const weight = Math.max(0, width - 1);

Callers 1

renderTokenMethod · 0.95

Calls 7

renderInlineTokensMethod · 0.95
getLongestWordWidthMethod · 0.95
wrapCellTextMethod · 0.95
wrapTextWithAnsiFunction · 0.90
visibleWidthFunction · 0.90
boldMethod · 0.80
pushMethod · 0.45

Tested by

no test coverage detected