UNPKG

@nanocollective/nanocoder

Version:

A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter

93 lines 3.82 kB
import chalk from 'chalk'; import Table from 'cli-table3'; import { DEFAULT_TERMINAL_WIDTH, TABLE_COLUMN_MIN_WIDTH } from '../constants.js'; import { stripMarkdown } from './utils.js'; // Parse markdown tables using cli-table3 export function parseMarkdownTable(tableText, themeColors, width) { const lines = tableText.trim().split('\n'); if (lines.length < 2) return tableText; // Extract rows const rows = lines.map(line => line .split('|') .map(cell => cell.trim()) .filter(cell => cell.length > 0)); // Check if second row is separator (e.g., |---|---|) const separatorRow = rows[1]; const isSeparator = separatorRow?.every(cell => /^:?-+:?$/.test(cell)); if (!isSeparator || rows.length < 3) return tableText; // Helper to clean cell content - remove all markdown and HTML const cleanCell = (text) => { let result = text; // Remove inline code backticks (extract the content) result = result.replace(/`([^`]+)`/g, '$1'); // Remove HTML tags result = result.replace(/<[^>]+>/g, ''); // Strip markdown formatting (bold, italic, links) result = stripMarkdown(result); return result.trim(); }; // Extract header and data rows - clean all content const header = rows[0].map(cell => cleanCell(cell)); const dataRows = rows.slice(2).map(row => row.map(cell => cleanCell(cell))); // Calculate widths from cleaned content const headerWidths = header.map(cell => cell.length); const dataWidths = dataRows.map(row => row.map(cell => cell.length)); // Calculate column widths properly const terminalWidth = width || process.stdout.columns || DEFAULT_TERMINAL_WIDTH; const numCols = header.length; // Get max content width for each column const contentWidths = headerWidths.map((headerWidth, colIdx) => { let maxWidth = headerWidth; for (const rowWidths of dataWidths) { if (rowWidths[colIdx]) { maxWidth = Math.max(maxWidth, rowWidths[colIdx]); } } return maxWidth; }); // Calculate available width (accounting for borders and padding) const borderWidth = numCols + 1; // vertical bars const paddingWidth = numCols * 2; // 1 space on each side of each column const availableWidth = terminalWidth - borderWidth - paddingWidth; // Distribute width proportionally const totalContentWidth = contentWidths.reduce((a, b) => a + b, 0); const colWidths = contentWidths.map(width => Math.max(TABLE_COLUMN_MIN_WIDTH, Math.floor((width / totalContentWidth) * availableWidth))); // Create table with cli-table3 - full borders, proper alignment const table = new Table({ head: header.map(cell => chalk.hex(themeColors.primary).bold(cell)), colWidths: colWidths, style: { head: [], // Don't apply default styles, we're using chalk border: ['gray'], // Subtle border color 'padding-left': 1, 'padding-right': 1, }, chars: { top: '─', 'top-mid': '┬', 'top-left': '┌', 'top-right': '┐', bottom: '─', 'bottom-mid': '┴', 'bottom-left': '└', 'bottom-right': '┘', left: '│', 'left-mid': '├', mid: '─', 'mid-mid': '┼', right: '│', 'right-mid': '┤', middle: '│', }, wordWrap: true, wrapOnWordBoundary: true, }); // Add data rows - don't style them, let cli-table3 handle layout for (const row of dataRows) { table.push(row); } return table.toString(); } //# sourceMappingURL=table-parser.js.map