Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 1x 1x 1x 1x 3x 9x 9x 9x 9x 9x 9x 9x 9x 9x 3x 1x 1x 1x 1x 3x 3x 1x 1x 12x 12x 12x 12x 12x 12x 12x 12x 12x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | type CellFormatter = (str: string, rowIndex: number, colIndex: number) => any export interface AlignedTextTableOptions { alignRight?: boolean maxCharactersPerColumn?: number maxCharactersPerLine?: number } // Output a pretty table for consles export const toAlignedTextTable = ( headerSlugs: string[], rows: any[], options: AlignedTextTableOptions = {} ): string => { const { alignRight = true, maxCharactersPerColumn = 20, maxCharactersPerLine = 80, } = options // Set initial column widths const colWidths = headerSlugs.map((slug) => slug.length > maxCharactersPerColumn ? maxCharactersPerColumn : slug.length ) // Expand column widths if needed rows.forEach((row) => { headerSlugs.forEach((slug, index) => { const cellValue = row[slug] if (!cellValue) return const length = cellValue.toString().length if (length > colWidths[index]) colWidths[index] = length > maxCharactersPerColumn ? maxCharactersPerColumn : length }) }) // Drop columns if they exceed the max line width let runningWidth = 0 const finalHeaderSlugs = headerSlugs.filter((slug, index) => { runningWidth = runningWidth + colWidths[index] if (runningWidth <= maxCharactersPerLine) return true return false }) const cellFn = (cellText = "", row: number, col: number) => { const width = colWidths[col] // Strip newlines in fixedWidth output const cellValue = cellText?.toString().replace(/\n/g, "\\n") || "" const cellLength = cellValue.length if (cellLength > width) return cellValue.substr(0, width - 3) + "..." const padding = " ".repeat(width - cellLength) return alignRight ? padding + cellValue : cellValue + padding } return ( (finalHeaderSlugs.length !== headerSlugs.length ? `Showing ${finalHeaderSlugs.length} of ${headerSlugs.length} columns\n` : "") + toDelimited(" ", finalHeaderSlugs, rows, cellFn) ) } export const toMarkdownTable = ( slugs: string[], rows: any[], formatFn?: CellFormatter ): string => [ slugs, slugs.map(() => "-"), ...rows.map((row) => slugs.map((slug) => row[slug])), ] .map((row, rowIndex) => { const formattedValues = row.map((val, colIndex) => formatFn ? formatFn(val, rowIndex, colIndex) : val ) return `|${formattedValues.join("|")}|` }) .join("\n") export const toDelimited = ( delimiter: string, columnSlugs: string[], rows: any[], cellFn?: CellFormatter, rowDelimiter = "\n" ): string => { const skipHeaderRow = 1 const header = columnSlugs.map((columnName, index) => cellFn ? cellFn(columnName, 0, index) : columnName ) const formattedRows = rows.map((row, rowNumber) => columnSlugs.map((slug, columnIndex) => cellFn ? cellFn(row[slug], rowNumber + skipHeaderRow, columnIndex) : row[slug] ) ) return ( header.join(delimiter) + rowDelimiter + formattedRows.map((row) => row.join(delimiter)).join(rowDelimiter) ) } |