Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support truecolor, #352 #354

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 155 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ unmaintained. `cli-table3` includes all the additional features from
## Features

- Customizable characters that constitute the table.
- Color/background styling in the header through
- [Color/background](#colors) styling the table through
[<s>colors.js</s>](https://github.com/marak/colors.js)
[@colors/colors](https://github.com/DABH/colors.js)
[ansis](https://github.com/webdiscus/ansis).
- Column width customization
- Text truncation based on predefined widths
- Text alignment (left, right, center)
Expand Down Expand Up @@ -167,6 +167,159 @@ console.log(table.toString());
//frobnicate bar quuz
```

<a id="colors" name="colors"></a>

## Colors

You can colorize the text in the table head and the table border with 16 named colors or with truecolor using a hex code.
The color and styles can be combined.

### Base 16 colors and styles

See the full list of [base named colors and styles](https://github.com/webdiscus/ansis#base-ansi-16-colors-and-styles).

### Truecolor

To apply a custom `truecolor`, use the format `hex(CODE)` for foreground and `bgHex(CODE)` for background,
where `CODE` is a 3- or 6-digit hexadecimal code, e.g., `hex(#FFA500)`, `hex(#A7E)`, `bgHex(#FF69B4)`, `bgHex(#49B)`.

### Colorizing table head

Use the `style.head[]` option to style text in the table header.

For example, the header text in base color `green` and styled as `bold` :
```js
var table = new Table({
head: ['Name', 'Age'],
style: {
head: ['green', 'bold'],
}
});

table.push(['Walter White', '50']);

console.log(table.toString());
```

Outputs:

![Screenshot](https://i.imgur.com/mUNLz6l.png)

For example, the header text in truecolor `orange` and styled as `italic`:
```js
style: {
head: ['hex(#FFA500)', 'italic'],
}
```

![Screenshot](https://i.imgur.com/mVieAvj.png)


### Colorizing table border

Use the `style.border[]` option to specify a border color.

For example, the header text in truecolor `orange` and the border in truecolor `gold`:
```js
style: {
border: ['hex(#FFD700)'],
head: ['hex(#FFA500)', 'italic'],
}
```

![Screenshot](https://i.imgur.com/NWzB3nL.png)


### Colorizing table cells

To colorize cells can be used [ansis](https://github.com/webdiscus/ansis), which is already included in this package as an optional dependency.

For example, apply an individual color to the single cell in the table body:
```js
var ansi = require('ansis');
var Table = require('cli-table3');

var table = new Table({
head: ['Name', 'Age'],
style: {
border: ['hex(#FFD700)'],
head: ['hex(#FFA500)', 'italic'],
}
});

table.push(
// apply a color to cells
[ansi.green('Walter White'), ansi.red('50')],
[ansi.hex('#FF69B4')('Jesse Pinkman'), ansi.blueBright('24')],
);

console.log(table.toString());
```

Outputs:

![Screenshot](https://i.imgur.com/EhnOn9i.png)

For example, colorize the table body with one color:
```js
var { green } = require('ansis'); // use a named import when using a few colors
var Table = require('cli-table3');

var table = new Table({
head: ['Name', 'Age'],
style: {
border: ['hex(#FFD700)'],
head: ['hex(#FFA500)', 'italic'],
}
});

table.push(
['Walter White', '50'],
['Jesse Pinkman', '24'],
);

var output = green(table.toString()); // colorize the whole table

console.log(output);
```

Outputs:

![Screenshot](https://i.imgur.com/TGUUzsB.png)


### Colorizing table background

To specify the background color you can use a color name with the `bg` prefix, e.g., `bgGreen`, `bgGreenBright` or `gbHex()` for truecolor.

For example, add a background color to the example above:
```js
var { green } = require('ansis');
var Table = require('cli-table3');

var table = new Table({
head: ['Name', 'Age'],
style: {
border: ['hex(#FFD700)'],
head: ['hex(#FFA500)', 'italic'],
}
});

table.push(
['Walter White', '50'],
['Jesse Pinkman', '24'],
);

var output = green.bgHex('#3d239d')(table.toString()); // <- add a background to the table

console.log(output);
```

Outputs:

![Screenshot](https://i.imgur.com/SY5ikmJ.png)


## Debugging

Later versions of cli-table3 supporting debugging your table data.
Expand Down
2 changes: 2 additions & 0 deletions env/truecolor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// set env variable to simulate truecolor color space in any test environment
process.env.FORCE_COLOR = '3';
2 changes: 1 addition & 1 deletion examples/basic-usage-examples.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const Table = require('../src/table');
const colors = require('@colors/colors/safe');
const colors = require('ansis');
const { hyperlink } = require('../src/utils');

// prettier-ignore
Expand Down
2 changes: 1 addition & 1 deletion examples/col-and-row-span-examples.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const Table = require('../src/table');
const colors = require('@colors/colors/safe');
const colors = require('ansis');

// prettier-ignore
// Disable prettier so that examples are formatted more clearly
Expand Down
13 changes: 4 additions & 9 deletions lib/print-example.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-env jest */
/* eslint-disable no-console */

const colors = require('@colors/colors/safe');
const colors = require('ansis');
const fs = require('fs');

function logExample(fn) {
Expand Down Expand Up @@ -39,7 +39,7 @@ function mdExample(fn, file, cb) {
},
function logTable(table) {
//md files won't render color strings properly.
table = replaceLinks(stripColors(table));
table = replaceLinks(colors.strip(table));

// indent table so is displayed preformatted text
table = ' ' + table.split('\n').join('\n ');
Expand All @@ -48,11 +48,11 @@ function mdExample(fn, file, cb) {
},
function logCode(code) {
buffer.push('```javascript');
buffer.push(stripColors(code));
buffer.push(colors.strip(code));
buffer.push('```');
},
function logSeparator(sep) {
buffer.push(stripColors(sep));
buffer.push(colors.strip(sep));
},
function logScreenShot(image) {
buffer.push('![table image](./examples/screenshots/' + image + '.png)');
Expand Down Expand Up @@ -116,11 +116,6 @@ function runPrintingExample(fn, logName, logTable, logCode, logSeparator, logScr
fn(printExample);
}

// removes all the color characters from a string
function stripColors(str) {
return str.split(/\u001b\[(?:\d*;){0,5}\d*m/g).join('');
}

// returns the first arg - used as snapshot function
function identity(str) {
return str;
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cli-table3",
"version": "0.6.5",
"version": "0.7.0",
"description": "Pretty unicode tables for the command line. Based on the original cli-table.",
"main": "index.js",
"types": "index.d.ts",
Expand All @@ -16,6 +16,7 @@
"string-width": "^4.2.0"
},
"devDependencies": {
"@colors/colors": "1.5.0",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @colors/colors package is still required for test the legacy cli-table package in the verify-legacy-compatibility-test.js file, therefore it should be in devDependencies

"cli-table": "^0.3.1",
"eslint": "^6.0.0",
"eslint-config-prettier": "^6.0.0",
Expand All @@ -26,13 +27,14 @@
"prettier": "2.3.2"
},
"optionalDependencies": {
"@colors/colors": "1.5.0"
"ansis": "3.10.0"
},
"scripts": {
"changelog": "lerna-changelog",
"docs": "node ./scripts/update-docs.js",
"prettier": "prettier --write '{examples,lib,scripts,src,test}/**/*.js'",
"test": "jest --color",
"test:coverage": "jest --color --collectCoverage",
"test:watch": "jest --color --watchAll --notify"
},
"repository": {
Expand Down Expand Up @@ -96,5 +98,6 @@
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "es5"
}
},
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
}
13 changes: 11 additions & 2 deletions src/cell.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,18 @@ class Cell {
wrapWithStyleColors(styleProperty, content) {
if (this[styleProperty] && this[styleProperty].length) {
try {
let colors = require('@colors/colors/safe');
let colors = require('ansis');
for (let i = this[styleProperty].length - 1; i >= 0; i--) {
colors = colors[this[styleProperty][i]];
let style = this[styleProperty][i];
let isHex = style.startsWith('hex');
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add support for new truecolor syntax using hex code, e.g.: hex(#FFD700) and bgHex(#FFD700).

let isBgHex = style.startsWith('bgHex');

if (isHex || isBgHex) {
let value = utils.parseHexValue(style);
colors = isBgHex ? colors.bgHex(value) : colors.hex(value);
} else {
colors = colors[style];
}
}
return colors(content);
} catch (e) {
Expand Down
14 changes: 14 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,19 @@ function hyperlink(url, text) {
return [OSC, '8', SEP, SEP, url || text, BEL, text, OSC, '8', SEP, SEP, BEL].join('');
}

/**
* Parse hex value from string like 'hex(#ff00aa)', 'bgHex(#f00aa)'.
*
* @param {string} text
* @return {string} Return a hex value, e.g. '#ff00aa'. If hex value is invalid, return black.
*/
function parseHexValue(text) {
const regex = /#[0-9a-fA-F]{3,6}/;
const [value] = text.match(regex) || ['#000'];

return value;
}

module.exports = {
strlen: strlen,
repeat: repeat,
Expand All @@ -341,4 +354,5 @@ module.exports = {
wordWrap: multiLineWordWrap,
colorizeLines: colorizeLines,
hyperlink,
parseHexValue,
};
2 changes: 1 addition & 1 deletion test/cell-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
describe('Cell', function () {
const colors = require('@colors/colors');
const colors = require('ansis');
const Cell = require('../src/cell');
const { ColSpanCell, RowSpanCell } = Cell;
const utils = require('../src/utils');
Expand Down
Loading
Loading