/table

A lightweight, cross-runtime text formatting library for producing text-based tables. Designed for use with CLI and text-based applications.

Primary LanguageJavaScriptMIT LicenseMIT

@author.io/table Version

Test and Build using the cross-runtime template.

The table module generates nicely formatted/align text (UTF8) based tables. It was designed for use with @author.io/shell, but it is a generic library that can be used in any type of text application. It works across runtimes (Node.js, browsers), contains unit tests and source maps, and is available via popular CDN's. It has no dependencies and remaining lightweight is a key priority of this library (there are many other text table formatting libraries that do everything under the sun).

Example:

const rows = [
  ['Column 1', 'Column 2', 'Column 3'],
  ['test', '[-o, -opt]', 'This is an example, using a run-on sentence that should break onto a separate line or multiple lines depending on the table with specified.'],
  ['cmd', '', 'Another command description.']
]

const table = new Table(rows)

console.log(table.output)

The default output:

Column 1                  Column 2                  Column 3
test                      [-o, -opt]                This is an example, using a
                                                    run-on sentence that should
                                                    break onto a separate line
                                                    or multiple lines depending
                                                    on the table with specified.
cmd                                                 Another command description.

Installation & Usage

For Modern Node (ES Modules)

npm install @author.io/table

Please note, you'll need a verison of Node that supports ES Modules. In Node 12, this feature is behind the --experimental-modules flag. It is available in Node 13+ without a flag, but your package.json file must have the "type": "module" attribute. This feature will be generally available in Node 14.0.0 (release date April 21, 2020).

For Browsers

CDN

import Table from 'https://cdn.jsdelivr.net/npm/@author.io/table/index.min.js'

Also available from unpkg.

Debugging

Each distribution has a corresponding -debug version that should be installed alongside the main module (the debugging is an add-on module). For example, npm install @author.io/table-debug --save-dev would install the debugging code.


Default configuration

Each of these are modifiable using methods and/or configuration parameters (detailed below).

  1. 80 characters wide.
  2. Equally distributed column widths.
  3. Left aligned columns.
  4. No cellspacing.
  5. No table margins.
  6. Long content is wrapped.

All empty columns are stripped. Here's why:

There is no need for an empty column.

But... I want an empty column! Blank columns usually have a header. This is different from an empty column, which has NO content. For example:

Column 1                  Column 2                  Column 3
test                                                This is an example...
test2                                               This is an example...
test3                                               This is an example...

Column 2 is blank. If there were no header, it would be considered "empty".

But, but... I want to use an empty column as a spacer! Use cellspacing to create space separation between columns.

But, but, BUT... I want to use an empty column to add space to a SPECIFIC column! To add space before/after a specific column, pad the content.

Customizing Output

The table class accepts several configuration options.

new Table(rows, columnAlignment, columnWidths, tableWidth, tableMargins)

Rows (required)

This is an array of arrays. The main array contains rows. Each "subarray" contains the column data.

Example:

[
  ['Column 1', 'Column 2', 'Column 3'], // Row 1
  ['Column 1', 'Column 2', 'Column 3'], // Row 2
  ['Column 1', 'Column 2', 'Column 3']  // Row 3
]

Column Alignment

This is an array of characters, where each character represents alignment of a column.

Example:

[
  'l', // Left align column 1
  'c', // Center align column 2
  'r'  // Right align column 3
]

Column Widths

This is an array of numbers or strings. Each value represents the width of a column. A number represents how many characters wide the column will be. A string can represent a percentage, such as 50% to represent half the width of the total table. It's possible to mix these, but isn't thoroughly tested. As a result, it's recommended to use one or other instead of mixing percentages with explicit numeric widths.

Percentage Example: (Assume an 80 character-wide table)

[
  '20%', // Column 1 will be 16 characters wide
  '20%', // Column 2 will be 16 characters wide
  '60%'  // Column 3 will be 48 characters wide
]

Numeric Example: (Assume an 80 character-wide table)

[
  16, // Column 1 will be 16 characters wide
  16, // Column 2 will be 16 characters wide
  48  // Column 3 will be 48 characters wide
]

Table Width

This is the maximum width of the table, in characters. Default is 80.

Examples:

const table = new Table(rows, null, null, 80, null)

Table Margins

It is possible to add spacing around the table.

The syntax is:

[<left>[, <right>][, <top>][, <bottom>]]

Everything is available. All unspecified values default to 0.

Example:

[
  2, // Left margin will be 2 empty spaces
  2, // Right margin will be 2 empty spaces
  1, // Top margin will be 1 empty spaces
  1  // Bottom margin will be 1 empty spaces
]

This is represented as you would expect (borders for illustration purposes only):

--------------------------
|           Top          |
|  --------------------  |
|L |                  |R |
|e |       Table      |i |
|f |  (76 chars wide) |g |
|t |                  |h |
|  |                  |t |
|  --------------------  |
|          Bottom        |
--------------------------

Advanced Formatting Options

In addition to basic arguments, there are several other settings/methods to help customize the output.

Cellspacing

Cellspacing is a number of characters applied after every column except the last one. By default, there is no cellspacing (i.e. 0).

WARNING: This will expand the width of your table! (Calculate accordingly)

Example:

const rows = [
  ['a', 'b'],
  ['c', 'd']
]

const table = new Table(rows, null, null, 4)
table.cellspacing = 2

Output:

# Spaces represented by underscores for illustration purposes
a___b_
c___d_

The cellspacing is then injected at the end of each column (except the last).

If cellspacing had not been defined, the output would have looked like:

a_b_
c_d_

The output above is 4 characters wide. There would be a space after b and d since the table is 4 characters wide and left aligned (each column is 2 characters wide, but with no cellspacing).

Custom Fill Character

In most cases, using a space is the best custom fill character. However; it is possible to modify this using the fill property. We don't really see many use cases for this (other than leader lines), but it's there if you need it.

Example:

const rows = [
  ['a', 'b'],
  ['c', 'd']
]

const table = new Table(rows, null, null, 10)

table.fill = '*'

console.log(table.output)

Output:

a****b****
c****d****

Wrapping & Truncating Long Text

By default, long text is wrapped in a column. It is possible to truncate one or more columns instead of wrapping text.

1. To truncate all columns:

const table = new Table(rows)
table.truncate()

2. To truncate specific columns: (uses a 1-based column index)

const table = new Table(rows)
table.truncate(2, 4) // Truncate column #2 and column #4

3. Clear truncation:

const table = new Table(rows)
table.truncate(0) // Anything 0 or less

NOTICE there is no way to modify truncation properties of a specific column. If you need to "modify", clear truncation and reset (i.e. use example 3, then example 2).

Additional Properties

The class has 4 read-only properties:

  1. columns - the raw column map
  2. columnCount - The number of columns.
  3. rows - The raw row object, updated with appropriate formatting.
  4. rowCount - the number of rows.
const table = new Table(rows)

console.log(table.rowCount, table.columnCount)

Miscellaneous Notes

This class replaces tab characters with two spaces. This is an opinionated decision to prevent inconsistencies in display.

If you disagree with this opinion the workaround is to extend the class:

class MyTable extends Table {
  constructor () {
    super()

    this.#tabWidth = 4
  }
}

const table = new MyTable(rows)

Credits

Created by Corey Butler for Author.io.

Sponsors (as of 2021)