Comparing version 1.0.0 to 2.0.0
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
var _border = require('./border/'); | ||
var _border2 = _interopRequireDefault(_border); | ||
var _table = require('./table'); | ||
var _table2 = _interopRequireDefault(_table); | ||
exports.border = _border2['default']; | ||
exports['default'] = _table2['default']; | ||
//# sourceMappingURL=index.js.map |
'use strict'; | ||
var _lodashCollectionMap2 = require('lodash/collection/map'); | ||
var _lodashLangCloneDeep2 = require('lodash/lang/cloneDeep'); | ||
var _lodashCollectionMap3 = _interopRequireDefault(_lodashCollectionMap2); | ||
var _lodashLangCloneDeep3 = _interopRequireDefault(_lodashLangCloneDeep2); | ||
var _lodashObjectAssign2 = require('lodash/object/assign'); | ||
var _lodashObjectAssign3 = _interopRequireDefault(_lodashObjectAssign2); | ||
var _lodashUtilityTimes2 = require('lodash/utility/times'); | ||
var _lodashUtilityTimes3 = _interopRequireDefault(_lodashUtilityTimes2); | ||
var _lodashLangIsUndefined2 = require('lodash/lang/isUndefined'); | ||
@@ -11,2 +19,6 @@ | ||
var _lodashObjectMapValues2 = require('lodash/object/mapValues'); | ||
var _lodashObjectMapValues3 = _interopRequireDefault(_lodashObjectMapValues2); | ||
Object.defineProperty(exports, '__esModule', { | ||
@@ -16,2 +28,6 @@ value: true | ||
var _border = require('./border/'); | ||
var _border2 = _interopRequireDefault(_border); | ||
var _validateConfig = require('./validateConfig'); | ||
@@ -27,4 +43,4 @@ | ||
* @param {Array[]} rows | ||
* @param {formatData~config} config | ||
* @return {formatData~config} | ||
* @param {Object} inputConfig | ||
* @return {Object} | ||
*/ | ||
@@ -35,16 +51,31 @@ | ||
exports['default'] = function (rows) { | ||
var config = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var inputConfig = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var maximumColumnValueIndex = undefined; | ||
var config = undefined, | ||
maximumColumnValueIndex = undefined; | ||
config = (0, _lodashLangCloneDeep3['default'])(inputConfig); | ||
(0, _validateConfig2['default'])(rows, config); | ||
if (!config.border) { | ||
config.border = {}; | ||
} | ||
config.border = (0, _lodashObjectAssign3['default'])({}, (0, _border2['default'])('honeywell'), config.border); | ||
maximumColumnValueIndex = (0, _calculateMaximumColumnValueIndex2['default'])(rows); | ||
config.columnConfig = config.columnConfig || Array(rows[0].length); | ||
if (!config.column) { | ||
config.column = {}; | ||
} | ||
config.columnConfig = (0, _lodashCollectionMap3['default'])(config.columnConfig, function (column, index0) { | ||
if (column === undefined) column = {}; | ||
(0, _lodashUtilityTimes3['default'])(rows[0].length, function (index) { | ||
if ((0, _lodashLangIsUndefined3['default'])(config.column[index])) { | ||
config.column[index] = {}; | ||
} | ||
}); | ||
if ((0, _lodashLangIsUndefined3['default'])(column.minWidth) || maximumColumnValueIndex[index0] > config.columnConfig[index0].minWidth) { | ||
config.column = (0, _lodashObjectMapValues3['default'])(config.column, function (column, index0) { | ||
if ((0, _lodashLangIsUndefined3['default'])(column.minWidth) || maximumColumnValueIndex[index0] > config.column[index0].minWidth) { | ||
column.minWidth = maximumColumnValueIndex[index0]; | ||
@@ -63,2 +94,10 @@ } | ||
if ((0, _lodashLangIsUndefined3['default'])(column.paddingLeft)) { | ||
column.paddingLeft = 0; | ||
} | ||
if ((0, _lodashLangIsUndefined3['default'])(column.paddingRight)) { | ||
column.paddingRight = 0; | ||
} | ||
return column; | ||
@@ -65,0 +104,0 @@ }); |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashCollectionForEach2 = require('lodash/collection/forEach'); | ||
var _lodashStringRepeat2 = require('lodash/string/repeat'); | ||
var _lodashCollectionForEach3 = _interopRequireDefault(_lodashCollectionForEach2); | ||
var _lodashStringRepeat3 = _interopRequireDefault(_lodashStringRepeat2); | ||
@@ -16,54 +16,149 @@ Object.defineProperty(exports, '__esModule', { | ||
var _border = require('./border'); | ||
var _drawTable = require('./drawTable'); | ||
var _border2 = _interopRequireDefault(_border); | ||
var _drawTable2 = _interopRequireDefault(_drawTable); | ||
var _drawBorder = require('./drawBorder'); | ||
var _calculateColumnSizeIndex = require('./calculateColumnSizeIndex'); | ||
var _drawRow = require('./drawRow'); | ||
var _calculateColumnSizeIndex2 = _interopRequireDefault(_calculateColumnSizeIndex); | ||
var _drawRow2 = _interopRequireDefault(_drawRow); | ||
var _makeConfig = require('./makeConfig'); | ||
var _formatData = require('./formatData'); | ||
var _makeConfig2 = _interopRequireDefault(_makeConfig); | ||
var _formatData2 = _interopRequireDefault(_formatData); | ||
var _calculateRowSpanIndex = require('./calculateRowSpanIndex'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
var _calculateRowSpanIndex2 = _interopRequireDefault(_calculateRowSpanIndex); | ||
var drawTop = undefined, | ||
getColumnSizeIndex = undefined; | ||
var _mapDataUsingRowSpanIndex = require('./mapDataUsingRowSpanIndex'); | ||
var _mapDataUsingRowSpanIndex2 = _interopRequireDefault(_mapDataUsingRowSpanIndex); | ||
var _stringWidth = require('string-width'); | ||
var _stringWidth2 = _interopRequireDefault(_stringWidth); | ||
var _align = require('./align'); | ||
var _align2 = _interopRequireDefault(_align); | ||
var _validateData = require('./validateData'); | ||
var _validateData2 = _interopRequireDefault(_validateData); | ||
/** | ||
* @param {String[]} columns | ||
* @return {Number[]} | ||
* @typedef {String} table~cell | ||
*/ | ||
getColumnSizeIndex = function (columns) { | ||
return (0, _lodashCollectionMap3['default'])(columns, function (data) { | ||
return data.length; | ||
}); | ||
}; | ||
exports['default'] = function (data) { | ||
var table = undefined, | ||
/** | ||
* @typedef {table~cell[]} table~row | ||
*/ | ||
/** | ||
* @typedef {Object} table~configColumn | ||
* @property {String} alignment Cell content alignment (enum: left, center, right) (default: left). | ||
* @property {Number} minWidth Minimum column width (default: 0). | ||
* @property {Number} maxWidth Maximum column width (default: Infinity). | ||
* @property {Number} paddingLeft Cell content padding width left (default: 0). | ||
* @property {Number} paddingRight Cell content padding width right (default: 0). | ||
*/ | ||
/** | ||
* @typedef {Object} table~configBorder | ||
* @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 | ||
*/ | ||
/** | ||
* @typedef {Object} table~config | ||
* @property {table~configBorder} | ||
* @property {table~configColumn[]} column Column specific configuration. | ||
*/ | ||
/** | ||
* Generates a text table. | ||
* | ||
* @param {table~row[]} rows | ||
* @param {table~config} config | ||
* @return {String} | ||
*/ | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
exports['default'] = function (rows) { | ||
var config = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var derivedConfig = undefined, | ||
safeData = undefined, | ||
rowSpanIndex = undefined, | ||
columnSizeIndex = undefined, | ||
rows = undefined; | ||
dataMappedUsingRowSpanIndex = undefined, | ||
tableBorder = undefined; | ||
rows = (0, _formatData2['default'])(data); | ||
(0, _validateData2['default'])(rows); | ||
columnSizeIndex = getColumnSizeIndex(rows[0]); | ||
safeData = (0, _lodashCollectionMap3['default'])(rows, function (columns) { | ||
return (0, _lodashCollectionMap3['default'])(columns, String); | ||
}); | ||
table = ''; | ||
table += (0, _drawBorder.drawBorderTop)(columnSizeIndex, _border2['default']); | ||
// console.log(`safeData`, safeData); | ||
(0, _lodashCollectionForEach3['default'])(rows, function (row, i) { | ||
table += (0, _drawRow2['default'])(row, _border2['default']); | ||
derivedConfig = (0, _makeConfig2['default'])(safeData, config); | ||
if (i + 1 !== rows.length) { | ||
table += (0, _drawBorder.drawBorderJoin)(columnSizeIndex, _border2['default']); | ||
} | ||
// console.log(`derivedConfig`, derivedConfig); | ||
rowSpanIndex = (0, _calculateRowSpanIndex2['default'])(safeData, derivedConfig); | ||
// console.log(`rowSpanIndex`, rowSpanIndex); | ||
dataMappedUsingRowSpanIndex = (0, _mapDataUsingRowSpanIndex2['default'])(safeData, rowSpanIndex, derivedConfig); | ||
// console.log(`dataMappedUsingRowSpanIndex`, dataMappedUsingRowSpanIndex); | ||
dataMappedUsingRowSpanIndex = (0, _lodashCollectionMap3['default'])(dataMappedUsingRowSpanIndex, function (cells, index0) { | ||
return (0, _lodashCollectionMap3['default'])(cells, function (value, index1) { | ||
var column = undefined; | ||
column = derivedConfig.column[index1]; | ||
// console.log(column); | ||
if ((0, _stringWidth2['default'])(value) === column.maxWidth) { | ||
return value; | ||
} else { | ||
return (0, _align2['default'])(value, column.minWidth, column.alignment); | ||
} | ||
}); | ||
}); | ||
table += (0, _drawBorder.drawBorderBottom)(columnSizeIndex, _border2['default']); | ||
dataMappedUsingRowSpanIndex = (0, _lodashCollectionMap3['default'])(dataMappedUsingRowSpanIndex, function (cells, index0) { | ||
return (0, _lodashCollectionMap3['default'])(cells, function (value, index1) { | ||
var column = undefined; | ||
return table; | ||
column = derivedConfig.column[index1]; | ||
return (0, _lodashStringRepeat3['default'])(' ', column.paddingLeft) + value + (0, _lodashStringRepeat3['default'])(' ', column.paddingRight); | ||
}); | ||
}); | ||
//_.times(config.column[index1].paddingLeft, ` `) | ||
columnSizeIndex = (0, _calculateColumnSizeIndex2['default'])(dataMappedUsingRowSpanIndex[0]); | ||
// console.log(`columnSizeIndex`, columnSizeIndex); | ||
return (0, _drawTable2['default'])(dataMappedUsingRowSpanIndex, derivedConfig.border, columnSizeIndex, rowSpanIndex); | ||
}; | ||
@@ -70,0 +165,0 @@ |
'use strict'; | ||
var _lodashArrayFirst2 = require('lodash/array/first'); | ||
var _lodashArrayFirst3 = _interopRequireDefault(_lodashArrayFirst2); | ||
var _lodashArrayDifference2 = require('lodash/array/difference'); | ||
var _lodashArrayDifference3 = _interopRequireDefault(_lodashArrayDifference2); | ||
var _lodashObjectKeys2 = require('lodash/object/keys'); | ||
var _lodashObjectKeys3 = _interopRequireDefault(_lodashObjectKeys2); | ||
var _lodashCollectionForEach2 = require('lodash/collection/forEach'); | ||
@@ -27,4 +15,10 @@ | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
var _schemasConfigJson = require('./schemas/config.json'); | ||
var _schemasConfigJson2 = _interopRequireDefault(_schemasConfigJson); | ||
var _tv4 = require('tv4'); | ||
var _tv42 = _interopRequireDefault(_tv4); | ||
/** | ||
@@ -36,22 +30,26 @@ * @param {row[]} rows | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
exports['default'] = function (rows) { | ||
var config = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var unknownPropertyName = undefined; | ||
var result = undefined; | ||
unknownPropertyName = (0, _lodashArrayFirst3['default'])((0, _lodashArrayDifference3['default'])((0, _lodashObjectKeys3['default'])(config), ['columnConfig'])); | ||
result = _tv42['default'].validateResult(config, _schemasConfigJson2['default']); | ||
if (unknownPropertyName) { | ||
throw new Error('Config must not define unknown properties. "' + unknownPropertyName + '" is an unknown property.'); | ||
if (!result.valid) { | ||
console.log('config', config); | ||
console.log('error', { | ||
message: result.error.message, | ||
params: result.error.params, | ||
dataPath: result.error.dataPath, | ||
schemaPath: result.error.schemaPath | ||
}); | ||
throw new Error('Invalid config.'); | ||
} | ||
if (config.columnConfig) { | ||
(0, _lodashCollectionForEach3['default'])(config.columnConfig, function (columnConfig) { | ||
unknownPropertyName = (0, _lodashArrayFirst3['default'])((0, _lodashArrayDifference3['default'])((0, _lodashObjectKeys3['default'])(columnConfig), ['align', 'minWidth', 'maxWidth'])); | ||
if (unknownPropertyName) { | ||
throw new Error('Column config must not define unknown properties. "' + unknownPropertyName + '" is an unknown property.'); | ||
} | ||
if (!(0, _lodashLangIsUndefined3['default'])(columnConfig.minWidth) && !(0, _lodashLangIsUndefined3['default'])(columnConfig.maxWidth) && columnConfig.minWidth > columnConfig.maxWidth) { | ||
if (config.column) { | ||
(0, _lodashCollectionForEach3['default'])(config.column, function (column) { | ||
if (!(0, _lodashLangIsUndefined3['default'])(column.minWidth) && !(0, _lodashLangIsUndefined3['default'])(column.maxWidth) && column.minWidth > column.maxWidth) { | ||
throw new Error('Column minWidth cannot be greater than maxWidth.'); | ||
@@ -58,0 +56,0 @@ } |
{ | ||
"name": "table", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"description": "Formats data into a string table.", | ||
@@ -18,6 +18,8 @@ "main": "./dist/index.js", | ||
"text", | ||
"table" | ||
"table", | ||
"align", | ||
"ansi" | ||
], | ||
"scripts": { | ||
"test": "babel-node ./node_modules/.bin/gulp lint", | ||
"test": "babel-node ./node_modules/.bin/gulp test", | ||
"build": "babel-node ./node_modules/.bin/gulp build", | ||
@@ -48,4 +50,5 @@ "watch": "babel-node ./node_modules/.bin/gulp watch" | ||
"strip-ansi": "^3.0.0", | ||
"tv4": "^1.2.7", | ||
"xregexp": "slevithan/xregexp#baef6b6429fbd6f9aeb3c2c86a41b5422b023e18" | ||
} | ||
} |
363
README.md
@@ -6,20 +6,111 @@ # Table | ||
(This library is work in progress. The working library will be released in 2.0.0.) | ||
* [Features](#features) | ||
* [Usage](#usage) | ||
* [Custom Border](#custom-border) | ||
* [Predefined Border Templates](#predefined-border-templates) | ||
* [Minimum Column Width](#minimum-column-width) | ||
* [Maximum Column Width](#maximum-column-width) | ||
* [Cell Content Alignment](#cell-content-alignment) | ||
Formats data into a string table. | ||
Produces a string that represents array data in a text table. | ||
## 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). | ||
* Supports `minWidth`, `maxWidth` properties per column. | ||
* Supports expanding long cell values into multiple rows. | ||
* Custom border characters. | ||
* Content alignment. | ||
* Content padding. | ||
* Column `minWidth`. | ||
* Column `maxWidth`. | ||
* Expanding long cell values into multiple rows. | ||
## Usage | ||
### Basic Table | ||
Table data is described using an array (rows) of array (cells). | ||
Table data is described using an array of arrays. | ||
```js | ||
import table from '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~configColumn | ||
* @property {String} alignment Cell content alignment (enum: left, center, right) (default: left). | ||
* @property {Number} minWidth Minimum column width (default: 0). | ||
* @property {Number} maxWidth Maximum column width (default: Infinity). | ||
* @property {Number} paddingLeft Cell content padding width left (default: 0). | ||
* @property {Number} paddingRight Cell content padding width right (default: 0). | ||
*/ | ||
/** | ||
* @typedef {Object} table~configBorder | ||
* @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 | ||
*/ | ||
/** | ||
* @typedef {Object} table~config | ||
* @property {table~configBorder} | ||
* @property {table~configColumn[]} column Column specific configuration. | ||
*/ | ||
/** | ||
* 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║ | ||
╚══╧══╧══╝ | ||
``` | ||
### Custom Border | ||
`border` property describes the characters used to draw the table borders. | ||
```js | ||
let table = require('table'), | ||
data; | ||
let data, | ||
output, | ||
options; | ||
@@ -32,3 +123,257 @@ data = [ | ||
console.log(table(data)); | ||
options = { | ||
border: { | ||
topBody: `─`, | ||
topJoin: `┬`, | ||
topLeft: `┌`, | ||
topRight: `┐`, | ||
bottomBody: `─`, | ||
bottomJoin: `┴`, | ||
bottomLeft: `└`, | ||
bottomRight: `┘`, | ||
bodyLeft: `│`, | ||
bodyRight: `│`, | ||
bodyJoin: `│`, | ||
joinBody: `─`, | ||
joinLeft: `├`, | ||
joinRight: `┤`, | ||
joinJoin: `┼` | ||
} | ||
}; | ||
output = table(data, options); | ||
console.log(output); | ||
``` | ||
``` | ||
┌──┬──┬──┐ | ||
│0A│0B│0C│ | ||
├──┼──┼──┤ | ||
│1A│1B│1C│ | ||
├──┼──┼──┤ | ||
│2A│2B│2C│ | ||
└──┴──┴──┘ | ||
``` | ||
#### Predefined Border Templates | ||
You can load one of the predefined border templates using `border` function. | ||
```js | ||
import table from 'table'; | ||
import { | ||
border | ||
} from 'table'; | ||
let data; | ||
data = [ | ||
['0A', '0B', '0C'], | ||
['1A', '1B', '1C'], | ||
['2A', '2B', '2C'] | ||
]; | ||
table(data, { | ||
border: border(`name of the template`) | ||
}); | ||
``` | ||
``` | ||
# honeywell | ||
╔══╤══╤══╗ | ||
║0A│0B│0C║ | ||
╟──┼──┼──╢ | ||
║1A│1B│1C║ | ||
╟──┼──┼──╢ | ||
║2A│2B│2C║ | ||
╚══╧══╧══╝ | ||
# norc | ||
┌──┬──┬──┐ | ||
│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. | ||
### Minimum Column Width | ||
`minWidth` property pads the string to fill the cell. | ||
```js | ||
let data, | ||
output, | ||
options; | ||
data = [ | ||
['0A', '0B', '0C'], | ||
['1A', '1B', '1C'], | ||
['2A', '2B', '2C'] | ||
]; | ||
options = { | ||
column: { | ||
1: { | ||
minWidth: 10 | ||
} | ||
} | ||
}; | ||
output = table(data, options); | ||
console.log(output); | ||
``` | ||
``` | ||
╔══╤══════════╤══╗ | ||
║0A│0B │0C║ | ||
╟──┼──────────┼──╢ | ||
║1A│1B │1C║ | ||
╟──┼──────────┼──╢ | ||
║2A│2B │2C║ | ||
╚══╧══════════╧══╝ | ||
``` | ||
### Maximum Column Width | ||
`maxWidth` property makes the overflowing text break into multiple lines. | ||
```js | ||
let data, | ||
output, | ||
options; | ||
data = [ | ||
['0A', 'AAABBBCCC', '0C'], | ||
['1A', '1B', '1C'], | ||
['2A', '2B', '2C'] | ||
]; | ||
options = { | ||
column: { | ||
1: { | ||
maxWidth: 3 | ||
} | ||
} | ||
}; | ||
output = table(data, options); | ||
console.log(output); | ||
``` | ||
``` | ||
╔══╤═══╤══╗ | ||
║0A│AAA│0C║ | ||
║ │BBB│ ║ | ||
║ │CCC│ ║ | ||
╟──┼───┼──╢ | ||
║1A│1B │1C║ | ||
╟──┼───┼──╢ | ||
║2A│2B │2C║ | ||
╚══╧═══╧══╝ | ||
``` | ||
### Cell Content Alignment | ||
`alignment` property controls content horizontal alignment within a cell. | ||
Valid values are: "left", "right" and "center". | ||
```js | ||
let data, | ||
output, | ||
options; | ||
data = [ | ||
['0A', '0B', '0C'], | ||
['1A', '1B', '1C'], | ||
['2A', '2B', '2C'] | ||
]; | ||
options = { | ||
column: { | ||
0: { | ||
alignment: 'left', | ||
minWidth: 10 | ||
}, | ||
1: { | ||
alignment: 'center', | ||
minWidth: 10 | ||
}, | ||
2: { | ||
alignment: 'right', | ||
minWidth: 10 | ||
} | ||
} | ||
}; | ||
output = table(data, options); | ||
console.log(output); | ||
``` | ||
``` | ||
╔══════════╤══════════╤══════════╗ | ||
║0A │ 0B │ 0C║ | ||
╟──────────┼──────────┼──────────╢ | ||
║1A │ 1B │ 1C║ | ||
╟──────────┼──────────┼──────────╢ | ||
║2A │ 2B │ 2C║ | ||
╚══════════╧══════════╧══════════╝ | ||
``` | ||
### Padding Cell Content | ||
`paddingLeft` and `paddingRight` properties control content padding within a cell. Property value represents a number of whitespaces using to pad the content. | ||
```js | ||
let data, | ||
output, | ||
options; | ||
data = [ | ||
['0A', 'AABBCC', '0C'], | ||
['1A', '1B', '1C'], | ||
['2A', '2B', '2C'] | ||
]; | ||
options = { | ||
column: { | ||
0: { | ||
paddingLeft: 3 | ||
}, | ||
1: { | ||
maxWidth: 2, | ||
paddingRight: 3 | ||
} | ||
} | ||
}; | ||
output = table(data, options); | ||
console.log(output); | ||
``` | ||
``` | ||
╔═════╤═════╤══╗ | ||
║ 0A│AA │0C║ | ||
║ │BB │ ║ | ||
║ │CC │ ║ | ||
╟─────┼─────┼──╢ | ||
║ 1A│1B │1C║ | ||
╟─────┼─────┼──╢ | ||
║ 2A│2B │2C║ | ||
╚═════╧═════╧══╝ | ||
``` |
import _ from 'lodash'; | ||
import stringWith from 'string-width'; | ||
import stringWidth from 'string-width'; | ||
@@ -23,3 +23,3 @@ /** | ||
valueLength = stringWith(value); | ||
valueLength = stringWidth(value); | ||
@@ -26,0 +26,0 @@ if (_.isUndefined(columns[index0]) || columns[index0] < valueLength) { |
@@ -0,1 +1,8 @@ | ||
import border from './border/'; | ||
import table from './table'; | ||
export { | ||
border | ||
}; | ||
export default table; |
import _ from 'lodash'; | ||
import border from './border/'; | ||
import validateConfig from './validateConfig'; | ||
@@ -8,16 +9,33 @@ import calculateMaximumColumnValueIndex from './calculateMaximumColumnValueIndex'; | ||
* @param {Array[]} rows | ||
* @param {formatData~config} config | ||
* @return {formatData~config} | ||
* @param {Object} inputConfig | ||
* @return {Object} | ||
*/ | ||
export default (rows, config = {}) => { | ||
let maximumColumnValueIndex; | ||
export default (rows, inputConfig = {}) => { | ||
let config, | ||
maximumColumnValueIndex; | ||
config = _.cloneDeep(inputConfig); | ||
validateConfig(rows, config); | ||
if (!config.border) { | ||
config.border = {} | ||
} | ||
config.border = _.assign({}, border(`honeywell`), config.border); | ||
maximumColumnValueIndex = calculateMaximumColumnValueIndex(rows); | ||
config.columnConfig = config.columnConfig || Array(rows[0].length); | ||
if (!config.column) { | ||
config.column = {}; | ||
} | ||
config.columnConfig = _.map(config.columnConfig, (column = {}, index0) => { | ||
if (_.isUndefined(column.minWidth) || maximumColumnValueIndex[index0] > config.columnConfig[index0].minWidth) { | ||
_.times(rows[0].length, (index) => { | ||
if (_.isUndefined(config.column[index])) { | ||
config.column[index] = {}; | ||
} | ||
}); | ||
config.column = _.mapValues(config.column, (column, index0) => { | ||
if (_.isUndefined(column.minWidth) || maximumColumnValueIndex[index0] > config.column[index0].minWidth) { | ||
column.minWidth = maximumColumnValueIndex[index0]; | ||
@@ -36,2 +54,10 @@ } | ||
if (_.isUndefined(column.paddingLeft)) { | ||
column.paddingLeft = 0; | ||
} | ||
if (_.isUndefined(column.paddingRight)) { | ||
column.paddingRight = 0; | ||
} | ||
return column; | ||
@@ -38,0 +64,0 @@ }); |
132
src/table.js
import _ from 'lodash'; | ||
import drawTable from './drawTable'; | ||
import calculateColumnSizeIndex from './calculateColumnSizeIndex'; | ||
import makeConfig from './makeConfig'; | ||
import calculateRowSpanIndex from './calculateRowSpanIndex'; | ||
import mapDataUsingRowSpanIndex from './mapDataUsingRowSpanIndex'; | ||
import stringWidth from 'string-width'; | ||
import align from './align'; | ||
import validateData from './validateData'; | ||
import border from './border'; | ||
/** | ||
* @typedef {String} table~cell | ||
*/ | ||
import { | ||
drawBorderTop, | ||
drawBorderJoin, | ||
drawBorderBottom | ||
} from './drawBorder'; | ||
/** | ||
* @typedef {table~cell[]} table~row | ||
*/ | ||
import drawRow from './drawRow'; | ||
/** | ||
* @typedef {Object} table~configColumn | ||
* @property {String} alignment Cell content alignment (enum: left, center, right) (default: left). | ||
* @property {Number} minWidth Minimum column width (default: 0). | ||
* @property {Number} maxWidth Maximum column width (default: Infinity). | ||
* @property {Number} paddingLeft Cell content padding width left (default: 0). | ||
* @property {Number} paddingRight Cell content padding width right (default: 0). | ||
*/ | ||
import formatData from './formatData'; | ||
/** | ||
* @typedef {Object} table~configBorder | ||
* @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 | ||
*/ | ||
let drawTop, | ||
getColumnSizeIndex; | ||
/** | ||
* @typedef {Object} table~config | ||
* @property {table~configBorder} | ||
* @property {table~configColumn[]} column Column specific configuration. | ||
*/ | ||
/** | ||
* @param {String[]} columns | ||
* @return {Number[]} | ||
* Generates a text table. | ||
* | ||
* @param {table~row[]} rows | ||
* @param {table~config} config | ||
* @return {String} | ||
*/ | ||
getColumnSizeIndex = (columns) => { | ||
return _.map(columns, (data) => { | ||
return data.length; | ||
export default (rows, config = {}) => { | ||
let derivedConfig, | ||
safeData, | ||
rowSpanIndex, | ||
columnSizeIndex, | ||
dataMappedUsingRowSpanIndex, | ||
tableBorder; | ||
validateData(rows); | ||
safeData = _.map(rows, (columns) => { | ||
return _.map(columns, String); | ||
}); | ||
}; | ||
export default (data) => { | ||
let table, | ||
columnSizeIndex, | ||
rows; | ||
// console.log(`safeData`, safeData); | ||
rows = formatData(data); | ||
derivedConfig = makeConfig(safeData, config); | ||
columnSizeIndex = getColumnSizeIndex(rows[0]); | ||
// console.log(`derivedConfig`, derivedConfig); | ||
table = ''; | ||
table += drawBorderTop(columnSizeIndex, border); | ||
rowSpanIndex = calculateRowSpanIndex(safeData, derivedConfig); | ||
_.forEach(rows, (row, i) => { | ||
table += drawRow(row, border); | ||
// console.log(`rowSpanIndex`, rowSpanIndex); | ||
if (i + 1 !== rows.length) { | ||
table += drawBorderJoin(columnSizeIndex, border); | ||
} | ||
dataMappedUsingRowSpanIndex = mapDataUsingRowSpanIndex(safeData, rowSpanIndex, derivedConfig); | ||
// console.log(`dataMappedUsingRowSpanIndex`, dataMappedUsingRowSpanIndex); | ||
dataMappedUsingRowSpanIndex = _.map(dataMappedUsingRowSpanIndex, (cells, index0) => { | ||
return _.map(cells, (value, index1) => { | ||
let column; | ||
column = derivedConfig.column[index1]; | ||
// console.log(column); | ||
if (stringWidth(value) === column.maxWidth) { | ||
return value; | ||
} else { | ||
return align(value, column.minWidth, column.alignment); | ||
} | ||
}); | ||
}); | ||
table += drawBorderBottom(columnSizeIndex, border); | ||
dataMappedUsingRowSpanIndex = _.map(dataMappedUsingRowSpanIndex, (cells, index0) => { | ||
return _.map(cells, (value, index1) => { | ||
let column; | ||
return table; | ||
column = derivedConfig.column[index1]; | ||
return _.repeat(` `, column.paddingLeft) + value + _.repeat(` `, column.paddingRight); | ||
}); | ||
}); | ||
//_.times(config.column[index1].paddingLeft, ` `) | ||
columnSizeIndex = calculateColumnSizeIndex(dataMappedUsingRowSpanIndex[0]); | ||
// console.log(`columnSizeIndex`, columnSizeIndex); | ||
return drawTable(dataMappedUsingRowSpanIndex, derivedConfig.border, columnSizeIndex, rowSpanIndex); | ||
}; |
import _ from 'lodash'; | ||
import schema from './schemas/config.json'; | ||
import tv4 from 'tv4'; | ||
/** | ||
@@ -9,19 +13,21 @@ * @param {row[]} rows | ||
export default (rows, config = {}) => { | ||
let unknownPropertyName; | ||
let result; | ||
unknownPropertyName = _.first(_.difference(_.keys(config), [`columnConfig`])); | ||
result = tv4.validateResult(config, schema); | ||
if (unknownPropertyName) { | ||
throw new Error(`Config must not define unknown properties. "${unknownPropertyName}" is an unknown property.`); | ||
if (!result.valid) { | ||
console.log(`config`, config); | ||
console.log(`error`, { | ||
message: result.error.message, | ||
params: result.error.params, | ||
dataPath: result.error.dataPath, | ||
schemaPath: result.error.schemaPath | ||
}); | ||
throw new Error(`Invalid config.`); | ||
} | ||
if (config.columnConfig) { | ||
_.forEach(config.columnConfig, (columnConfig) => { | ||
unknownPropertyName = _.first(_.difference(_.keys(columnConfig), [`align`, `minWidth`, `maxWidth`])); | ||
if (unknownPropertyName) { | ||
throw new Error(`Column config must not define unknown properties. "${unknownPropertyName}" is an unknown property.`); | ||
} | ||
if (!_.isUndefined(columnConfig.minWidth) && !_.isUndefined(columnConfig.maxWidth) && columnConfig.minWidth > columnConfig.maxWidth) { | ||
if (config.column) { | ||
_.forEach(config.column, (column) => { | ||
if (!_.isUndefined(column.minWidth) && !_.isUndefined(column.maxWidth) && column.minWidth > column.maxWidth) { | ||
throw new Error(`Column minWidth cannot be greater than maxWidth.`); | ||
@@ -28,0 +34,0 @@ } |
@@ -12,18 +12,19 @@ /* eslint-disable max-nested-callbacks */ | ||
describe(`makeConfig`, () => { | ||
context(`column specific alignment is not provided`, () => { | ||
it(`defaults to 'left'`, () => { | ||
let config; | ||
it(`does not affect the parameter configuration object`, () => { | ||
let config; | ||
config = makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
]); | ||
config = {}; | ||
expect(config.columnConfig[0].alignment).to.equal(`left`); | ||
}); | ||
makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
], config); | ||
expect(config).to.deep.equal({}); | ||
}); | ||
context(`column specific minWidth is not provided`, () => { | ||
context(`maxWidth is not set`, () => { | ||
it(`uses the maximum value length`, () => { | ||
context(`column`, () => { | ||
context(`alignment is not provided`, () => { | ||
it(`defaults to 'left'`, () => { | ||
let config; | ||
@@ -37,7 +38,46 @@ | ||
expect(config.columnConfig[0].minWidth).to.equal(5); | ||
expect(config.column[0].alignment).to.equal(`left`); | ||
}); | ||
}); | ||
context(`maxWidth is set`, () => { | ||
context(`maxWidth is larger than maximum value length`, () => { | ||
context(`maxWidth is not provided`, () => { | ||
it(`defaults to Infinity`, () => { | ||
let config; | ||
config = makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
]); | ||
expect(config.column[0].maxWidth).to.equal(Infinity); | ||
}); | ||
}); | ||
context(`paddingLeft is not provided`, () => { | ||
it(`defaults to 0`, () => { | ||
let config; | ||
config = makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
]); | ||
expect(config.column[0].paddingLeft).to.equal(0); | ||
}); | ||
}); | ||
context(`paddingRight is not provided`, () => { | ||
it(`defaults to Infinity`, () => { | ||
let config; | ||
config = makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
]); | ||
expect(config.column[0].paddingRight).to.equal(0); | ||
}); | ||
}); | ||
context(`minWidth is not provided`, () => { | ||
context(`maxWidth is not set`, () => { | ||
it(`uses the maximum value length`, () => { | ||
@@ -50,15 +90,51 @@ let config; | ||
] | ||
], { | ||
columnConfig: [ | ||
{ | ||
maxWidth: 10 | ||
]); | ||
expect(config.column[0].minWidth).to.equal(5); | ||
}); | ||
}); | ||
context(`maxWidth is set`, () => { | ||
context(`maxWidth is larger than maximum value length`, () => { | ||
it(`uses the maximum value length`, () => { | ||
let config; | ||
config = makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
], { | ||
column: { | ||
0: { | ||
maxWidth: 10 | ||
} | ||
} | ||
] | ||
}); | ||
expect(config.column[0].minWidth).to.equal(5); | ||
}); | ||
}); | ||
context(`maxWidth is lesser than maximum value length`, () => { | ||
it(`uses the maxWidth value`, () => { | ||
let config; | ||
expect(config.columnConfig[0].minWidth).to.equal(5); | ||
config = makeConfig([ | ||
[ | ||
`aaaaaaaaaa` | ||
] | ||
], { | ||
column: { | ||
0: { | ||
maxWidth: 5 | ||
} | ||
} | ||
}); | ||
expect(config.column[0].minWidth).to.equal(5); | ||
}); | ||
}); | ||
}); | ||
context(`maxWidth is lesser than maximum value length`, () => { | ||
it(`uses the maxWidth value`, () => { | ||
}); | ||
context(`minWidth is provided`, () => { | ||
context(`minWidth is larger than maximum value length`, () => { | ||
it(`uses the maximum value length`, () => { | ||
let config; | ||
@@ -68,54 +144,33 @@ | ||
[ | ||
`aaaaaaaaaa` | ||
`aaaaa` | ||
] | ||
], { | ||
columnConfig: [ | ||
{ | ||
maxWidth: 5 | ||
column: { | ||
0: { | ||
minWidth: 10 | ||
} | ||
] | ||
} | ||
}); | ||
expect(config.columnConfig[0].minWidth).to.equal(5); | ||
expect(config.column[0].minWidth).to.deep.equal(10); | ||
}); | ||
}); | ||
}); | ||
}); | ||
context(`column specific minWidth is provided`, () => { | ||
context(`column specific minWidth is larger than maximum value length`, () => { | ||
it(`uses the maximum value length`, () => { | ||
let config; | ||
context(`minWidth is smaller than maximum value length`, () => { | ||
it(`uses the maximum value length`, () => { | ||
let config; | ||
config = makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
], { | ||
columnConfig: [ | ||
{ | ||
minWidth: 10 | ||
config = makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
], { | ||
column: { | ||
0: { | ||
minWidth: 2 | ||
} | ||
} | ||
] | ||
}); | ||
}); | ||
expect(_.pluck(config.columnConfig, `minWidth`)).to.deep.equal([10]); | ||
}); | ||
}); | ||
context(`column specific minWidth is smaller than maximum value length`, () => { | ||
it(`uses the maximum value length`, () => { | ||
let config; | ||
config = makeConfig([ | ||
[ | ||
`aaaaa` | ||
] | ||
], { | ||
columnConfig: [ | ||
{ | ||
minWidth: 2 | ||
} | ||
] | ||
expect(config.column[0].minWidth).to.deep.equal(5); | ||
}); | ||
expect(_.pluck(config.columnConfig, `minWidth`)).to.deep.equal([5]); | ||
}); | ||
@@ -122,0 +177,0 @@ }); |
@@ -9,3 +9,3 @@ import { | ||
describe(`table`, () => { | ||
xdescribe(`table`, () => { | ||
let expectTable; | ||
@@ -12,0 +12,0 @@ |
@@ -10,25 +10,3 @@ /* eslint-disable max-nested-callbacks */ | ||
describe(`validateConfig`, () => { | ||
context(`config defines an unknown property`, () => { | ||
it(`throws an error`, () => { | ||
expect(() => { | ||
validateConfig([[`a`]], { | ||
unknownProperty: true | ||
}); | ||
}).to.throw(Error, `Config must not define unknown properties. "unknownProperty" is an unknown property.`); | ||
}); | ||
}); | ||
context(`columnConfig`, () => { | ||
context(`config defines an unknown property`, () => { | ||
it(`throws an error`, () => { | ||
expect(() => { | ||
validateConfig([[`a`]], { | ||
columnConfig: [ | ||
{ | ||
unknownProperty: true | ||
} | ||
] | ||
}); | ||
}).to.throw(Error, `Column config must not define unknown properties. "unknownProperty" is an unknown property.`); | ||
}); | ||
}); | ||
context(`column`, () => { | ||
context(`column specific minWidth and maxWidth are provided`, () => { | ||
@@ -39,8 +17,8 @@ context(`minWidth is greater than maxWidth`, () => { | ||
validateConfig([[`a`]], { | ||
columnConfig: [ | ||
{ | ||
column: { | ||
0: { | ||
minWidth: 10, | ||
maxWidth: 5 | ||
} | ||
] | ||
} | ||
}); | ||
@@ -47,0 +25,0 @@ }).to.throw(Error, `Column minWidth cannot be greater than maxWidth.`); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
118901
63
2307
378
1
8
+ Addedtv4@^1.2.7
+ Addedtv4@1.3.0(transitive)