| <a name="table"></a> |
| # Table |
| |
| [](https://gitspo.com/mentions/gajus/table) |
| [](https://travis-ci.org/gajus/table) |
| [](https://coveralls.io/github/gajus/table) |
| [](https://www.npmjs.org/package/table) |
| [](https://github.com/gajus/canonical) |
| [](https://twitter.com/kuizinas) |
| |
| * [Table](#table) |
| * [Features](#table-features) |
| * [Install](#table-install) |
| * [Usage](#table-usage) |
| * [Cell Content Alignment](#table-usage-cell-content-alignment) |
| * [Column Width](#table-usage-column-width) |
| * [Custom Border](#table-usage-custom-border) |
| * [Draw Horizontal Line](#table-usage-draw-horizontal-line) |
| * [Single Line Mode](#table-usage-single-line-mode) |
| * [Padding Cell Content](#table-usage-padding-cell-content) |
| * [Predefined Border Templates](#table-usage-predefined-border-templates) |
| * [Streaming](#table-usage-streaming) |
| * [Text Truncation](#table-usage-text-truncation) |
| * [Text Wrapping](#table-usage-text-wrapping) |
| |
| |
| Produces a string that represents array data in a text table. |
| |
|  |
| |
| <a name="table-features"></a> |
| ## Features |
| |
| * Works with strings containing [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) characters. |
| * Works with strings containing [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code). |
| * Configurable border characters. |
| * Configurable content alignment per column. |
| * Configurable content padding per column. |
| * Configurable column width. |
| * Text wrapping. |
| |
| <a name="table-install"></a> |
| ## Install |
| |
| ```bash |
| npm install table |
| |
| ``` |
| |
| [](https://www.buymeacoffee.com/gajus) |
| [](https://www.patreon.com/gajus) |
| |
| <a name="table-usage"></a> |
| ## Usage |
| |
| Table data is described using an array (rows) of array (cells). |
| |
| ```js |
| import { |
| table |
| } from 'table'; |
| |
| // Using commonjs? |
| // const {table} = require('table'); |
| |
| let data, |
| output; |
| |
| data = [ |
| ['0A', '0B', '0C'], |
| ['1A', '1B', '1C'], |
| ['2A', '2B', '2C'] |
| ]; |
| |
| /** |
| * @typedef {string} table~cell |
| */ |
| |
| /** |
| * @typedef {table~cell[]} table~row |
| */ |
| |
| /** |
| * @typedef {Object} table~columns |
| * @property {string} alignment Cell content alignment (enum: left, center, right) (default: left). |
| * @property {number} width Column width (default: auto). |
| * @property {number} truncate Number of characters are which the content will be truncated (default: Infinity). |
| * @property {number} paddingLeft Cell content padding width left (default: 1). |
| * @property {number} paddingRight Cell content padding width right (default: 1). |
| */ |
| |
| /** |
| * @typedef {Object} table~border |
| * @property {string} topBody |
| * @property {string} topJoin |
| * @property {string} topLeft |
| * @property {string} topRight |
| * @property {string} bottomBody |
| * @property {string} bottomJoin |
| * @property {string} bottomLeft |
| * @property {string} bottomRight |
| * @property {string} bodyLeft |
| * @property {string} bodyRight |
| * @property {string} bodyJoin |
| * @property {string} joinBody |
| * @property {string} joinLeft |
| * @property {string} joinRight |
| * @property {string} joinJoin |
| */ |
| |
| /** |
| * Used to dynamically tell table whether to draw a line separating rows or not. |
| * The default behavior is to always return true. |
| * |
| * @typedef {function} drawHorizontalLine |
| * @param {number} index |
| * @param {number} size |
| * @return {boolean} |
| */ |
| |
| /** |
| * @typedef {Object} table~config |
| * @property {table~border} border |
| * @property {table~columns[]} columns Column specific configuration. |
| * @property {table~columns} columnDefault Default values for all columns. Column specific settings overwrite the default values. |
| * @property {table~drawHorizontalLine} drawHorizontalLine |
| */ |
| |
| /** |
| * Generates a text table. |
| * |
| * @param {table~row[]} rows |
| * @param {table~config} config |
| * @return {String} |
| */ |
| output = table(data); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| ╔════╤════╤════╗ |
| ║ 0A │ 0B │ 0C ║ |
| ╟────┼────┼────╢ |
| ║ 1A │ 1B │ 1C ║ |
| ╟────┼────┼────╢ |
| ║ 2A │ 2B │ 2C ║ |
| ╚════╧════╧════╝ |
| |
| ``` |
| |
| |
| <a name="table-usage-cell-content-alignment"></a> |
| ### Cell Content Alignment |
| |
| `{string} config.columns[{number}].alignment` property controls content horizontal alignment within a cell. |
| |
| Valid values are: "left", "right" and "center". |
| |
| ```js |
| let config, |
| data, |
| output; |
| |
| data = [ |
| ['0A', '0B', '0C'], |
| ['1A', '1B', '1C'], |
| ['2A', '2B', '2C'] |
| ]; |
| |
| config = { |
| columns: { |
| 0: { |
| alignment: 'left', |
| width: 10 |
| }, |
| 1: { |
| alignment: 'center', |
| width: 10 |
| }, |
| 2: { |
| alignment: 'right', |
| width: 10 |
| } |
| } |
| }; |
| |
| output = table(data, config); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| ╔════════════╤════════════╤════════════╗ |
| ║ 0A │ 0B │ 0C ║ |
| ╟────────────┼────────────┼────────────╢ |
| ║ 1A │ 1B │ 1C ║ |
| ╟────────────┼────────────┼────────────╢ |
| ║ 2A │ 2B │ 2C ║ |
| ╚════════════╧════════════╧════════════╝ |
| ``` |
| |
| <a name="table-usage-column-width"></a> |
| ### Column Width |
| |
| `{number} config.columns[{number}].width` property restricts column width to a fixed width. |
| |
| ```js |
| let data, |
| output, |
| options; |
| |
| data = [ |
| ['0A', '0B', '0C'], |
| ['1A', '1B', '1C'], |
| ['2A', '2B', '2C'] |
| ]; |
| |
| options = { |
| columns: { |
| 1: { |
| width: 10 |
| } |
| } |
| }; |
| |
| output = table(data, options); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| ╔════╤════════════╤════╗ |
| ║ 0A │ 0B │ 0C ║ |
| ╟────┼────────────┼────╢ |
| ║ 1A │ 1B │ 1C ║ |
| ╟────┼────────────┼────╢ |
| ║ 2A │ 2B │ 2C ║ |
| ╚════╧════════════╧════╝ |
| ``` |
| |
| <a name="table-usage-custom-border"></a> |
| ### Custom Border |
| |
| `{object} config.border` property describes characters used to draw the table border. |
| |
| ```js |
| let config, |
| data, |
| output; |
| |
| data = [ |
| ['0A', '0B', '0C'], |
| ['1A', '1B', '1C'], |
| ['2A', '2B', '2C'] |
| ]; |
| |
| config = { |
| border: { |
| topBody: `─`, |
| topJoin: `┬`, |
| topLeft: `┌`, |
| topRight: `┐`, |
| |
| bottomBody: `─`, |
| bottomJoin: `┴`, |
| bottomLeft: `└`, |
| bottomRight: `┘`, |
| |
| bodyLeft: `│`, |
| bodyRight: `│`, |
| bodyJoin: `│`, |
| |
| joinBody: `─`, |
| joinLeft: `├`, |
| joinRight: `┤`, |
| joinJoin: `┼` |
| } |
| }; |
| |
| output = table(data, config); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| ┌────┬────┬────┐ |
| │ 0A │ 0B │ 0C │ |
| ├────┼────┼────┤ |
| │ 1A │ 1B │ 1C │ |
| ├────┼────┼────┤ |
| │ 2A │ 2B │ 2C │ |
| └────┴────┴────┘ |
| ``` |
| |
| <a name="table-usage-draw-horizontal-line"></a> |
| ### Draw Horizontal Line |
| |
| `{function} config.drawHorizontalLine` property is a function that is called for every non-content row in the table. The result of the function `{boolean}` determines whether a row is drawn. |
| |
| ```js |
| let data, |
| output, |
| options; |
| |
| data = [ |
| ['0A', '0B', '0C'], |
| ['1A', '1B', '1C'], |
| ['2A', '2B', '2C'], |
| ['3A', '3B', '3C'], |
| ['4A', '4B', '4C'] |
| ]; |
| |
| options = { |
| /** |
| * @typedef {function} drawHorizontalLine |
| * @param {number} index |
| * @param {number} size |
| * @return {boolean} |
| */ |
| drawHorizontalLine: (index, size) => { |
| return index === 0 || index === 1 || index === size - 1 || index === size; |
| } |
| }; |
| |
| output = table(data, options); |
| |
| console.log(output); |
| |
| ``` |
| |
| ``` |
| ╔════╤════╤════╗ |
| ║ 0A │ 0B │ 0C ║ |
| ╟────┼────┼────╢ |
| ║ 1A │ 1B │ 1C ║ |
| ║ 2A │ 2B │ 2C ║ |
| ║ 3A │ 3B │ 3C ║ |
| ╟────┼────┼────╢ |
| ║ 4A │ 4B │ 4C ║ |
| ╚════╧════╧════╝ |
| |
| ``` |
| |
| <a name="table-usage-single-line-mode"></a> |
| ### Single Line Mode |
| |
| Horizontal lines inside the table are not drawn. |
| |
| ```js |
| import { |
| table, |
| getBorderCharacters |
| } from 'table'; |
| |
| const data = [ |
| ['-rw-r--r--', '1', 'pandorym', 'staff', '1529', 'May 23 11:25', 'LICENSE'], |
| ['-rw-r--r--', '1', 'pandorym', 'staff', '16327', 'May 23 11:58', 'README.md'], |
| ['drwxr-xr-x', '76', 'pandorym', 'staff', '2432', 'May 23 12:02', 'dist'], |
| ['drwxr-xr-x', '634', 'pandorym', 'staff', '20288', 'May 23 11:54', 'node_modules'], |
| ['-rw-r--r--', '1,', 'pandorym', 'staff', '525688', 'May 23 11:52', 'package-lock.json'], |
| ['-rw-r--r--@', '1', 'pandorym', 'staff', '2440', 'May 23 11:25', 'package.json'], |
| ['drwxr-xr-x', '27', 'pandorym', 'staff', '864', 'May 23 11:25', 'src'], |
| ['drwxr-xr-x', '20', 'pandorym', 'staff', '640', 'May 23 11:25', 'test'], |
| ]; |
| |
| const config = { |
| singleLine: true |
| }; |
| |
| const output = table(data, config); |
| console.log(output); |
| ``` |
| |
| ``` |
| ╔═════════════╤═════╤══════════╤═══════╤════════╤══════════════╤═══════════════════╗ |
| ║ -rw-r--r-- │ 1 │ pandorym │ staff │ 1529 │ May 23 11:25 │ LICENSE ║ |
| ║ -rw-r--r-- │ 1 │ pandorym │ staff │ 16327 │ May 23 11:58 │ README.md ║ |
| ║ drwxr-xr-x │ 76 │ pandorym │ staff │ 2432 │ May 23 12:02 │ dist ║ |
| ║ drwxr-xr-x │ 634 │ pandorym │ staff │ 20288 │ May 23 11:54 │ node_modules ║ |
| ║ -rw-r--r-- │ 1, │ pandorym │ staff │ 525688 │ May 23 11:52 │ package-lock.json ║ |
| ║ -rw-r--r--@ │ 1 │ pandorym │ staff │ 2440 │ May 23 11:25 │ package.json ║ |
| ║ drwxr-xr-x │ 27 │ pandorym │ staff │ 864 │ May 23 11:25 │ src ║ |
| ║ drwxr-xr-x │ 20 │ pandorym │ staff │ 640 │ May 23 11:25 │ test ║ |
| ╚═════════════╧═════╧══════════╧═══════╧════════╧══════════════╧═══════════════════╝ |
| ``` |
| |
| <a name="table-usage-padding-cell-content"></a> |
| ### Padding Cell Content |
| |
| `{number} config.columns[{number}].paddingLeft` and `{number} config.columns[{number}].paddingRight` properties control content padding within a cell. Property value represents a number of whitespaces used to pad the content. |
| |
| ```js |
| let config, |
| data, |
| output; |
| |
| data = [ |
| ['0A', 'AABBCC', '0C'], |
| ['1A', '1B', '1C'], |
| ['2A', '2B', '2C'] |
| ]; |
| |
| config = { |
| columns: { |
| 0: { |
| paddingLeft: 3 |
| }, |
| 1: { |
| width: 2, |
| paddingRight: 3 |
| } |
| } |
| }; |
| |
| output = table(data, config); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| ╔══════╤══════╤════╗ |
| ║ 0A │ AA │ 0C ║ |
| ║ │ BB │ ║ |
| ║ │ CC │ ║ |
| ╟──────┼──────┼────╢ |
| ║ 1A │ 1B │ 1C ║ |
| ╟──────┼──────┼────╢ |
| ║ 2A │ 2B │ 2C ║ |
| ╚══════╧══════╧════╝ |
| ``` |
| |
| <a name="table-usage-predefined-border-templates"></a> |
| ### Predefined Border Templates |
| |
| You can load one of the predefined border templates using `getBorderCharacters` function. |
| |
| ```js |
| import { |
| table, |
| getBorderCharacters |
| } from 'table'; |
| |
| let config, |
| data; |
| |
| data = [ |
| ['0A', '0B', '0C'], |
| ['1A', '1B', '1C'], |
| ['2A', '2B', '2C'] |
| ]; |
| |
| config = { |
| border: getBorderCharacters(`name of the template`) |
| }; |
| |
| table(data, config); |
| ``` |
| |
| ``` |
| # honeywell |
| |
| ╔════╤════╤════╗ |
| ║ 0A │ 0B │ 0C ║ |
| ╟────┼────┼────╢ |
| ║ 1A │ 1B │ 1C ║ |
| ╟────┼────┼────╢ |
| ║ 2A │ 2B │ 2C ║ |
| ╚════╧════╧════╝ |
| |
| # norc |
| |
| ┌────┬────┬────┐ |
| │ 0A │ 0B │ 0C │ |
| ├────┼────┼────┤ |
| │ 1A │ 1B │ 1C │ |
| ├────┼────┼────┤ |
| │ 2A │ 2B │ 2C │ |
| └────┴────┴────┘ |
| |
| # ramac (ASCII; for use in terminals that do not support Unicode characters) |
| |
| +----+----+----+ |
| | 0A | 0B | 0C | |
| |----|----|----| |
| | 1A | 1B | 1C | |
| |----|----|----| |
| | 2A | 2B | 2C | |
| +----+----+----+ |
| |
| # void (no borders; see "bordless table" section of the documentation) |
| |
| 0A 0B 0C |
| |
| 1A 1B 1C |
| |
| 2A 2B 2C |
| |
| ``` |
| |
| Raise [an issue](https://github.com/gajus/table/issues) if you'd like to contribute a new border template. |
| |
| <a name="table-usage-predefined-border-templates-borderless-table"></a> |
| #### Borderless Table |
| |
| Simply using "void" border character template creates a table with a lot of unnecessary spacing. |
| |
| To create a more plesant to the eye table, reset the padding and remove the joining rows, e.g. |
| |
| ```js |
| let output; |
| |
| output = table(data, { |
| border: getBorderCharacters(`void`), |
| columnDefault: { |
| paddingLeft: 0, |
| paddingRight: 1 |
| }, |
| drawHorizontalLine: () => { |
| return false |
| } |
| }); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| 0A 0B 0C |
| 1A 1B 1C |
| 2A 2B 2C |
| ``` |
| |
| <a name="table-usage-streaming"></a> |
| ### Streaming |
| |
| `table` package exports `createStream` function used to draw a table and append rows. |
| |
| `createStream` requires `{number} columnDefault.width` and `{number} columnCount` configuration properties. |
| |
| ```js |
| import { |
| createStream |
| } from 'table'; |
| |
| let config, |
| stream; |
| |
| config = { |
| columnDefault: { |
| width: 50 |
| }, |
| columnCount: 1 |
| }; |
| |
| stream = createStream(config); |
| |
| setInterval(() => { |
| stream.write([new Date()]); |
| }, 500); |
| ``` |
| |
|  |
| |
| `table` package uses ANSI escape codes to overwrite the output of the last line when a new row is printed. |
| |
| The underlying implementation is explained in this [Stack Overflow answer](http://stackoverflow.com/a/32938658/368691). |
| |
| Streaming supports all of the configuration properties and functionality of a static table (such as auto text wrapping, alignment and padding), e.g. |
| |
| ```js |
| import { |
| createStream |
| } from 'table'; |
| |
| import _ from 'lodash'; |
| |
| let config, |
| stream, |
| i; |
| |
| config = { |
| columnDefault: { |
| width: 50 |
| }, |
| columnCount: 3, |
| columns: { |
| 0: { |
| width: 10, |
| alignment: 'right' |
| }, |
| 1: { |
| alignment: 'center', |
| }, |
| 2: { |
| width: 10 |
| } |
| } |
| }; |
| |
| stream = createStream(config); |
| |
| i = 0; |
| |
| setInterval(() => { |
| let random; |
| |
| random = _.sample('abcdefghijklmnopqrstuvwxyz', _.random(1, 30)).join(''); |
| |
| stream.write([i++, new Date(), random]); |
| }, 500); |
| ``` |
| |
|  |
| |
| <a name="table-usage-text-truncation"></a> |
| ### Text Truncation |
| |
| To handle a content that overflows the container width, `table` package implements [text wrapping](#table-usage-text-wrapping). However, sometimes you may want to truncate content that is too long to be displayed in the table. |
| |
| `{number} config.columns[{number}].truncate` property (default: `Infinity`) truncates the text at the specified length. |
| |
| ```js |
| let config, |
| data, |
| output; |
| |
| data = [ |
| ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pulvinar nibh sed mauris convallis dapibus. Nunc venenatis tempus nulla sit amet viverra.'] |
| ]; |
| |
| config = { |
| columns: { |
| 0: { |
| width: 20, |
| truncate: 100 |
| } |
| } |
| }; |
| |
| output = table(data, config); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| ╔══════════════════════╗ |
| ║ Lorem ipsum dolor si ║ |
| ║ t amet, consectetur ║ |
| ║ adipiscing elit. Pha ║ |
| ║ sellus pulvinar nibh ║ |
| ║ sed mauris conva... ║ |
| ╚══════════════════════╝ |
| ``` |
| |
| <a name="table-usage-text-wrapping"></a> |
| ### Text Wrapping |
| |
| `table` package implements auto text wrapping, i.e. text that has width greater than the container width will be separated into multiple lines, e.g. |
| |
| ```js |
| let config, |
| data, |
| output; |
| |
| data = [ |
| ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pulvinar nibh sed mauris convallis dapibus. Nunc venenatis tempus nulla sit amet viverra.'] |
| ]; |
| |
| config = { |
| columns: { |
| 0: { |
| width: 20 |
| } |
| } |
| }; |
| |
| output = table(data, config); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| ╔══════════════════════╗ |
| ║ Lorem ipsum dolor si ║ |
| ║ t amet, consectetur ║ |
| ║ adipiscing elit. Pha ║ |
| ║ sellus pulvinar nibh ║ |
| ║ sed mauris convallis ║ |
| ║ dapibus. Nunc venena ║ |
| ║ tis tempus nulla sit ║ |
| ║ amet viverra. ║ |
| ╚══════════════════════╝ |
| ``` |
| |
| When `wrapWord` is `true` the text is broken at the nearest space or one of the special characters ("-", "_", "\", "/", ".", ",", ";"), e.g. |
| |
| ```js |
| let config, |
| data, |
| output; |
| |
| data = [ |
| ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pulvinar nibh sed mauris convallis dapibus. Nunc venenatis tempus nulla sit amet viverra.'] |
| ]; |
| |
| config = { |
| columns: { |
| 0: { |
| width: 20, |
| wrapWord: true |
| } |
| } |
| }; |
| |
| output = table(data, config); |
| |
| console.log(output); |
| ``` |
| |
| ``` |
| ╔══════════════════════╗ |
| ║ Lorem ipsum dolor ║ |
| ║ sit amet, ║ |
| ║ consectetur ║ |
| ║ adipiscing elit. ║ |
| ║ Phasellus pulvinar ║ |
| ║ nibh sed mauris ║ |
| ║ convallis dapibus. ║ |
| ║ Nunc venenatis ║ |
| ║ tempus nulla sit ║ |
| ║ amet viverra. ║ |
| ╚══════════════════════╝ |
| |
| ``` |
| |