Array of rows (each row is an array of cell values).
Table formatting options.
The formatted table string, ready for terminal output.
Width & alignment
String(cell).length)
unless overridden by TableOptions.columnWidths. Widths include only visible text,
not ANSI SGR sequences (those are added after layout)."left" (default), "center", or "right". Centering uses
naive code-unit math to split leftover spaces.Borders
"single"/"double" (e.g., ┌┬┐│└┴┘─═) and ASCII
for "dashed" (+ - |). Rendering of U+2500–U+257F varies across fonts/terminals; ASCII
is the most portable. :contentReference[oaicite:2]{index=2}Unicode & terminal caveats
length counts UTF-16 code units, not grapheme clusters; emoji/ZWJ/combining
marks can misalign. For perfect results, segment by grapheme (UAX #29) and compute display
width with a wcwidth approach. Terminal display width varies for East Asian wide/ambiguous
characters; wcwidth() is the standard heuristic. :contentReference[oaicite:3]{index=3}Basic:
table(
[
['Alice', 10, 'Admin'],
['Bob', 7, 'User'],
['Charlie', 14, 'PowerUser'],
],
{ headers: ['Name', 'Score', 'Role'] }
);
Styled borders, alignment, and conditional cell styling:
table(
[
['Alice', 10, 'Admin'],
['Bob', 7, 'User'],
['Charlie', 14, 'PowerUser'],
],
{
headers: ['Name', 'Score', 'Role'],
align: ['left', 'right', 'center'],
borderStyle: 'double',
borderColor: 'cyan',
headerStyle: bold,
cellStyle: (txt, _row, col) => col === 1 && Number(txt) >= 10 ? '\x1b[32m' + txt + '\x1b[39m' : txt,
padding: 1,
}
);
Draw a styled table with borders, headers, and aligned cells.