column-layout
Advanced tools
Comparing version 1.1.3 to 1.2.0
@@ -8,2 +8,3 @@ #!/usr/bin/env node | ||
var o = require('object-tools') | ||
var t = require('typical') | ||
@@ -17,3 +18,4 @@ var cli = cliArgs([ | ||
{ name: 'padding-right', type: String, alias: 'r', | ||
description: "One or more characters to pad the right of each column. Defaults to ' '." } | ||
description: "One or more characters to pad the right of each column. Defaults to ' '." }, | ||
{ name: 'lines', type: Boolean, description: 'return an array of lines' } | ||
]) | ||
@@ -51,9 +53,10 @@ var options = cli.parse() | ||
} | ||
if (options['padding-left']) clOptions.padding.left = options['padding-left'] | ||
if (options['padding-right']) clOptions.padding.right = options['padding-right'] | ||
if (t.isDefined(options['padding-left'])) clOptions.padding.left = options['padding-left'] | ||
if (t.isDefined(options['padding-right'])) clOptions.padding.right = options['padding-right'] | ||
/* split input into data and options */ | ||
if (!Array.isArray(json)) { | ||
if (json.options && json.data) { | ||
clOptions = o.extend(json.options, clOptions) | ||
clOptions = o.extend(clOptions, json.options) | ||
json = json.data | ||
@@ -66,3 +69,5 @@ } else { | ||
if (columns.length) clOptions.columns = columns | ||
return columnLayout(json, clOptions) | ||
return options.lines | ||
? JSON.stringify(columnLayout.lines(json, clOptions), null, ' ') + '\n' | ||
: columnLayout(json, clOptions) | ||
})) | ||
@@ -69,0 +74,0 @@ .on('error', function (err) { |
'use strict'; | ||
require('core-js/es6/array'); | ||
require('core-js/es6/weak-map'); | ||
var Table = require('./table'); | ||
var Columns = require('./columns'); | ||
@@ -15,2 +17,8 @@ module.exports = columnLayout; | ||
return table.renderLines(); | ||
}; | ||
}; | ||
columnLayout.table = function (data, options) { | ||
return new Table(data, options); | ||
}; | ||
columnLayout.Columns = Columns; |
@@ -12,3 +12,6 @@ 'use strict'; | ||
var t = require('typical'); | ||
var Padding = require('./padding'); | ||
var _viewWidth = new WeakMap(); | ||
var Columns = (function (_Array) { | ||
@@ -70,3 +73,3 @@ _inherits(Columns, _Array); | ||
columns.forEach(function (column) { | ||
_this.push(column); | ||
_this.push(column instanceof Column ? column : new Column(column)); | ||
}); | ||
@@ -84,7 +87,9 @@ } | ||
key: 'autoSize', | ||
value: function autoSize(viewWidth) { | ||
value: function autoSize() { | ||
var _this2 = this; | ||
var viewWidth = _viewWidth.get(this); | ||
this.forEach(function (column) { | ||
column.generatedWidth = column.width || column.contentWidth + column.padding.length(); | ||
return column.generateWidth(); | ||
}); | ||
@@ -100,3 +105,7 @@ | ||
if (width.diff) { | ||
if (width.diff > 0) { | ||
var grownColumns; | ||
var shrunkenColumns; | ||
var salvagedSpace; | ||
(function () { | ||
@@ -107,11 +116,33 @@ var resizableColumns = _this2.getResizable(); | ||
}); | ||
grownColumns = _this2.filter(function (column) { | ||
return column.generatedWidth > column.contentWidth; | ||
}); | ||
shrunkenColumns = _this2.filter(function (column) { | ||
return column.generatedWidth < column.contentWidth; | ||
}); | ||
salvagedSpace = 0; | ||
grownColumns.forEach(function (column) { | ||
var currentGeneratedWidth = column.generatedWidth; | ||
column.generateWidth(); | ||
salvagedSpace += currentGeneratedWidth - column.generatedWidth; | ||
}); | ||
shrunkenColumns.forEach(function (column) { | ||
column.generatedWidth += Math.floor(salvagedSpace / shrunkenColumns.length); | ||
}); | ||
_this2.forEach(function (column) { | ||
if (t.isDefined(column.maxWidth) && column.generatedWidth > column.maxWidth) { | ||
column.generatedWidth = column.maxWidth; | ||
} | ||
}); | ||
})(); | ||
} | ||
this.forEach(function (column) { | ||
if (t.isDefined(column.maxWidth) && column.generatedWidth > column.maxWidth) { | ||
column.generatedWidth = column.maxWidth; | ||
} | ||
}); | ||
} | ||
}, { | ||
key: 'viewWidth', | ||
set: function set(val) { | ||
_viewWidth.set(this, val); | ||
} | ||
}]); | ||
@@ -122,2 +153,4 @@ | ||
var _padding = new WeakMap(); | ||
var Column = (function () { | ||
@@ -127,5 +160,11 @@ function Column(column) { | ||
for (var prop in column) { | ||
this[prop] = column[prop]; | ||
} | ||
if (t.isDefined(column.name)) this.name = column.name; | ||
if (t.isDefined(column.width)) this.width = column.width; | ||
if (t.isDefined(column.maxWidth)) this.maxWidth = column.maxWidth; | ||
if (t.isDefined(column.nowrap)) this.nowrap = column.nowrap; | ||
if (t.isDefined(column['break'])) this['break'] = column['break']; | ||
if (t.isDefined(column.contentWrappable)) this.contentWrappable = column.contentWrappable; | ||
if (t.isDefined(column.contentWidth)) this.contentWidth = column.contentWidth; | ||
this.padding = column.padding || { left: ' ', right: ' ' }; | ||
this.generatedWidth = null; | ||
} | ||
@@ -143,2 +182,20 @@ | ||
} | ||
}, { | ||
key: 'generateWidth', | ||
value: function generateWidth() { | ||
this.generatedWidth = this.width || this.contentWidth + this.padding.length(); | ||
} | ||
}, { | ||
key: 'padding', | ||
set: function set(padding) { | ||
_padding.set(this, new Padding(padding)); | ||
}, | ||
get: function get() { | ||
return _padding.get(this); | ||
} | ||
}, { | ||
key: 'wrappedContentWidth', | ||
get: function get() { | ||
return this.generatedWidth - this.padding.length(); | ||
} | ||
}]); | ||
@@ -145,0 +202,0 @@ |
@@ -14,20 +14,2 @@ 'use strict'; | ||
var Padding = (function () { | ||
function Padding(padding) { | ||
_classCallCheck(this, Padding); | ||
this.left = padding.left; | ||
this.right = padding.right; | ||
} | ||
_createClass(Padding, [{ | ||
key: 'length', | ||
value: function length() { | ||
return this.left.length + this.right.length; | ||
} | ||
}]); | ||
return Padding; | ||
})(); | ||
var Table = (function () { | ||
@@ -49,5 +31,12 @@ function Table(data, options) { | ||
this.columns.viewWidth = options.viewWidth; | ||
this.columns.forEach(function (column) { | ||
column.padding = new Padding(options.padding); | ||
if (options.padding) column.padding = options.padding; | ||
if (options.nowrap) column.nowrap = options.nowrap; | ||
if (options['break']) { | ||
column['break'] = options['break']; | ||
column.contentWrappable = true; | ||
} | ||
}); | ||
options.columns.forEach(function (optionColumn) { | ||
@@ -70,3 +59,3 @@ var column = _this.columns.get(optionColumn.name); | ||
this.columns.autoSize(options.viewWidth); | ||
this.columns.autoSize(); | ||
} | ||
@@ -84,2 +73,9 @@ | ||
var cell = row[column.name]; | ||
if (!t.isString(cell)) { | ||
if (!t.isDefined(cell)) { | ||
cell = ''; | ||
} else { | ||
cell = String(cell); | ||
} | ||
} | ||
if (column.nowrap) { | ||
@@ -86,0 +82,0 @@ line.push(cell.split(/\r\n?|\n/)); |
'use strict' | ||
require('core-js/es6/array') | ||
require('core-js/es6/weak-map') | ||
var Table = require('./table') | ||
var Columns = require('./columns') | ||
@@ -16,2 +18,4 @@ /** | ||
@param [options.viewWidth] {number} - maximum width of layout | ||
@param [options.nowrap] {boolean} - disable wrapping on all columns | ||
@param [options.break] {boolean} - enable breaking on all columns | ||
@param [options.columns] {module:column-layout~columnOption} - array of column options | ||
@@ -57,2 +61,7 @@ @param [options.padding] {object} - Padding values to set on each column. Per-column overrides can be set in the `options.columns` array. | ||
columnLayout.table = function (data, options) { | ||
return new Table(data, options) | ||
} | ||
/** | ||
@@ -63,2 +72,3 @@ * @typedef module:column-layout~columnOption | ||
* @property [nowrap] {boolean} - disable wrapping for this column | ||
* @property [break] {boolean} - enable breaking on all columns | ||
* @property [padding] {object} - padding options | ||
@@ -68,1 +78,3 @@ * @property [padding.left] {string} - a string to pad the left of each cell (default: `" "`) | ||
*/ | ||
columnLayout.Columns = Columns |
'use strict' | ||
var t = require('typical') | ||
var Padding = require('./padding') | ||
var _viewWidth = new WeakMap() | ||
class Columns extends Array { | ||
@@ -33,3 +36,3 @@ constructor (columns) { | ||
columns.forEach(column => { | ||
this.push(column) | ||
this.push(column instanceof Column ? column : new Column(column)) | ||
}) | ||
@@ -45,9 +48,15 @@ } | ||
autoSize (viewWidth) { | ||
set viewWidth (val) { | ||
_viewWidth.set(this, val) | ||
} | ||
/** | ||
* sets `generatedWidth` for each column | ||
*/ | ||
autoSize () { | ||
var viewWidth = _viewWidth.get(this) | ||
/* size */ | ||
this.forEach(column => { | ||
column.generatedWidth = column.width || (column.contentWidth + column.padding.length()) | ||
}) | ||
this.forEach(column => column.generateWidth()) | ||
/* adjust if short of space */ | ||
var width = { | ||
@@ -60,4 +69,6 @@ total: this.totalWidth(), | ||
} | ||
if (width.diff) { | ||
// console.log(width); | ||
/* adjust if short of space */ | ||
if (width.diff > 0) { | ||
/* share the available space between resizeable columns */ | ||
let resizableColumns = this.getResizable() | ||
@@ -67,20 +78,54 @@ resizableColumns.forEach(column => { | ||
}) | ||
/* at this point, the generatedWidth should never end up bigger than the contentWidth */ | ||
var grownColumns = this.filter(column => column.generatedWidth > column.contentWidth) | ||
var shrunkenColumns = this.filter(column => column.generatedWidth < column.contentWidth) | ||
var salvagedSpace = 0 | ||
grownColumns.forEach(column => { | ||
var currentGeneratedWidth = column.generatedWidth | ||
column.generateWidth() | ||
salvagedSpace += currentGeneratedWidth - column.generatedWidth | ||
}) | ||
shrunkenColumns.forEach(column => { | ||
column.generatedWidth += Math.floor(salvagedSpace / shrunkenColumns.length) | ||
}) | ||
/* adjust if user set a maxWidth */ | ||
this.forEach(column => { | ||
if (t.isDefined(column.maxWidth) && column.generatedWidth > column.maxWidth) { | ||
column.generatedWidth = column.maxWidth | ||
} | ||
}) | ||
/* need a minWidth to stop breakable columns getting too short */ | ||
} | ||
/* adjust if user set a maxWidth */ | ||
this.forEach(column => { | ||
if (t.isDefined(column.maxWidth) && column.generatedWidth > column.maxWidth) { | ||
column.generatedWidth = column.maxWidth | ||
} | ||
}) | ||
} | ||
} | ||
var _padding = new WeakMap() | ||
class Column { | ||
constructor (column) { | ||
for (let prop in column) { | ||
this[prop] = column[prop] | ||
} | ||
if (t.isDefined(column.name)) this.name = column.name | ||
if (t.isDefined(column.width)) this.width = column.width | ||
if (t.isDefined(column.maxWidth)) this.maxWidth = column.maxWidth | ||
if (t.isDefined(column.nowrap)) this.nowrap = column.nowrap | ||
if (t.isDefined(column.break)) this.break = column.break | ||
if (t.isDefined(column.contentWrappable)) this.contentWrappable = column.contentWrappable | ||
if (t.isDefined(column.contentWidth)) this.contentWidth = column.contentWidth | ||
this.padding = column.padding || { left: ' ', right: ' ' } | ||
this.generatedWidth = null | ||
} | ||
set padding (padding) { | ||
_padding.set(this, new Padding(padding)) | ||
} | ||
get padding () { | ||
return _padding.get(this) | ||
} | ||
get wrappedContentWidth () { | ||
return this.generatedWidth - this.padding.length() | ||
} | ||
isResizable () { | ||
@@ -93,2 +138,6 @@ return !this.isFixed() | ||
} | ||
generateWidth () { | ||
this.generatedWidth = this.width || (this.contentWidth + this.padding.length()) | ||
} | ||
} | ||
@@ -95,0 +144,0 @@ |
@@ -38,2 +38,3 @@ 'use strict' | ||
if (!column.contentWrappable) column.contentWrappable = /\s+/.test(cellValue) | ||
// row[prop] = cellValue | ||
} | ||
@@ -40,0 +41,0 @@ }) |
@@ -9,12 +9,2 @@ 'use strict' | ||
class Padding { | ||
constructor (padding) { | ||
this.left = padding.left | ||
this.right = padding.right | ||
} | ||
length () { | ||
return this.left.length + this.right.length | ||
} | ||
} | ||
/** | ||
@@ -27,2 +17,5 @@ * @class | ||
constructor (data, options) { | ||
// TODO: HANDLE EMPTY data [] | ||
/* defaults */ | ||
options = options || {} | ||
@@ -41,5 +34,13 @@ if (!options.padding) options.padding = {} | ||
/* load values from options */ | ||
this.columns.viewWidth = options.viewWidth | ||
this.columns.forEach(column => { | ||
column.padding = new Padding(options.padding) | ||
if (options.padding) column.padding = options.padding | ||
if (options.nowrap) column.nowrap = options.nowrap | ||
if (options.break) { | ||
column.break = options.break | ||
column.contentWrappable = true | ||
} | ||
}) | ||
/* load values from options.columns */ | ||
options.columns.forEach(optionColumn => { | ||
@@ -62,3 +63,4 @@ let column = this.columns.get(optionColumn.name) | ||
this.columns.autoSize(options.viewWidth) | ||
this.columns.autoSize() | ||
// console.log(this.columns); | ||
} | ||
@@ -72,2 +74,9 @@ | ||
let cell = row[column.name] | ||
if (!t.isString(cell)) { | ||
if (!t.isDefined(cell)) { | ||
cell = '' | ||
} else { | ||
cell = String(cell) | ||
} | ||
} | ||
if (column.nowrap) { | ||
@@ -74,0 +83,0 @@ line.push(cell.split(/\r\n?|\n/)) |
{ | ||
"name": "column-layout", | ||
"author": "Lloyd Brookes <75pound@gmail.com>", | ||
"version": "1.1.3", | ||
"version": "1.2.0", | ||
"description": "Pretty-print JSON data in columns.", | ||
@@ -23,6 +23,6 @@ "repository": "https://github.com/75lb/column-layout.git", | ||
"scripts": { | ||
"test": "tape test/columnLayout.js", | ||
"lint": "jshint lib/*.js bin/*.js test/*.js; echo", | ||
"test": "tape test/*.js", | ||
"docs": "jsdoc2md -t jsdoc2md/README.hbs lib/*.js > README.md; echo", | ||
"es5": "babel --no-comments lib --out-dir es5" | ||
"es5": "babel --no-comments lib --out-dir es5", | ||
"cover": "istanbul cover tape -- test/*.js && cat coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf coverage; echo" | ||
}, | ||
@@ -42,2 +42,3 @@ "dependencies": { | ||
"devDependencies": { | ||
"coveralls": "^2.11.4", | ||
"jsdoc-to-markdown": "^1.1.1", | ||
@@ -44,0 +45,0 @@ "tape": "^4.0.0" |
[![view on npm](http://img.shields.io/npm/v/column-layout.svg)](https://www.npmjs.org/package/column-layout) | ||
[![npm module downloads](http://img.shields.io/npm/dt/column-layout.svg)](https://www.npmjs.org/package/column-layout) | ||
[![Build Status](https://travis-ci.org/75lb/column-layout.svg?branch=master)](https://travis-ci.org/75lb/column-layout) | ||
[![Coverage Status](https://coveralls.io/repos/75lb/column-layout/badge.svg?branch=master&service=github)](https://coveralls.io/github/75lb/column-layout?branch=master) | ||
[![Dependency Status](https://david-dm.org/75lb/column-layout.svg)](https://david-dm.org/75lb/column-layout) | ||
@@ -130,2 +131,4 @@ [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](https://github.com/feross/standard) | ||
| [options.viewWidth] | <code>number</code> | maximum width of layout | | ||
| [options.nowrap] | <code>boolean</code> | disable wrapping on all columns | | ||
| [options.break] | <code>boolean</code> | enable breaking on all columns | | ||
| [options.columns] | <code>[columnOption](#module_column-layout--columnLayout..columnOption)</code> | array of column options | | ||
@@ -174,2 +177,3 @@ | [options.padding] | <code>object</code> | Padding values to set on each column. Per-column overrides can be set in the `options.columns` array. | | ||
| nowrap | <code>boolean</code> | disable wrapping for this column | | ||
| break | <code>boolean</code> | enable breaking on all columns | | ||
| padding | <code>object</code> | padding options | | ||
@@ -176,0 +180,0 @@ | padding.left | <code>string</code> | a string to pad the left of each cell (default: `" "`) | |
@@ -6,12 +6,21 @@ 'use strict' | ||
test('columnLayout(data, options)', function (t) { | ||
var data = [ | ||
{ one: 'row 1 column one .. .. ..', two: 'r1 c2' }, | ||
{ one: 'r2 c1', two: 'row two column 2' } | ||
var fixture = require('./fixture/simple-viewWidth') | ||
var result = | ||
'<row 1 column one .. ><r1 c2 >\n\ | ||
<.. .. >< >\n\ | ||
<r2 c1 ><row two column 2>\n\ | ||
' | ||
t.strictEqual(columnLayout(fixture.data, fixture.options), result) | ||
t.end() | ||
}) | ||
test('columnLayout.lines(data, options)', function (t) { | ||
var fixture = require('./fixture/simple-viewWidth') | ||
var result = [ | ||
"<row 1 column one .. ><r1 c2 >", | ||
"<.. .. >< >", | ||
"<r2 c1 ><row two column 2>" | ||
] | ||
t.strictEqual( | ||
columnLayout(data, { viewWidth: 40 }), | ||
' row 1 column one r1 c2 \n .. .. .. \n r2 c1 row two column 2 \n' | ||
) | ||
t.deepEqual(columnLayout.lines(fixture.data, fixture.options), result) | ||
t.end() | ||
@@ -21,17 +30,11 @@ }) | ||
test('columnLayout.lines(data, options)', function (t) { | ||
var data = [ | ||
{ one: 'row 1 column one .. .. ..', two: 'r1 c2' }, | ||
{ one: 'r2 c1', two: 'row two column 2' } | ||
var fixture = require('./fixture/primatives') | ||
var result = [ | ||
"<row 1 column one .. .. ..><3000>", | ||
"<true ><null>", | ||
"<[object Object] >< >" | ||
] | ||
t.deepEqual( | ||
columnLayout.lines(data, { viewWidth: 40 }), | ||
[ | ||
' row 1 column one r1 c2 ', | ||
' .. .. .. ', | ||
' r2 c1 row two column 2 ' | ||
] | ||
) | ||
t.deepEqual(columnLayout.lines(fixture.data, fixture.options), result) | ||
t.end() | ||
}) |
'use strict' | ||
var test = require('tape') | ||
var Columns = require('../lib/columns') | ||
var Columns = require('../').Columns | ||
test('new Columns(columns)', function (t) { | ||
var data = [ | ||
{ name: 'one', width: 6 } | ||
] | ||
var columns = new Columns(data) | ||
t.deepEqual(columns, columns) | ||
t.end() | ||
}) | ||
test('columns.autoSize(contentColumns, viewWidth)', function (t) { | ||
@@ -21,73 +11,8 @@ var columns = new Columns([ | ||
columns.autoSize(30) | ||
t.deepEqual(columns, [ | ||
{ name: 'one', contentWidth: 10, contentWrappable: true, generatedWidth: 10 }, | ||
{ name: 'two', contentWidth: 20, contentWrappable: true, generatedWidth: 20 } | ||
]) | ||
columns.viewWidth = 30 | ||
columns.autoSize() | ||
t.strictEqual(columns[0].generatedWidth, 12) | ||
t.strictEqual(columns[1].generatedWidth, 18) | ||
columns.autoSize(20) | ||
t.deepEqual(columns, [ | ||
{ name: 'one', contentWidth: 10, contentWrappable: true, generatedWidth: 10 }, | ||
{ name: 'two', contentWidth: 20, contentWrappable: true, generatedWidth: 10 } | ||
]) | ||
t.deepEqual(columns, [ | ||
{ name: 'one', contentWidth: 10, contentWrappable: true, generatedWidth: 5, width: 5 }, | ||
{ name: 'two', contentWidth: 20, contentWrappable: true, generatedWidth: 15 } | ||
]) | ||
t.deepEqual(columns, [ | ||
{ name: 'one', contentWidth: 12, contentWrappable: false, generatedWidth: 12 }, | ||
{ name: 'two', contentWidth: 20, contentWrappable: true, generatedWidth: 8 } | ||
]) | ||
t.deepEqual(columns, [ | ||
{ name: 'one', contentWidth: 12, contentWrappable: true, generatedWidth: 12, nowrap: true }, | ||
{ name: 'two', contentWidth: 20, contentWrappable: true, generatedWidth: 8 } | ||
]) | ||
t.end() | ||
}) | ||
test.skip('columns.fromRows(rows) 5, with viewWidth', function (t) { | ||
var columns = new Columns({ viewWidth: 50 }) | ||
columns.fromRows(fixture.rows5) | ||
t.deepEqual(columns, [ | ||
{ name: 'one', width: 5 }, | ||
{ name: 'two', width: 5 }, | ||
{ name: 'three', width: 40 } | ||
]) | ||
t.end() | ||
}) | ||
test.skip('columns.fromRows(rows), with viewWidth, 2 wrappable columns', function (t) { | ||
var columns = new Columns({ viewWidth: 10 }) | ||
var rows = [ | ||
{ | ||
one: "one four seven", | ||
two: "four seven eleven" | ||
} | ||
] | ||
columns.fromRows(rows) | ||
t.deepEqual(columns, [ | ||
{ name: 'one', width: 5 }, | ||
{ name: 'two', width: 5 } | ||
]) | ||
t.end() | ||
}) | ||
test.skip('columns.fromRows(rows), with viewWidth, 1 wrappable columns', function (t) { | ||
var columns = new Columns({ viewWidth: 20 }) | ||
var rows = [ | ||
{ | ||
one: "one four seven eight", | ||
two: ".............." | ||
} | ||
] | ||
columns.fromRows(rows) | ||
t.deepEqual(columns, [ | ||
{ name: 'one', width: 6 }, | ||
{ name: 'two', width: 14 } | ||
]) | ||
t.end() | ||
}) |
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
89403
39
185
3
1907