Comparing version 2.5.2 to 2.5.3
@@ -36,5 +36,5 @@ //var Table = require('cli-table'); | ||
var vertical_table = new Table({ | ||
style : { | ||
head : ['green'] | ||
} | ||
style : { | ||
head : ['green'] | ||
} | ||
}); | ||
@@ -41,0 +41,0 @@ vertical_table.push({ "Some Key": "Some Value"}, |
@@ -5,17 +5,17 @@ var Chalk = require('chalk'); | ||
var header = [ | ||
{ | ||
value : "item", | ||
formatter : function(value){ | ||
return Chalk.cyan(value); | ||
}, | ||
width : 10 | ||
}, | ||
{ | ||
value : "price", | ||
width : 10 | ||
}, | ||
{ | ||
value : "organic", | ||
width : 10 | ||
} | ||
{ | ||
value : "item", | ||
formatter : function(value){ | ||
return Chalk.cyan(value); | ||
}, | ||
width : 10 | ||
}, | ||
{ | ||
value : "price", | ||
width : 10 | ||
}, | ||
{ | ||
value : "organic", | ||
width : 10 | ||
} | ||
]; | ||
@@ -25,12 +25,12 @@ | ||
var t1 = Table(header,[],{ | ||
borderStyle : 1, | ||
paddingBottom : 0, | ||
headerAlign : "center", | ||
align : "center", | ||
color : "green", | ||
truncate : "..." | ||
borderStyle : 1, | ||
paddingBottom : 0, | ||
headerAlign : "center", | ||
align : "center", | ||
color : "green", | ||
truncate : "..." | ||
}); | ||
t1.push( | ||
["chocolate cake",4.65,"no"] | ||
["chocolate cake",4.65,"no"] | ||
); | ||
@@ -43,12 +43,12 @@ | ||
var t2 = Table(header,[],{ | ||
borderStyle : 1, | ||
paddingBottom : 0, | ||
headerAlign : "center", | ||
align : "center", | ||
color : "green", | ||
truncate : "..." | ||
borderStyle : 1, | ||
paddingBottom : 0, | ||
headerAlign : "center", | ||
align : "center", | ||
color : "green", | ||
truncate : "..." | ||
}); | ||
t2.push( | ||
["pound cake",123456789123456789,"no"] | ||
["pound cake",123456789123456789,"no"] | ||
); | ||
@@ -61,13 +61,13 @@ | ||
var t3 = Table(header,[],{ | ||
borderStyle : 1, | ||
paddingLeft : 2, | ||
paddingRight: 2, | ||
headerAlign : "center", | ||
align : "center", | ||
color : "green", | ||
truncate : "..." | ||
borderStyle : 1, | ||
paddingLeft : 2, | ||
paddingRight: 2, | ||
headerAlign : "center", | ||
align : "center", | ||
color : "green", | ||
truncate : "..." | ||
}); | ||
t3.push( | ||
["pound cake",123456789123456789,"no"] | ||
["pound cake",123456789123456789,"no"] | ||
); | ||
@@ -74,0 +74,0 @@ |
var Table = require('../'); | ||
var header = [ | ||
{ | ||
value : "项目", | ||
}, | ||
{ | ||
value : "价格", | ||
width: 6 | ||
}, | ||
{ | ||
value : "有机", | ||
maxWidth: 3 | ||
} | ||
{ | ||
value : "项目", | ||
}, | ||
{ | ||
value : "价格", | ||
}, | ||
{ | ||
value : "有机", | ||
} | ||
]; | ||
var rows = [ | ||
["汉堡包",2.50,null], | ||
["特制的酱汁",0.10], | ||
["2玉米饼, 大米和豆类, 奶酪",9.80,""], | ||
["苹果片",1.00,"yes"], | ||
[null,1.50,"no"], | ||
["意大利粉, 火腿, 意大利干酪",3.75,"no"] | ||
["汉堡包",2.50,null], | ||
["特制的酱汁",0.10], | ||
["2玉米饼, 大米和豆类, 奶酪",9.80,""], | ||
["苹果片",1.00,"yes"], | ||
[null,1.50,"no"], | ||
["意大利粉, 火腿, 意大利干酪",3.75,"no"] | ||
]; | ||
var t1 = Table(header,rows,{ | ||
borderStyle : 1, | ||
paddingBottom : 0, | ||
paddingLeft: 0, | ||
paddingRight: 0, | ||
headerAlign : "right", | ||
align : "center", | ||
color : "white" | ||
borderStyle : 1, | ||
paddingBottom : 0, | ||
paddingLeft: 2, | ||
paddingRight: 1, | ||
headerAlign : "right", | ||
align : "center", | ||
color : "white" | ||
}); | ||
@@ -41,15 +39,15 @@ | ||
//var rows = [ | ||
// "abc", | ||
// "abć", | ||
// "ab한" | ||
// "abc", | ||
// "abć", | ||
// "ab한" | ||
//]; | ||
// | ||
//var t2 = Table(header,rows,{ | ||
// borderStyle : 2, | ||
// paddingBottom : 0, | ||
// paddingLeft: 2, | ||
// paddingRight: 2, | ||
// headerAlign : "right", | ||
// align : "center", | ||
// color : "white" | ||
// borderStyle : 2, | ||
// paddingBottom : 0, | ||
// paddingLeft: 2, | ||
// paddingRight: 2, | ||
// headerAlign : "right", | ||
// align : "center", | ||
// color : "white" | ||
//}); | ||
@@ -56,0 +54,0 @@ // |
358
Gruntfile.js
/** | ||
* To debug gruntfile: | ||
* node-debug $(which grunt) task | ||
*/ | ||
*/ | ||
module.exports = function(grunt) { | ||
//Modules for browserify to ignore | ||
var _ignore = '--ignore=path --ignore=request --ignore=http --ignore=fs --ignore=vm --ignore=process --ignore=lodash'; | ||
//Modules for browserify to ignore | ||
var _ignore = '--ignore=path --ignore=request --ignore=http --ignore=fs --ignore=vm --ignore=process --ignore=lodash'; | ||
var banner = '/** \n<%= pkg.name %>: <%= pkg.description %> \nVersion: <%= pkg.version %> \nBuilt: <%= grunt.template.today("yyyy-mm-dd") %> <%= options.timestamp %>\nAuthor: <%= pkg.author %> \n*/\n'; | ||
var banner = '/** \n<%= pkg.name %>: <%= pkg.description %> \nVersion: <%= pkg.version %> \nBuilt: <%= grunt.template.today("yyyy-mm-dd") %> <%= options.timestamp %>\nAuthor: <%= pkg.author %> \n*/\n'; | ||
// Project configuration. | ||
grunt.initConfig({ | ||
pkg: grunt.file.readJSON('package.json'), | ||
// Project configuration. | ||
grunt.initConfig({ | ||
pkg: grunt.file.readJSON('package.json'), | ||
options : { | ||
timestamp : (function(){ | ||
//A FORMATTED TIMESTAMP STRING FOR BACKUP NAMING | ||
var d = new Date(),dstr = ''; | ||
dstr = ('0' + d.getHours()).slice(-2) | ||
+ ':' + ('0' + d.getMinutes()).slice(-2) | ||
+ ':' + ('0' + d.getSeconds()).slice(-2); | ||
return dstr; | ||
}()) | ||
}, | ||
mochaTest: { | ||
test: { | ||
options: { | ||
ui : 'bdd', | ||
reporter: 'spec', | ||
}, | ||
//We require all our tests in the conf file, so we | ||
//can do some pre-test functions before they are run. | ||
src: ['./test/mocha.conf.js'] | ||
} | ||
}, | ||
shell: { | ||
"browserify-prod-standalone": { | ||
command: function () { | ||
var cmd = 'browserify --standalone=TtyTable '+_ignore+' -r ./src/main.js > ./dist/<%= pkg.name %>.js -t [ babelify --presets [ es2015 babili] ] -p [ browserify-banner --template "'+banner+'"]'; | ||
return cmd; | ||
} | ||
}, | ||
"browserify-devel-standalone": { | ||
command: function () { | ||
var cmd = 'browserify --debug --standalone=TtyTable '+_ignore+' -r ./src/main.js > ./dist/<%= pkg.name %>.devel.js -t [ babelify --presets [ es2015 babili] ]'; | ||
return cmd; | ||
} | ||
}, | ||
"cleanup" : { | ||
command: function(){ | ||
return "rm ./dist/<%= pkg.name %>.js ./dist/<%= pkg.name %>.bundle.js"; | ||
} | ||
}, | ||
"generate-vim-tags-file": { | ||
command: function (){ | ||
var cmd = 'find . -name "*.js" -path "./src/*" | xargs jsctags {} -f | sed "/^$/d" | sort > tags'; | ||
return cmd; | ||
} | ||
}, | ||
"get-node-version": { | ||
command: function (){ | ||
var cmd = 'echo "Fetching node version...\n" && node --version'; | ||
return cmd; | ||
} | ||
}, | ||
}, | ||
//regenerate tags file on file save | ||
watch: { | ||
scripts: { | ||
files: ['**/*.js'], | ||
tasks: ['shell:generate-vim-tags-file'], | ||
options: { | ||
spawn: true, | ||
reload: false | ||
} | ||
} | ||
} | ||
}); | ||
options : { | ||
timestamp : (function(){ | ||
//A FORMATTED TIMESTAMP STRING FOR BACKUP NAMING | ||
var d = new Date(),dstr = ''; | ||
dstr = ('0' + d.getHours()).slice(-2) | ||
+ ':' + ('0' + d.getMinutes()).slice(-2) | ||
+ ':' + ('0' + d.getSeconds()).slice(-2); | ||
return dstr; | ||
}()) | ||
}, | ||
mochaTest: { | ||
test: { | ||
options: { | ||
ui : 'bdd', | ||
reporter: 'spec', | ||
}, | ||
//We require all our tests in the conf file, so we | ||
//can do some pre-test functions before they are run. | ||
src: ['./test/mocha.conf.js'] | ||
} | ||
}, | ||
shell: { | ||
"browserify-prod-standalone": { | ||
command: function () { | ||
var cmd = 'browserify --standalone=TtyTable '+_ignore+' -r ./src/main.js > ./dist/<%= pkg.name %>.js -t [ babelify --presets [ es2015 babili] ] -p [ browserify-banner --template "'+banner+'"]'; | ||
return cmd; | ||
} | ||
}, | ||
"browserify-devel-standalone": { | ||
command: function () { | ||
var cmd = 'browserify --debug --standalone=TtyTable '+_ignore+' -r ./src/main.js > ./dist/<%= pkg.name %>.devel.js -t [ babelify --presets [ es2015 babili] ]'; | ||
return cmd; | ||
} | ||
}, | ||
"cleanup" : { | ||
command: function(){ | ||
return "rm ./dist/<%= pkg.name %>.js ./dist/<%= pkg.name %>.bundle.js"; | ||
} | ||
}, | ||
"generate-vim-tags-file": { | ||
command: function (){ | ||
var cmd = 'find . -name "*.js" -path "./src/*" | xargs jsctags {} -f | sed "/^$/d" | sort > tags'; | ||
return cmd; | ||
} | ||
}, | ||
"get-node-version": { | ||
command: function (){ | ||
var cmd = 'echo "Fetching node version...\n" && node --version'; | ||
return cmd; | ||
} | ||
}, | ||
}, | ||
//regenerate tags file on file save | ||
watch: { | ||
scripts: { | ||
files: ['**/*.js'], | ||
tasks: ['shell:generate-vim-tags-file'], | ||
options: { | ||
spawn: true, | ||
reload: false | ||
} | ||
} | ||
} | ||
}); | ||
grunt.registerTask('save-test-outputs','Saves the ouptuts of all unit tests to file.',function(){ | ||
var glob = require('glob'); | ||
var exec = require('child_process').exec, child; | ||
var gruntDeferred = this.async(); | ||
var jobQueue = []; | ||
var orgy = require('orgy'); | ||
var fs = require('fs'); | ||
grunt.registerTask('save-test-outputs','Saves the ouptuts of all unit tests to file.',function(){ | ||
var glob = require('glob'); | ||
var exec = require('child_process').exec, child; | ||
var gruntDeferred = this.async(); | ||
var jobQueue = []; | ||
var orgy = require('orgy'); | ||
var fs = require('fs'); | ||
//Get list of all test scripts | ||
var list = glob.sync('examples/*.js'); | ||
list.forEach(function(element){ | ||
//Create a deferred for each run, which is pushed into a queue. | ||
var deferred = orgy.deferred(); | ||
jobQueue.push(deferred); | ||
//Get list of all example scripts | ||
var list = glob.sync('examples/*.js'); | ||
list.forEach(function(element){ | ||
//Create a deferred for each run, which is pushed into a queue. | ||
var deferred = orgy.deferred(); | ||
jobQueue.push(deferred); | ||
child = exec('node ./'+element+' --color=always', | ||
function (error, stdout, stderr) { | ||
if (error !== null) { | ||
grunt.log.error('Exec error: ' + error); | ||
} | ||
var subname = element.split('.')[0]; | ||
var filename = subname + '-output.txt'; | ||
fs.writeFileSync(filename,stdout); | ||
grunt.log.write('Wrote output to text file: ' + filename + '\n'); | ||
deferred.resolve(); | ||
}); | ||
}); | ||
child = exec('node ./'+element+' --color=always', | ||
function (error, stdout, stderr) { | ||
if (error !== null) { | ||
grunt.log.error('Exec error: ' + error); | ||
} | ||
var subname = element.split('.')[0]; | ||
var filename = subname + '-output.txt'; | ||
fs.writeFileSync(filename,stdout); | ||
grunt.log.write('Wrote output to text file: ' + filename + '\n'); | ||
deferred.resolve(); | ||
}); | ||
}); | ||
//Resolve grunt deferred only after jobQueue is complete. | ||
orgy.queue(jobQueue,[{ | ||
timeout : 1000 | ||
}]) | ||
.done(function(){ | ||
gruntDeferred(); | ||
}); | ||
//Resolve grunt deferred only after jobQueue is complete. | ||
orgy.queue(jobQueue,[{ | ||
timeout : 1000 | ||
}]) | ||
.done(function(){ | ||
gruntDeferred(); | ||
}); | ||
}); | ||
}); | ||
grunt.registerTask('doc','Documentation generation task',function(){ | ||
var gruntDeferred = this.async(), | ||
orgy = require('orgy'), | ||
deferred1 = orgy.deferred({timeout : 20000}), | ||
deferred2 = orgy.deferred({timeout : 20000}), | ||
fs = require('fs'); | ||
orgy.queue([deferred1,deferred2],{ | ||
timeout : 20000 | ||
}) | ||
.done(function(){ | ||
gruntDeferred(); | ||
}); | ||
//Get README | ||
var readme = fs.readFileSync("./README.md",{ | ||
encoding : "utf-8" | ||
}); | ||
//Inject example usage into README | ||
var example1 = fs.readFileSync('./examples/node-example.js',{ | ||
encoding : 'utf-8' | ||
}); | ||
example1 = example1.replace('../','tty-table'); | ||
example1 = '\n```js\n' + example1 + '\n```'; | ||
readme = readme.replace(/<!--EXAMPLE-USAGE-->((?:.|[\r\n])*)<!--END-EXAMPLE-USAGE-->/m, | ||
'<!--EXAMPLE-USAGE-->\n'+example1+'\n<!--END-EXAMPLE-USAGE-->'); | ||
deferred1.resolve(); | ||
//Inject public API reference | ||
var exec = require('child_process').exec, child; | ||
child = exec('jsdoc2md "src/*.js"', function (error, stdout, stderr) { | ||
//console.log('stdout: ' + stdout); | ||
//console.log('stderr: ' + stderr); | ||
if (error !== null) { | ||
grunt.log.error('Exec error: ' + error); | ||
} | ||
grunt.registerTask('doc','Documentation generation task',function(){ | ||
var gruntDeferred = this.async(), | ||
orgy = require('orgy'), | ||
deferred1 = orgy.deferred({timeout : 20000}), | ||
deferred2 = orgy.deferred({timeout : 20000}), | ||
fs = require('fs'); | ||
orgy.queue([deferred1,deferred2],{ | ||
timeout : 20000 | ||
}) | ||
.done(function(){ | ||
gruntDeferred(); | ||
}); | ||
//Get README | ||
var readme = fs.readFileSync("./README.md",{ | ||
encoding : "utf-8" | ||
}); | ||
//Inject example usage into README | ||
var example1 = fs.readFileSync('./examples/styles-and-formatting.js',{ | ||
encoding : 'utf-8' | ||
}); | ||
example1 = example1.replace('../','tty-table'); | ||
example1 = '\n```js\n' + example1 + '\n```'; | ||
readme = readme.replace(/<!--EXAMPLE-USAGE-->((?:.|[\r\n])*)<!--END-EXAMPLE-USAGE-->/m, | ||
'<!--EXAMPLE-USAGE-->\n'+example1+'\n<!--END-EXAMPLE-USAGE-->'); | ||
deferred1.resolve(); | ||
//Inject public API reference | ||
var exec = require('child_process').exec, child; | ||
child = exec('jsdoc2md "src/*.js"', function (error, stdout, stderr) { | ||
//console.log('stdout: ' + stdout); | ||
//console.log('stderr: ' + stderr); | ||
if (error !== null) { | ||
grunt.log.error('Exec error: ' + error); | ||
} | ||
//Reformat documentation to reflect correct method naming. | ||
var str = stdout.replace(/new /g,'') | ||
.replace(/_public\./g,''); | ||
//Reformat documentation to reflect correct method naming. | ||
var str = stdout.replace(/new /g,'') | ||
.replace(/_public\./g,''); | ||
readme = readme.replace(/<!--API-REF-->((?:.|[\r\n])*)<!--END-API-REF-->/m, | ||
'<!--API-REF-->\n\n'+str+'\n<!--END-API-REF-->'); | ||
readme = readme.replace(/<!--API-REF-->((?:.|[\r\n])*)<!--END-API-REF-->/m, | ||
'<!--API-REF-->\n\n'+str+'\n<!--END-API-REF-->'); | ||
fs.writeFileSync("./README.md",readme); | ||
fs.writeFileSync("./README.md",readme); | ||
deferred2.resolve(); | ||
}); | ||
}); | ||
deferred2.resolve(); | ||
}); | ||
}); | ||
grunt.loadNpmTasks('grunt-contrib-watch'); | ||
grunt.loadNpmTasks('grunt-shell'); | ||
grunt.loadNpmTasks('grunt-mocha-test'); | ||
grunt.loadNpmTasks('grunt-contrib-watch'); | ||
grunt.loadNpmTasks('grunt-shell'); | ||
grunt.loadNpmTasks('grunt-mocha-test'); | ||
grunt.registerTask('tags', [ | ||
'shell:generate-vim-tags-file', | ||
]); | ||
grunt.registerTask('tags', [ | ||
'shell:generate-vim-tags-file', | ||
]); | ||
grunt.registerTask('test', [ | ||
'mochaTest:test' | ||
]); | ||
grunt.registerTask('test', [ | ||
'mochaTest:test' | ||
]); | ||
grunt.registerTask('t', [ | ||
'mochaTest:test' | ||
]); | ||
grunt.registerTask('t', [ | ||
'mochaTest:test' | ||
]); | ||
grunt.registerTask('st',[ | ||
'save-test-outputs' | ||
]); | ||
grunt.registerTask('st',[ | ||
'save-test-outputs' | ||
]); | ||
grunt.registerTask('test-travis', [ | ||
'mochaTest:test' | ||
]); | ||
grunt.registerTask('test-travis', [ | ||
'mochaTest:test' | ||
]); | ||
grunt.registerTask('default', [ | ||
'shell:get-node-version', | ||
'shell:browserify-prod-standalone', | ||
'shell:browserify-devel-standalone', | ||
'shell:cleanup', | ||
'doc' | ||
]); | ||
grunt.registerTask('default', [ | ||
'shell:get-node-version', | ||
'shell:browserify-prod-standalone', | ||
'shell:browserify-devel-standalone', | ||
'shell:cleanup', | ||
'doc' | ||
]); | ||
}; |
{ | ||
"name": "tty-table", | ||
"version": "2.5.2", | ||
"version": "2.5.3", | ||
"description": "Command line table generator.", | ||
@@ -39,2 +39,3 @@ "main": "src/main.js", | ||
"strip-ansi": "^3.0.0", | ||
"use-strict": "^1.0.1", | ||
"wcwidth": "^1.0.1", | ||
@@ -57,4 +58,5 @@ "yargs": "^8.0.1" | ||
"grunt-shell": "^2.1.0", | ||
"mocha": "^3.4.1" | ||
"mocha": "^3.4.1", | ||
"orgy": "^2.2.0" | ||
} | ||
} |
178
README.md
@@ -5,7 +5,7 @@ # tty-table | ||
A terminal table widget for nodejs and the browser. | ||
Display yout data in a table using a terminal, browser, or browser console. | ||
## Installation | ||
- As a [terminal application](docs/terminal.md): | ||
- To install as a [terminal application](docs/terminal.md): | ||
@@ -20,3 +20,3 @@ ```sh | ||
```sh | ||
npm install tty-table | ||
$ npm install tty-table | ||
``` | ||
@@ -36,3 +36,3 @@ | ||
### Drop-in replacement for the unmaintained [Automattic/cli-table](docs/automattic-cli-table.md): | ||
- Can be used as a bugfixed, drop-in replacement for the [unmaintained, but popular Automattic/cli-table](https://github.com/Automattic/cli-table/issues/91): | ||
```js | ||
@@ -44,10 +44,12 @@ var Table = require('tty-table')('automattic-cli-table'); | ||
- Fixes these known issues with Automattic/cli-table: | ||
- Automatic text wrapping | ||
- [Supports Asian characters](https://github.com/tecfu/tty-table/pull/5) | ||
- [Automatically resizes to terminal width](https://github.com/tecfu/tty-table/issues/4) | ||
- Fixes these open issues with Automattic/cli-table: | ||
- [Text alignment](https://github.com/Automattic/cli-table/issues/64) | ||
- [Alternative table character sets](https://github.com/Automattic/cli-table/issues/10) | ||
- [Automatic text wrapping](https://github.com/Automattic/cli-table/issues/35) | ||
- [Wide character support](https://github.com/Automattic/cli-table/issues/82) | ||
- [Chokes on null values](https://github.com/Automattic/cli-table/issues/65) | ||
- [Automatically resize to terminal width](https://github.com/tecfu/tty-table/issues/4) | ||
- See the [docs here](docs/automattic-cli-table.md). | ||
### Beyond that, the native API also supports: | ||
### In addition to the fixes listed above, the native API also supports: | ||
@@ -65,11 +67,25 @@ - Optional callbacks on column values | ||
### Terminal | ||
(npm i -g tty-table) | ||
### Terminal (Static) | ||
[examples/styles-and-formatting.js](examples/styles-and-formatting.js) | ||
![Static](https://cloud.githubusercontent.com/assets/7478359/15691679/07142030-273f-11e6-8f1e-25728d558a2d.png "Static Example") | ||
### Terminal (Streaming) | ||
``` | ||
$ node examples/data/fake-stream.js | tty-table --format=json | ||
``` | ||
![Streaming](https://cloud.githubusercontent.com/assets/7478359/26528893/88e38e38-4369-11e7-8125-05df0259511e.gif "Streaming Example") | ||
- *See the built-in help for the terminal version of tty-table with: | ||
``` | ||
$ tty-table -h | ||
``` | ||
### Browser & Browser Console | ||
- [examples/browser-example.html](examples/browser-example.html) | ||
![Browser Console Example](https://cloud.githubusercontent.com/assets/7478359/25214897/df99d2e8-254e-11e7-962f-743890292a24.png) | ||
@@ -86,94 +102,2 @@ | ||
## Default API Usage | ||
<!--EXAMPLE-USAGE--> | ||
```js | ||
var Table = require('tty-table'); | ||
var chalk = require('chalk'); | ||
var header = [ | ||
{ | ||
value : "item", | ||
headerColor : "cyan", | ||
color: "white", | ||
align : "left", | ||
paddingLeft : 5, | ||
width : 30 | ||
}, | ||
{ | ||
value : "price", | ||
color : "red", | ||
width : 10, | ||
formatter : function(value){ | ||
var str = "$" + value.toFixed(2); | ||
if(value > 5){ | ||
str = chalk.underline.green(str); | ||
} | ||
return str; | ||
} | ||
} | ||
]; | ||
//Example with arrays as rows | ||
var rows = [ | ||
["hamburger",2.50,"no"], | ||
["el jefe's special cream sauce",0.10,"yes"], | ||
]; | ||
var footer = [ | ||
"TOTAL", | ||
(function(){ | ||
return rows.reduce(function(prev,curr){ | ||
return prev+curr[1] | ||
},0) | ||
}()), | ||
(function(){ | ||
var total = rows.reduce(function(prev,curr){ | ||
return prev+((curr[2]==='yes') ? 1 : 0); | ||
},0); | ||
return (total/rows.length*100).toFixed(2) + "%"; | ||
}())]; | ||
var t1 = Table(header,rows,footer,{ | ||
borderStyle : 1, | ||
borderColor : "blue", | ||
paddingBottom : 0, | ||
headerAlign : "center", | ||
align : "center", | ||
color : "white" | ||
}); | ||
str1 = t1.render(); | ||
console.log(str1); | ||
//Example with objects as rows | ||
var rows = [ | ||
{ | ||
item : "hamburger", | ||
price : 2.50, | ||
organic : "no" | ||
}, | ||
{ | ||
item : "el jefe's special cream sauce", | ||
price : 0.10, | ||
organic : "yes" | ||
} | ||
]; | ||
var t2 = Table(header,rows,{ | ||
borderStyle : 1, | ||
paddingBottom : 0, | ||
headerAlign : "center", | ||
align : "center", | ||
color : "white" | ||
}); | ||
var str2 = t2.render(); | ||
console.log(str2); | ||
``` | ||
<!--END-EXAMPLE-USAGE--> | ||
## Default API Reference | ||
@@ -190,18 +114,18 @@ <!--API-REF--> | ||
[ | ||
[ | ||
{v: " ", l: " ", j: " ", h: " ", r: " "}, | ||
{v: " ", l: " ", j: " ", h: " ", r: " "}, | ||
{v: " ", l: " ", j: " ", h: " ", r: " "} | ||
], | ||
[ | ||
{v: "│", l: "┌", j: "┬", h: "─", r: "┐"}, | ||
{v: "│", l: "├", j: "┼", h: "─", r: "┤"}, | ||
{v: "│", l: "└", j: "┴", h: "─", r: "┘"} | ||
], | ||
[ | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"}, | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"}, | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"} | ||
] | ||
[ | ||
{v: " ", l: " ", j: " ", h: " ", r: " "}, | ||
{v: " ", l: " ", j: " ", h: " ", r: " "}, | ||
{v: " ", l: " ", j: " ", h: " ", r: " "} | ||
], | ||
[ | ||
{v: "│", l: "┌", j: "┬", h: "─", r: "┐"}, | ||
{v: "│", l: "├", j: "┼", h: "─", r: "┤"}, | ||
{v: "│", l: "└", j: "┴", h: "─", r: "┘"} | ||
], | ||
[ | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"}, | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"}, | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"} | ||
] | ||
] | ||
``` | ||
@@ -245,8 +169,8 @@ | ||
| options.errorOnNull | <code>boolean</code> | default: false | | ||
| options.truncate | <code>mixed</code> | default: false Cell values are truncated when 'truncate' set to a string, length > 0 | | ||
| options.truncate | <code>mixed</code> | default: false <br/> When this property is set to a string, cell contents will be truncated by that string instead of wrapped when they extend beyond of the width of the cell. <br/> For example if: <br/> <code>"truncate":"..."</code> <br/> the cell will be truncated with "..." | | ||
**Example** | ||
```js | ||
var Table = require('tty-table'); | ||
var t1 = Table(header,rows,options); | ||
let Table = require('tty-table'); | ||
let t1 = Table(header,rows,options); | ||
console.log(t1.render()); | ||
@@ -262,3 +186,3 @@ ``` | ||
```js | ||
var str = t1.render(); | ||
let str = t1.render(); | ||
console.log(str); //outputs table | ||
@@ -272,3 +196,3 @@ ``` | ||
```sh | ||
grunt test | ||
$ grunt test | ||
``` | ||
@@ -279,3 +203,3 @@ | ||
```sh | ||
grunt st | ||
$ grunt st | ||
``` | ||
@@ -291,3 +215,3 @@ - Because: | ||
```sh | ||
grunt tags | ||
$ grunt tags | ||
``` | ||
@@ -298,3 +222,3 @@ | ||
```sh | ||
grunt watch | ||
$ grunt watch | ||
``` | ||
@@ -301,0 +225,0 @@ |
@@ -1,41 +0,41 @@ | ||
var Config = { | ||
borderCharacters : [ | ||
[ | ||
{v: " ", l: " ", j: " ", h: " ", r: " "}, | ||
{v: " ", l: " ", j: " ", h: " ", r: " "}, | ||
{v: " ", l: " ", j: " ", h: " ", r: " "} | ||
], | ||
[ | ||
{v: "│", l: "┌", j: "┬", h: "─", r: "┐"}, | ||
{v: "│", l: "├", j: "┼", h: "─", r: "┤"}, | ||
{v: "│", l: "└", j: "┴", h: "─", r: "┘"} | ||
], | ||
[ | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"}, | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"}, | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"} | ||
] | ||
], | ||
align : "center", | ||
borderColor : null, | ||
borderStyle : 1, | ||
color : false, | ||
compact : false, | ||
defaultErrorValue : "[32m[37m[41m ERROR! [49m[32m[39m", | ||
defaultValue : "[32m[37m[41m ? [49m[32m[39m", | ||
errorOnNull : false, | ||
footerAlign : "center", | ||
footerColor : false, | ||
formatter : null, | ||
headerAlign : "center", | ||
headerColor : "yellow", | ||
marginLeft : 2, | ||
marginTop : 1, | ||
paddingBottom : 0, | ||
paddingLeft : 0, | ||
paddingRight : 0, | ||
paddingTop : 0, | ||
tableType : null, | ||
truncate: false, | ||
width : 20, | ||
let Config = { | ||
borderCharacters : [ | ||
[ | ||
{v: " ", l: " ", j: " ", h: " ", r: " "}, | ||
{v: " ", l: " ", j: " ", h: " ", r: " "}, | ||
{v: " ", l: " ", j: " ", h: " ", r: " "} | ||
], | ||
[ | ||
{v: "│", l: "┌", j: "┬", h: "─", r: "┐"}, | ||
{v: "│", l: "├", j: "┼", h: "─", r: "┤"}, | ||
{v: "│", l: "└", j: "┴", h: "─", r: "┘"} | ||
], | ||
[ | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"}, | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"}, | ||
{v: "|", l: "+", j: "+", h: "-", r: "+"} | ||
] | ||
], | ||
align : "center", | ||
borderColor : null, | ||
borderStyle : 1, | ||
color : false, | ||
compact : false, | ||
defaultErrorValue : "[32m[37m[41m ERROR! [49m[32m[39m", | ||
defaultValue : "[32m[37m[41m ? [49m[32m[39m", | ||
errorOnNull : false, | ||
footerAlign : "center", | ||
footerColor : false, | ||
formatter : null, | ||
headerAlign : "center", | ||
headerColor : "yellow", | ||
marginLeft : 2, | ||
marginTop : 1, | ||
paddingBottom : 0, | ||
paddingLeft : 0, | ||
paddingRight : 0, | ||
paddingTop : 0, | ||
tableType : null, | ||
truncate: false, | ||
width : 20, | ||
}; | ||
@@ -45,15 +45,15 @@ | ||
//save so cell options can be merged into column options | ||
Config.columnSettings = []; | ||
Config.columnSettings = []; | ||
Config.headerEmpty = false; | ||
Config.table = { | ||
body : '', | ||
columnInnerWidths : [], | ||
columnWidths : [], | ||
columns : [], | ||
footer : '', | ||
header : '', //post-rendered strings. | ||
height : 0, | ||
typeLocked : false //once a table type is selected can't switch | ||
body : '', | ||
columnInnerWidths : [], | ||
columnWidths : [], | ||
columns : [], | ||
footer : '', | ||
header : '', //post-rendered strings. | ||
height : 0, | ||
typeLocked : false //once a table type is selected can't switch | ||
}; | ||
module.exports = Config; |
@@ -1,4 +0,4 @@ | ||
var Public = require('./public.js'); | ||
let Public = require('./public.js'); | ||
module.exports = (function(){ | ||
return Public.setup; | ||
return Public.setup; | ||
})() |
@@ -1,228 +0,228 @@ | ||
//var StripAnsi = require("strip-ansi"); | ||
//var Wrap = require("word-wrap"); | ||
var Wrap = require("smartwrap"); | ||
var Wcwidth = require("wcwidth"); | ||
var Format = {}; | ||
//let StripAnsi = require("strip-ansi"); | ||
//let Wrap = require("word-wrap"); | ||
let Wrap = require("smartwrap"); | ||
let Wcwidth = require("wcwidth"); | ||
let Format = {}; | ||
Format.calculateLength = function(line) { | ||
//return StripAnsi(line.replace(/[^\x00-\xff]/g,'XX')).length; | ||
return Wcwidth(line); | ||
//return StripAnsi(line.replace(/[^\x00-\xff]/g,'XX')).length; | ||
return Wcwidth(line); | ||
} | ||
Format.wrapCellContent = function( | ||
config, | ||
cellValue, | ||
columnIndex, | ||
cellOptions, | ||
rowType | ||
config, | ||
cellValue, | ||
columnIndex, | ||
cellOptions, | ||
rowType | ||
){ | ||
//coerce cell value to string | ||
var string = cellValue.toString(); | ||
//coerce cell value to string | ||
let string = cellValue.toString(); | ||
//ANSI chararacters that demarcate the start of a line | ||
var startAnsiRegexp = /^(\033\[[0-9;]*m)+/; | ||
//ANSI chararacters that demarcate the start of a line | ||
let startAnsiRegexp = /^(\033\[[0-9;]*m)+/; | ||
//store matching ANSI characters | ||
var startMatches = string.match(startAnsiRegexp) || ['']; | ||
//store matching ANSI characters | ||
let startMatches = string.match(startAnsiRegexp) || ['']; | ||
//remove ANSI start-of-line chars | ||
string = string.replace(startAnsiRegexp,''); | ||
//remove ANSI start-of-line chars | ||
string = string.replace(startAnsiRegexp,''); | ||
//ANSI chararacters that demarcate the end of a line | ||
var endAnsiRegexp = /(\033\[[0-9;]*m)+$/; | ||
//ANSI chararacters that demarcate the end of a line | ||
let endAnsiRegexp = /(\033\[[0-9;]*m)+$/; | ||
//store matching ANSI characters so can be later re-attached | ||
var endMatches = string.match(endAnsiRegexp) || ['']; | ||
//store matching ANSI characters so can be later re-attached | ||
let endMatches = string.match(endAnsiRegexp) || ['']; | ||
//remove ANSI end-of-line chars | ||
string = string.replace(endAnsiRegexp,''); | ||
//remove ANSI end-of-line chars | ||
string = string.replace(endAnsiRegexp,''); | ||
var alignTgt; | ||
let alignTgt; | ||
switch(rowType){ | ||
case('header'): | ||
alignTgt = "headerAlign" | ||
break; | ||
case('body'): | ||
alignTgt = "align" | ||
break; | ||
default: | ||
alignTgt = "footerAlign" | ||
break; | ||
} | ||
switch(rowType){ | ||
case('header'): | ||
alignTgt = "headerAlign" | ||
break; | ||
case('body'): | ||
alignTgt = "align" | ||
break; | ||
default: | ||
alignTgt = "footerAlign" | ||
break; | ||
} | ||
//equalize padding for centered lines | ||
if(cellOptions[alignTgt] === 'center'){ | ||
cellOptions.paddingLeft = cellOptions.paddingRight = | ||
Math.max(cellOptions.paddingRight,cellOptions.paddingLeft,0); | ||
} | ||
//equalize padding for centered lines | ||
if(cellOptions[alignTgt] === 'center'){ | ||
cellOptions.paddingLeft = cellOptions.paddingRight = | ||
Math.max(cellOptions.paddingRight,cellOptions.paddingLeft,0); | ||
} | ||
var columnWidth = config.table.columnWidths[columnIndex]; | ||
//innerWidth is the width available for text within the cell | ||
var innerWidth = columnWidth - | ||
cellOptions.paddingLeft - | ||
cellOptions.paddingRight - | ||
config.GUTTER; | ||
switch(true){ | ||
//no wrap, truncate | ||
case(typeof config.truncate === 'string' && config.truncate.length > 0): | ||
string = Format.handleTruncatedValue( | ||
string, | ||
cellOptions, | ||
innerWidth | ||
); | ||
break; | ||
//asian characters | ||
case(string.length < Format.calculateLength(string)): | ||
string = Format.handleAsianChars( | ||
string, | ||
cellOptions, | ||
innerWidth | ||
); | ||
break; | ||
//latin characters | ||
default: | ||
string = Format.handleLatinChars(string,cellOptions,innerWidth); | ||
} | ||
let columnWidth = config.table.columnWidths[columnIndex]; | ||
//innerWidth is the width available for text within the cell | ||
let innerWidth = columnWidth - | ||
cellOptions.paddingLeft - | ||
cellOptions.paddingRight - | ||
config.GUTTER; | ||
switch(true){ | ||
//no wrap, truncate | ||
case(typeof config.truncate === 'string' && config.truncate.length > 0): | ||
string = Format.handleTruncatedValue( | ||
string, | ||
cellOptions, | ||
innerWidth | ||
); | ||
break; | ||
//asian characters | ||
case(string.length < Format.calculateLength(string)): | ||
string = Format.handleAsianChars( | ||
string, | ||
cellOptions, | ||
innerWidth | ||
); | ||
break; | ||
//latin characters | ||
default: | ||
string = Format.handleLatinChars(string,cellOptions,innerWidth); | ||
} | ||
//break string into array of lines | ||
var strArr = string.split('\n'); | ||
//break string into array of lines | ||
let strArr = string.split('\n'); | ||
//format each line | ||
strArr = strArr.map(function(line){ | ||
//format each line | ||
strArr = strArr.map(function(line){ | ||
line = line.trim(); | ||
var lineLength = Format.calculateLength(line); | ||
line = line.trim(); | ||
let lineLength = Format.calculateLength(line); | ||
//alignment | ||
if(lineLength < columnWidth){ | ||
var emptySpace = columnWidth - lineLength; | ||
switch(true){ | ||
case(cellOptions[alignTgt] === 'center'): | ||
emptySpace --; | ||
var padBoth = Math.floor(emptySpace / 2), | ||
padRemainder = emptySpace % 2; | ||
line = Array(padBoth + 1).join(' ') + | ||
line + | ||
Array(padBoth + 1 + padRemainder).join(' '); | ||
break; | ||
case(cellOptions[alignTgt] === 'right'): | ||
line = Array(emptySpace - cellOptions.paddingRight).join(' ') + | ||
line + | ||
Array(cellOptions.paddingRight + 1).join(' '); | ||
break; | ||
default: | ||
line = Array(cellOptions.paddingLeft + 1).join(' ') + | ||
line + Array(emptySpace - cellOptions.paddingLeft).join(' '); | ||
} | ||
} | ||
//put ANSI color codes BACK on the beginning and end of string | ||
line = startMatches[0] + line; | ||
line = line + endMatches[0]; | ||
//alignment | ||
if(lineLength < columnWidth){ | ||
let emptySpace = columnWidth - lineLength; | ||
switch(true){ | ||
case(cellOptions[alignTgt] === 'center'): | ||
emptySpace --; | ||
let padBoth = Math.floor(emptySpace / 2), | ||
padRemainder = emptySpace % 2; | ||
line = Array(padBoth + 1).join(' ') + | ||
line + | ||
Array(padBoth + 1 + padRemainder).join(' '); | ||
break; | ||
case(cellOptions[alignTgt] === 'right'): | ||
line = Array(emptySpace - cellOptions.paddingRight).join(' ') + | ||
line + | ||
Array(cellOptions.paddingRight + 1).join(' '); | ||
break; | ||
default: | ||
line = Array(cellOptions.paddingLeft + 1).join(' ') + | ||
line + Array(emptySpace - cellOptions.paddingLeft).join(' '); | ||
} | ||
} | ||
//put ANSI color codes BACK on the beginning and end of string | ||
line = startMatches[0] + line; | ||
line = line + endMatches[0]; | ||
return line; | ||
}); | ||
return line; | ||
}); | ||
return { | ||
output : strArr, | ||
width : innerWidth | ||
}; | ||
return { | ||
output : strArr, | ||
width : innerWidth | ||
}; | ||
} | ||
Format.handleTruncatedValue = function(string,cellOptions,innerWidth){ | ||
var outstring = string; | ||
if(innerWidth < outstring.length){ | ||
outstring = outstring.substring(0,innerWidth - cellOptions.truncate.length); | ||
outstring = outstring + cellOptions.truncate; | ||
} | ||
return outstring; | ||
let outstring = string; | ||
if(innerWidth < outstring.length){ | ||
outstring = outstring.substring(0,innerWidth - cellOptions.truncate.length); | ||
outstring = outstring + cellOptions.truncate; | ||
} | ||
return outstring; | ||
} | ||
Format.handleAsianChars = function(string,cellOptions,innerWidth){ | ||
var count = 0; | ||
var start = 0; | ||
var characters = string.split(''); | ||
let count = 0; | ||
let start = 0; | ||
let characters = string.split(''); | ||
var outstring = characters.reduce(function (prev, cellValue, i) { | ||
count += Format.calculateLength(cellValue); | ||
if (count > innerWidth) { | ||
prev.push(string.slice(start, i)); | ||
start = i; | ||
count = 0; | ||
} else if (characters.length === i + 1) { | ||
prev.push(string.slice(start)); | ||
} | ||
return prev; | ||
}, []).join('\n'); | ||
let outstring = characters.reduce(function (prev, cellValue, i) { | ||
count += Format.calculateLength(cellValue); | ||
if (count > innerWidth) { | ||
prev.push(string.slice(start, i)); | ||
start = i; | ||
count = 0; | ||
} else if (characters.length === i + 1) { | ||
prev.push(string.slice(start)); | ||
} | ||
return prev; | ||
}, []).join('\n'); | ||
return outstring; | ||
return outstring; | ||
} | ||
Format.handleLatinChars = function(string,cellOptions,innerWidth){ | ||
var calculatedWidth = innerWidth - | ||
cellOptions.paddingLeft - | ||
cellOptions.paddingRight; | ||
var outstring = Wrap(string,{ | ||
width : calculatedWidth, | ||
trim : true//, | ||
//indent : '', | ||
//cut : true | ||
}); | ||
let calculatedWidth = innerWidth - | ||
cellOptions.paddingLeft - | ||
cellOptions.paddingRight; | ||
let outstring = Wrap(string,{ | ||
width : calculatedWidth, | ||
trim : true//, | ||
//indent : '', | ||
//cut : true | ||
}); | ||
return outstring; | ||
return outstring; | ||
} | ||
Format.getColumnWidths = function(config,rows){ | ||
var widths = []; | ||
var source; //source of columns | ||
//check widths on header settings if exists | ||
if(config.table.header[0] && config.table.header[0].length > 0){ | ||
source = config.table.header[0]; | ||
} | ||
else if(rows.length > 0){ | ||
source = rows[0]; | ||
} | ||
else { | ||
return []; | ||
} | ||
widths = source.map(function(cell){ | ||
if(typeof cell === 'object' && typeof cell.width !=='undefined'){ | ||
return cell.width; | ||
} | ||
else{ | ||
return config.width; | ||
} | ||
}); | ||
let widths = []; | ||
let source; //source of columns | ||
//check widths on header settings if exists | ||
if(config.table.header[0] && config.table.header[0].length > 0){ | ||
source = config.table.header[0]; | ||
} | ||
else if(rows.length > 0){ | ||
source = rows[0]; | ||
} | ||
else { | ||
return []; | ||
} | ||
widths = source.map(function(cell){ | ||
if(typeof cell === 'object' && typeof cell.width !=='undefined'){ | ||
return cell.width; | ||
} | ||
else{ | ||
return config.width; | ||
} | ||
}); | ||
//check to make sure widths will fit the current display, or resize. | ||
var totalWidth = widths.reduce(function(prev,curr){ | ||
return prev + curr; | ||
}); | ||
//add marginLeft to totalWidth | ||
totalWidth += config.marginLeft; | ||
//check to make sure widths will fit the current display, or resize. | ||
let totalWidth = widths.reduce(function(prev,curr){ | ||
return prev + curr; | ||
}); | ||
//add marginLeft to totalWidth | ||
totalWidth += config.marginLeft; | ||
//check process exists in case we are in browser | ||
if(process && process.stdout && totalWidth > process.stdout.columns){ | ||
//recalculate proportionately to fit size | ||
var prop = process.stdout.columns / totalWidth; | ||
prop = prop.toFixed(2)-0.01; | ||
widths = widths.map(function(value){ | ||
return Math.floor(prop*value); | ||
}); | ||
} | ||
//check process exists in case we are in browser | ||
if(process && process.stdout && totalWidth > process.stdout.columns){ | ||
//recalculate proportionately to fit size | ||
let prop = process.stdout.columns / totalWidth; | ||
prop = prop.toFixed(2)-0.01; | ||
widths = widths.map(function(value){ | ||
return Math.floor(prop*value); | ||
}); | ||
} | ||
return widths; | ||
return widths; | ||
} | ||
module.exports = Format; |
@@ -0,8 +1,10 @@ | ||
require('use-strict'); | ||
if(require.main === module){ | ||
//called directly in terminal | ||
require('./terminal-adapter.js'); | ||
//called directly in terminal | ||
require('./terminal-adapter.js'); | ||
} | ||
else{ | ||
//called as a module | ||
module.exports = require('./default-adapter.js'); | ||
//called as a module | ||
module.exports = require('./default-adapter.js'); | ||
} |
@@ -1,45 +0,51 @@ | ||
var Merge = require("merge"); | ||
//var Format = require('./format.js'); | ||
var Render = require('./render.js'); | ||
let Merge = require("merge"); | ||
let Render = require('./render.js'); | ||
//table body inherits from Array | ||
var Cls = Object.create(Array.prototype); | ||
let Cls = Object.create(Array.prototype); | ||
//make sure config is unique for each export | ||
var Config; | ||
let Config; | ||
/** | ||
* @class Table | ||
* @param {array} header - [See example](#example-usage) | ||
* @param {object} header.column - Column options | ||
* @param {string} header.column.alias - Alernate header column name | ||
* @param {string} header.column.align - default: "center" | ||
* @param {string} header.column.color - default: terminal default color | ||
* @param {string} header.column.footerAlign - default: "center" | ||
* @param {string} header.column.footerColor - default: terminal default color | ||
* @param {function} header.column.formatter - Runs a callback on each cell value in the parent column | ||
* @param {string} header.column.headerAlign - default: "center" | ||
* @param {string} header.column.headerColor - default: terminal's default color | ||
* @param {number} header.column.marginLeft - default: 0 | ||
* @param {number} header.column.marginTop - default: 0 | ||
* @param {number} header.column.maxWidth - default: 20 | ||
* @param {number} header.column.paddingBottom - default: 0 | ||
* @param {number} header.column.paddingLeft - default: 0 | ||
* @param {number} header.column.paddingRight - default: 0 | ||
* @param {number} header.column.paddingTop - default: 0 | ||
* @param {array} header - [See example](#example-usage) | ||
* @param {object} header.column - Column options | ||
* @param {string} header.column.alias - Alernate header column name | ||
* @param {string} header.column.align - default: "center" | ||
* @param {string} header.column.color - default: terminal default color | ||
* @param {string} header.column.footerAlign - default: "center" | ||
* @param {string} header.column.footerColor - default: terminal default color | ||
* @param {function} header.column.formatter - Runs a callback on each cell value in the parent column | ||
* @param {string} header.column.headerAlign - default: "center" | ||
* @param {string} header.column.headerColor - default: terminal's default color | ||
* @param {number} header.column.marginLeft - default: 0 | ||
* @param {number} header.column.marginTop - default: 0 | ||
* @param {number} header.column.maxWidth - default: 20 | ||
* @param {number} header.column.paddingBottom - default: 0 | ||
* @param {number} header.column.paddingLeft - default: 0 | ||
* @param {number} header.column.paddingRight - default: 0 | ||
* @param {number} header.column.paddingTop - default: 0 | ||
* | ||
* @param {array} rows - [See example](#example-usage) | ||
* @param {array} rows - [See example](#example-usage) | ||
* | ||
* @param {object} options - Table options | ||
* @param {number} options.borderStyle - default: 1 (0 = no border) | ||
* @param {object} options - Table options | ||
* @param {number} options.borderStyle - default: 1 (0 = no border) | ||
* Refers to the index of the desired character set. | ||
* @param {array} options.borderCharacters - [See @note](#note) | ||
* @param {string} options.borderColor - default: terminal's default color | ||
* @param {boolean} options.compact - default: false | ||
* @param {array} options.borderCharacters - [See @note](#note) | ||
* @param {string} options.borderColor - default: terminal's default color | ||
* @param {boolean} options.compact - default: false | ||
* Removes horizontal lines when true. | ||
* @param {mixed} options.defaultErrorValue - default: 'ERROR!' | ||
* @param {mixed} options.defaultValue - default: '?' | ||
* @param {boolean} options.errorOnNull - default: false | ||
* @param {boolean} options.errorOnNull - default: false | ||
* @param {mixed} options.truncate - default: false | ||
* Cell values are truncated when 'truncate' set to a string, length > 0 | ||
* <br/> | ||
* When this property is set to a string, cell contents will be truncated by that string instead of wrapped when they extend beyond of the width of the cell. | ||
* <br/> | ||
* For example if: | ||
* <br/> | ||
* <code>"truncate":"..."</code> | ||
* <br/> | ||
* the cell will be truncated with "..." | ||
@@ -71,4 +77,4 @@ * @returns {Table} | ||
* ```js | ||
* var Table = require('tty-table'); | ||
* var t1 = Table(header,rows,options); | ||
* let Table = require('tty-table'); | ||
* let t1 = Table(header,rows,options); | ||
* console.log(t1.render()); | ||
@@ -80,59 +86,57 @@ * ``` | ||
//check if adapter called | ||
if(Object.keys(arguments).length === 1 && | ||
typeof arguments[0] === 'string'){ | ||
return require('../'+arguments[0]); | ||
} | ||
//check if syntax adapter called, i.e. github.com/Automattic/cli-table | ||
if(Object.keys(arguments).length === 1 && | ||
typeof arguments[0] === 'string'){ | ||
return require('../'+arguments[0]); | ||
} | ||
Config = require('./config.js'); | ||
var data = Cls; | ||
Config = require('./config.js'); | ||
var options = (typeof arguments[3] === 'object') ? arguments[3] : | ||
(typeof arguments[2] === 'object') ? arguments[2] : {}; | ||
let options = (typeof arguments[3] === 'object') ? arguments[3] : | ||
(typeof arguments[2] === 'object') ? arguments[2] : {}; | ||
Config = Merge(true,Config,options); | ||
Config = Merge(true,Config,options); | ||
//backfixes for shortened option names | ||
Config.align = Config.alignment || Config.align; | ||
Config.headerAlign = Config.headerAlignment || Config.headerAlign; | ||
//backfixes for shortened option names | ||
Config.align = Config.alignment || Config.align; | ||
Config.headerAlign = Config.headerAlignment || Config.headerAlign; | ||
if(arguments[0] && arguments[0] instanceof Array && arguments[0].length){ | ||
Config.table.header = arguments[0]; | ||
} | ||
else{ | ||
Config.table.header = []; | ||
Config.headerEmpty = true; | ||
} | ||
if(arguments[0] && arguments[0] instanceof Array && arguments[0].length){ | ||
Config.table.header = arguments[0]; | ||
} | ||
else{ | ||
Config.table.header = []; | ||
Config.headerEmpty = true; | ||
} | ||
//save a copy for merging columnSettings into cell options | ||
Config.columnSettings = Config.table.header.slice(0); | ||
//save a copy for merging columnSettings into cell options | ||
Config.columnSettings = Config.table.header.slice(0); | ||
//if borderColor is called, lets do it now | ||
if(Config.borderColor !== null){ | ||
var Chalk = require('chalk') | ||
Config.borderCharacters[Config.borderStyle] = | ||
Config.borderCharacters[Config.borderStyle].map(function(obj){ | ||
Object.keys(obj).forEach(function(key){ | ||
obj[key] = Chalk[Config.borderColor](obj[key]); | ||
}) | ||
return obj; | ||
}); | ||
} | ||
//if borderColor is called, lets do it now | ||
if(Config.borderColor !== null){ | ||
let Chalk = require('chalk') | ||
Config.borderCharacters[Config.borderStyle] = | ||
Config.borderCharacters[Config.borderStyle].map(function(obj){ | ||
Object.keys(obj).forEach(function(key){ | ||
obj[key] = Chalk[Config.borderColor](obj[key]); | ||
}) | ||
return obj; | ||
}); | ||
} | ||
//match header geometry with body array | ||
Config.table.header = [Config.table.header]; | ||
//pushed body data into instance prototype | ||
if(arguments[1] && arguments[1] instanceof Array){ | ||
arguments[1].forEach(function(val){ | ||
data.push(val); | ||
}); | ||
} | ||
//match header geometry with body array | ||
Config.table.header = [Config.table.header]; | ||
//pushed body data into instance prototype | ||
if(arguments[1] && arguments[1] instanceof Array){ | ||
arguments[1].forEach(function(val){ | ||
Cls.push(val); | ||
}); | ||
} | ||
Config.table.footer = (arguments[2] instanceof Array) ? arguments[2] : []; | ||
return data; | ||
Config.table.footer = (arguments[2] instanceof Array) ? arguments[2] : []; | ||
return Cls; | ||
} | ||
@@ -147,3 +151,3 @@ | ||
* ```js | ||
* var str = t1.render(); | ||
* let str = t1.render(); | ||
* console.log(str); //outputs table | ||
@@ -153,11 +157,9 @@ * ``` | ||
Cls.render = function(){ | ||
var data = this; | ||
//get sring output | ||
let output = Render.stringifyData.call(this,Config,this); | ||
//get sring output | ||
var output = Render.stringifyData.call(this,Config,data); | ||
return output; | ||
} | ||
return output; | ||
} | ||
module.exports = Cls; |
@@ -1,5 +0,5 @@ | ||
var Merge = require("merge"); | ||
var Style = require("./style.js"); | ||
var Format = require("./format.js"); | ||
var Render = {}; | ||
let Merge = require("merge"); | ||
let Style = require("./style.js"); | ||
let Format = require("./format.js"); | ||
let Render = {}; | ||
@@ -10,122 +10,122 @@ /** | ||
Render.stringifyData = function(Config,data){ | ||
var sections = { | ||
header : [], | ||
body : [], | ||
footer : [] | ||
}, | ||
output = '', | ||
marginLeft = Array(Config.marginLeft + 1).join('\ '), | ||
borderStyle = Config.borderCharacters[Config.borderStyle], | ||
borders = []; | ||
let sections = { | ||
header : [], | ||
body : [], | ||
footer : [] | ||
}, | ||
output = '', | ||
marginLeft = Array(Config.marginLeft + 1).join('\ '), | ||
borderStyle = Config.borderCharacters[Config.borderStyle], | ||
borders = []; | ||
//because automattic/cli-table syntax infers table type based on | ||
//how rows are passed (array of arrays, objects, etc) | ||
Config.rowFormat = Render.getRowFormat(data[0] || []); | ||
//now translate them | ||
data = Render.transformRows(Config,data); | ||
Config.table.columnWidths = Format.getColumnWidths(Config,data); | ||
//stringify header cells | ||
if(!Config.headerEmpty){ | ||
sections.header = Config.table.header.map(function(row){ | ||
return Render.buildRow(Config,row,'header'); | ||
}); | ||
} | ||
else{ | ||
sections.header = []; | ||
} | ||
//because automattic/cli-table syntax infers table type based on | ||
//how rows are passed (array of arrays, objects, etc) | ||
Config.rowFormat = Render.getRowFormat(data[0] || []); | ||
//now translate them | ||
data = Render.transformRows(Config,data); | ||
Config.table.columnWidths = Format.getColumnWidths(Config,data); | ||
//stringify header cells | ||
if(!Config.headerEmpty){ | ||
sections.header = Config.table.header.map(function(row){ | ||
return Render.buildRow(Config,row,'header'); | ||
}); | ||
} | ||
else{ | ||
sections.header = []; | ||
} | ||
//stringify body cells | ||
sections.body = data.map(function(row){ | ||
return Render.buildRow(Config,row,'body'); | ||
}); | ||
//stringify body cells | ||
sections.body = data.map(function(row){ | ||
return Render.buildRow(Config,row,'body'); | ||
}); | ||
//stringify footer cells | ||
sections.footer = (Config.table.footer instanceof Array && Config.table.footer.length > 0) ? [Config.table.footer] : []; | ||
sections.footer = sections.footer.map(function(row){ | ||
return Render.buildRow(Config,row,'footer'); | ||
}); | ||
//stringify footer cells | ||
sections.footer = (Config.table.footer instanceof Array && Config.table.footer.length > 0) ? [Config.table.footer] : []; | ||
sections.footer = sections.footer.map(function(row){ | ||
return Render.buildRow(Config,row,'footer'); | ||
}); | ||
//add borders | ||
//0=header, 1=body, 2=footer | ||
for(var a=0; a<3; a++){ | ||
borders.push(''); | ||
Config.table.columnWidths.forEach(function(w,i,arr){ | ||
borders[a] += Array(w).join(borderStyle[a].h) + | ||
((i+1 !== arr.length) ? borderStyle[a].j : borderStyle[a].r); | ||
}); | ||
borders[a] = borderStyle[a].l + borders[a]; | ||
borders[a] = borders[a].split(''); | ||
borders[a][borders[a].length1] = borderStyle[a].r; | ||
borders[a] = borders[a].join(''); | ||
//no trailing space on footer | ||
borders[a] = (a<2) ? marginLeft + borders[a] + '\n' : marginLeft + borders[a]; | ||
} | ||
//top horizontal border | ||
output += borders[0]; | ||
//add borders | ||
//0=header, 1=body, 2=footer | ||
for(let a=0; a<3; a++){ | ||
borders.push(''); | ||
Config.table.columnWidths.forEach(function(w,i,arr){ | ||
borders[a] += Array(w).join(borderStyle[a].h) + | ||
((i+1 !== arr.length) ? borderStyle[a].j : borderStyle[a].r); | ||
}); | ||
borders[a] = borderStyle[a].l + borders[a]; | ||
borders[a] = borders[a].split(''); | ||
borders[a][borders[a].length1] = borderStyle[a].r; | ||
borders[a] = borders[a].join(''); | ||
//no trailing space on footer | ||
borders[a] = (a<2) ? marginLeft + borders[a] + '\n' : marginLeft + borders[a]; | ||
} | ||
//top horizontal border | ||
output += borders[0]; | ||
//rows | ||
var row; | ||
//rows | ||
let row; | ||
//for each section (header,body,footer) | ||
Object.keys(sections).forEach(function(p,i){ | ||
//for each row in the section | ||
while(sections[p].length){ | ||
row = sections[p].shift(); | ||
//if(row.length === 0) {break} | ||
//for each section (header,body,footer) | ||
Object.keys(sections).forEach(function(p,i){ | ||
//for each row in the section | ||
while(sections[p].length){ | ||
row = sections[p].shift(); | ||
//if(row.length === 0) {break} | ||
row.forEach(function(line){ | ||
//vertical row borders | ||
output = output | ||
+ marginLeft | ||
//left vertical border | ||
+ borderStyle[1].v | ||
//join cells on vertical border | ||
+ line.join(borderStyle[1].v) | ||
//right vertical border | ||
+ borderStyle[1].v | ||
//end of line | ||
+ '\n'; | ||
}); | ||
//bottom horizontal row border | ||
switch(true){ | ||
//skip if end of body and no footer | ||
case(sections[p].length === 0 | ||
&& i === 1 | ||
&& sections.footer.length === 0): | ||
break; | ||
//skip if end of footer | ||
case(sections[p].length === 0 | ||
&& i === 2): | ||
break; | ||
//skip if compact | ||
case(Config.compact && p === 'body' && !row.empty): | ||
break; | ||
default: | ||
output += borders[1]; | ||
} | ||
} | ||
}); | ||
//bottom horizontal border | ||
output += borders[2]; | ||
//remove all rows in prototype array | ||
this.splice(0,this.length); | ||
var finalOutput = Array(Config.marginTop + 1).join('\n') + output; | ||
row.forEach(function(line){ | ||
//vertical row borders | ||
output = output | ||
+ marginLeft | ||
//left vertical border | ||
+ borderStyle[1].v | ||
//join cells on vertical border | ||
+ line.join(borderStyle[1].v) | ||
//right vertical border | ||
+ borderStyle[1].v | ||
//end of line | ||
+ '\n'; | ||
}); | ||
//bottom horizontal row border | ||
switch(true){ | ||
//skip if end of body and no footer | ||
case(sections[p].length === 0 | ||
&& i === 1 | ||
&& sections.footer.length === 0): | ||
break; | ||
//skip if end of footer | ||
case(sections[p].length === 0 | ||
&& i === 2): | ||
break; | ||
//skip if compact | ||
case(Config.compact && p === 'body' && !row.empty): | ||
break; | ||
default: | ||
output += borders[1]; | ||
} | ||
} | ||
}); | ||
//bottom horizontal border | ||
output += borders[2]; | ||
//remove all rows in prototype array | ||
this.splice(0,this.length); | ||
let finalOutput = Array(Config.marginTop + 1).join('\n') + output; | ||
//record the height of the output | ||
this.height = finalOutput.split(/\r\n|\r|\n/).length; | ||
return finalOutput; | ||
//record the height of the output | ||
this.height = finalOutput.split(/\r\n|\r|\n/).length; | ||
return finalOutput; | ||
}; | ||
@@ -135,150 +135,150 @@ | ||
var minRowHeight = 0; | ||
//tag row as empty if empty | ||
//(used) for compact tables | ||
if(row.length === 0 && config.compact){ | ||
row.empty = true; | ||
return row; | ||
} | ||
let minRowHeight = 0; | ||
//tag row as empty if empty | ||
//(used) for compact tables | ||
if(row.length === 0 && config.compact){ | ||
row.empty = true; | ||
return row; | ||
} | ||
//check for diffeerences in line length | ||
var difL = config.table.columnWidths.length - row.length; | ||
//check for diffeerences in line length | ||
let difL = config.table.columnWidths.length - row.length; | ||
if(difL > 0){ | ||
//add empty element to array | ||
row = row.concat(Array.apply(null, new Array(difL)) | ||
.map(function(){return null})); | ||
//.map(function(){return ''})); | ||
} | ||
else if(difL < 0){ | ||
//truncate array | ||
row.length = config.table.columnWidths.length; | ||
} | ||
//get row as array of cell arrays | ||
//can't use es5 row functions (map, forEach because of | ||
//potential ellision; by which [1,,3] will only iterate 1,3 | ||
var cArrs = []; | ||
var rowLength = row.length; | ||
for(var index=0; index<rowLength; index++){ | ||
var c = Render.buildCell(config,row[index],index,rowType); | ||
var cellArr = c.cellArr; | ||
if(rowType === 'header'){ | ||
config.table.columnInnerWidths.push(c.width); | ||
} | ||
minRowHeight = (minRowHeight < cellArr.length) ? | ||
cellArr.length : minRowHeight; | ||
cArrs.push(cellArr); | ||
} | ||
//adjust minRowHeight to reflect vertical row padding | ||
minRowHeight = (rowType === 'header') ? minRowHeight : | ||
minRowHeight + (config.paddingBottom + config.paddingTop); | ||
if(difL > 0){ | ||
//add empty element to array | ||
row = row.concat(Array.apply(null, new Array(difL)) | ||
.map(function(){return null})); | ||
//.map(function(){return ''})); | ||
} | ||
else if(difL < 0){ | ||
//truncate array | ||
row.length = config.table.columnWidths.length; | ||
} | ||
//get row as array of cell arrays | ||
//can't use es5 row functions (map, forEach because of | ||
//potential ellision; by which [1,,3] will only iterate 1,3 | ||
let cArrs = []; | ||
let rowLength = row.length; | ||
for(let index=0; index<rowLength; index++){ | ||
let c = Render.buildCell(config,row[index],index,rowType); | ||
let cellArr = c.cellArr; | ||
if(rowType === 'header'){ | ||
config.table.columnInnerWidths.push(c.width); | ||
} | ||
minRowHeight = (minRowHeight < cellArr.length) ? | ||
cellArr.length : minRowHeight; | ||
cArrs.push(cellArr); | ||
} | ||
//adjust minRowHeight to reflect vertical row padding | ||
minRowHeight = (rowType === 'header') ? minRowHeight : | ||
minRowHeight + (config.paddingBottom + config.paddingTop); | ||
//convert array of cell arrays to array of lines | ||
var lines = Array.apply(null,{length:minRowHeight}) | ||
.map(Function.call,function(){return []}); | ||
cArrs.forEach(function(cellArr,a){ | ||
var whiteline = Array(config.table.columnWidths[a]).join('\ '); | ||
if(rowType ==='body'){ | ||
//add whitespace for top padding | ||
for(var i=0; i<config.paddingTop; i++){ | ||
cellArr.unshift(whiteline); | ||
} | ||
//add whitespace for bottom padding | ||
for(i=0; i<config.paddingBottom; i++){ | ||
cellArr.push(whiteline); | ||
} | ||
} | ||
for(var b=0; b<minRowHeight; b++){ | ||
lines[b].push((typeof cellArr[b] !== 'undefined') ? | ||
cellArr[b] : whiteline); | ||
} | ||
}); | ||
//convert array of cell arrays to array of lines | ||
let lines = Array.apply(null,{length:minRowHeight}) | ||
.map(Function.call,function(){return []}); | ||
cArrs.forEach(function(cellArr,a){ | ||
let whiteline = Array(config.table.columnWidths[a]).join('\ '); | ||
if(rowType ==='body'){ | ||
//add whitespace for top padding | ||
for(let i=0; i<config.paddingTop; i++){ | ||
cellArr.unshift(whiteline); | ||
} | ||
//add whitespace for bottom padding | ||
for(let i=0; i<config.paddingBottom; i++){ | ||
cellArr.push(whiteline); | ||
} | ||
} | ||
for(let b=0; b<minRowHeight; b++){ | ||
lines[b].push((typeof cellArr[b] !== 'undefined') ? | ||
cellArr[b] : whiteline); | ||
} | ||
}); | ||
return lines; | ||
return lines; | ||
} | ||
Render.buildCell = function(config,cell,columnIndex,rowType){ | ||
var cellValue, | ||
cellOptions = Merge(true,config, | ||
(rowType === 'body') ? | ||
config.columnSettings[columnIndex] : {}, //ignore columnSettings for footer | ||
cell); | ||
if(rowType === 'header'){ | ||
config.table.columns.push(cellOptions); | ||
cellValue = cellOptions.alias || cellOptions.value || ''; | ||
} | ||
else{ | ||
//set cellValue | ||
switch(true){ | ||
case(typeof cell === 'undefined' || cell === null): | ||
//replace undefined/null cell values with placeholder | ||
cellValue = (config.errorOnNull) ? config.defaultErrorValue : config.defaultValue; | ||
break; | ||
case(typeof cell === 'object' && typeof cell.value !== 'undefined'): | ||
cellValue = cell.value; | ||
break; | ||
default: | ||
//cell is assumed to be a scalar | ||
cellValue = cell; | ||
} | ||
//run formatter | ||
if(typeof cellOptions.formatter === 'function'){ | ||
cellValue = cellOptions.formatter(cellValue); | ||
} | ||
} | ||
//colorize cellValue | ||
cellValue = Style.colorizeCell(cellValue,cellOptions,rowType); | ||
let cellValue, | ||
cellOptions = Merge(true,config, | ||
(rowType === 'body') ? | ||
config.columnSettings[columnIndex] : {}, //ignore columnSettings for footer | ||
cell); | ||
if(rowType === 'header'){ | ||
config.table.columns.push(cellOptions); | ||
cellValue = cellOptions.alias || cellOptions.value || ''; | ||
} | ||
else{ | ||
//set cellValue | ||
switch(true){ | ||
case(typeof cell === 'undefined' || cell === null): | ||
//replace undefined/null cell values with placeholder | ||
cellValue = (config.errorOnNull) ? config.defaultErrorValue : config.defaultValue; | ||
break; | ||
case(typeof cell === 'object' && typeof cell.value !== 'undefined'): | ||
cellValue = cell.value; | ||
break; | ||
default: | ||
//cell is assumed to be a scalar | ||
cellValue = cell; | ||
} | ||
//run formatter | ||
if(typeof cellOptions.formatter === 'function'){ | ||
cellValue = cellOptions.formatter(cellValue); | ||
} | ||
} | ||
//colorize cellValue | ||
cellValue = Style.colorizeCell(cellValue,cellOptions,rowType); | ||
//textwrap cellValue | ||
var WrapObj = Format.wrapCellContent(config, cellValue, columnIndex, cellOptions, rowType); | ||
//cellValue = WrapObj.output.join('\n'); | ||
//textwrap cellValue | ||
let WrapObj = Format.wrapCellContent(config, cellValue, columnIndex, cellOptions, rowType); | ||
//cellValue = WrapObj.output.join('\n'); | ||
//return as array of lines | ||
return { | ||
cellArr : WrapObj.output, | ||
width : WrapObj.width | ||
}; | ||
//return as array of lines | ||
return { | ||
cellArr : WrapObj.output, | ||
width : WrapObj.width | ||
}; | ||
}; | ||
Render.getRowFormat = function(row){ | ||
var type; | ||
//rows passed as an object | ||
if(typeof row === 'object' && !(row instanceof Array)){ | ||
var keys = Object.keys(row); | ||
if(keys.length === 1){ | ||
//detected cross table | ||
var key = keys[0]; | ||
if(row[key] instanceof Array){ | ||
type = 'automattic-cross'; | ||
} | ||
//detected vertical table | ||
else{ | ||
type = 'automattic-vertical'; | ||
} | ||
} | ||
else { | ||
//detected horizontal table | ||
type = 'o-horizontal'; | ||
} | ||
} | ||
//rows passed as an array | ||
else{ | ||
type = 'a-horizontal'; | ||
} | ||
let type; | ||
//rows passed as an object | ||
if(typeof row === 'object' && !(row instanceof Array)){ | ||
let keys = Object.keys(row); | ||
if(keys.length === 1){ | ||
//detected cross table | ||
let key = keys[0]; | ||
if(row[key] instanceof Array){ | ||
type = 'automattic-cross'; | ||
} | ||
//detected vertical table | ||
else{ | ||
type = 'automattic-vertical'; | ||
} | ||
} | ||
else { | ||
//detected horizontal table | ||
type = 'o-horizontal'; | ||
} | ||
} | ||
//rows passed as an array | ||
else{ | ||
type = 'a-horizontal'; | ||
} | ||
return type; | ||
return type; | ||
}; | ||
@@ -290,19 +290,19 @@ | ||
//grow to # arrays equal to number of columns in input array | ||
var outputArray = []; | ||
var headers = config.table.columns; | ||
//grow to # arrays equal to number of columns in input array | ||
let outputArray = []; | ||
let headers = config.table.columns; | ||
//create a row for each heading, and prepend the row | ||
//with the heading name | ||
headers.forEach(function(name){ | ||
outputArray.push([name]); | ||
}); | ||
//create a row for each heading, and prepend the row | ||
//with the heading name | ||
headers.forEach(function(name){ | ||
outputArray.push([name]); | ||
}); | ||
inputArray.forEach(function(row){ | ||
row.forEach(function(element,index){ | ||
outputArray[index].push(element); | ||
}); | ||
}); | ||
inputArray.forEach(function(row){ | ||
row.forEach(function(element,index){ | ||
outputArray[index].push(element); | ||
}); | ||
}); | ||
return outputArray; | ||
return outputArray; | ||
} | ||
@@ -315,43 +315,43 @@ | ||
var output = []; | ||
switch(config.rowFormat){ | ||
case('automattic-cross'): | ||
//assign header styles to first column | ||
config.columnSettings[0] = config.columnSettings[0] || {}; | ||
config.columnSettings[0].color = config.headerColor; | ||
output = rows.map(function(obj){ | ||
var arr = []; | ||
var key = Object.keys(obj)[0]; | ||
arr.push(key); | ||
return arr.concat(obj[key]); | ||
}); | ||
break; | ||
case('automattic-vertical'): | ||
//assign header styles to first column | ||
config.columnSettings[0] = config.columnSettings[0] || {}; | ||
config.columnSettings[0].color = config.headerColor; | ||
output = rows.map(function(value){ | ||
var key = Object.keys(value)[0]; | ||
return [key,value[key]]; | ||
}); | ||
break; | ||
case('o-horizontal'): | ||
output = rows.map(function(row){ | ||
//requires that column names are specified in header | ||
return config.table.header[0].map(function(object){ | ||
return row[object.value] || null; | ||
}); | ||
}); | ||
break; | ||
case('a-horizontal'): | ||
output = rows; | ||
break; | ||
default: | ||
} | ||
let output = []; | ||
switch(config.rowFormat){ | ||
case('automattic-cross'): | ||
//assign header styles to first column | ||
config.columnSettings[0] = config.columnSettings[0] || {}; | ||
config.columnSettings[0].color = config.headerColor; | ||
output = rows.map(function(obj){ | ||
let arr = []; | ||
let key = Object.keys(obj)[0]; | ||
arr.push(key); | ||
return arr.concat(obj[key]); | ||
}); | ||
break; | ||
case('automattic-vertical'): | ||
//assign header styles to first column | ||
config.columnSettings[0] = config.columnSettings[0] || {}; | ||
config.columnSettings[0].color = config.headerColor; | ||
output = rows.map(function(value){ | ||
let key = Object.keys(value)[0]; | ||
return [key,value[key]]; | ||
}); | ||
break; | ||
case('o-horizontal'): | ||
output = rows.map(function(row){ | ||
//requires that column names are specified in header | ||
return config.table.header[0].map(function(object){ | ||
return row[object.value] || null; | ||
}); | ||
}); | ||
break; | ||
case('a-horizontal'): | ||
output = rows; | ||
break; | ||
default: | ||
} | ||
return output; | ||
return output; | ||
} | ||
module.exports = Render; |
@@ -1,23 +0,23 @@ | ||
var Chalk = require("chalk"); | ||
let Chalk = require("chalk"); | ||
exports.colorizeCell = function(str,cellOptions,rowType){ | ||
var color = false; //false will keep terminal default | ||
switch(true){ | ||
case(rowType === 'body'): | ||
color = cellOptions.color || color; | ||
break; | ||
case(rowType === 'header'): | ||
color = cellOptions.headerColor || color; | ||
break; | ||
default: | ||
color = cellOptions.footerColor || color; | ||
} | ||
if (color){ | ||
str = Chalk[color](str); | ||
} | ||
let color = false; //false will keep terminal default | ||
switch(true){ | ||
case(rowType === 'body'): | ||
color = cellOptions.color || color; | ||
break; | ||
case(rowType === 'header'): | ||
color = cellOptions.headerColor || color; | ||
break; | ||
default: | ||
color = cellOptions.footerColor || color; | ||
} | ||
if (color){ | ||
str = Chalk[color](str); | ||
} | ||
return str; | ||
return str; | ||
} | ||
@@ -27,7 +27,7 @@ | ||
exports.colorizeAllWords = function(color,str){ | ||
//color each word in the cell so that line breaks don't break color | ||
var arr = str.replace(/(\S+)/gi,function(match){ | ||
return Chalk[color](match)+'\ '; | ||
}); | ||
return arr; | ||
//color each word in the cell so that line breaks don't break color | ||
let arr = str.replace(/(\S+)/gi,function(match){ | ||
return Chalk[color](match)+'\ '; | ||
}); | ||
return arr; | ||
} | ||
@@ -34,0 +34,0 @@ */ |
#!/usr/bin/env node | ||
var yargs = require('yargs'); | ||
let csv = require('csv'); | ||
let yargs = require('yargs'); | ||
yargs.epilog('Copyight github.com/tecfu 2017'); | ||
yargs.option('csv-delimiter',{ | ||
describe:'Set the field delimiter. One character only.', | ||
default:',' | ||
describe:'Set the field delimiter. One character only.', | ||
default:',' | ||
}); | ||
yargs.option('csv-escape',{ | ||
describe:'Set the escape character. One character only.', | ||
default:'"' | ||
describe:'Set the escape character. One character only.' | ||
}); | ||
yargs.option('csv-rowDelimiter',{ | ||
describe:'String used to delimit record rows or a special constant; special constants are "auto","unix","max","windows","unicode".', | ||
default:"'" | ||
describe:'String used to delimit record rows. You can also use a special constant: "auto","unix","max","windows","unicode".', | ||
default: '\n' | ||
}); | ||
yargs.option('format',{ | ||
describe:'Set input data format', | ||
choices:['json','csv'], | ||
default:'csv' | ||
describe:'Set input data format', | ||
choices:['json','csv'], | ||
default:'csv' | ||
}); | ||
yargs.option('options\u2010\u002A',{ | ||
describe:'Specify an optional setting where * is the setting name. See README.md for a complete list.' | ||
}); | ||
yargs.version(function(){ | ||
var fs = require('fs'); | ||
var path =__dirname+'/../package.json'; | ||
var contents = fs.readFileSync(path,'utf-8'); | ||
var json = JSON.parse(contents); | ||
return json.version; | ||
let fs = require('fs'); | ||
let path =__dirname+'/../package.json'; | ||
let contents = fs.readFileSync(path,'utf-8'); | ||
let json = JSON.parse(contents); | ||
return json.version; | ||
}); | ||
var Chalk = require('chalk'); | ||
var sendError = function(msg){ | ||
msg = '\ntty-table error: ' + msg + '\n'; | ||
console.log(msg); | ||
process.exit(1); | ||
let Chalk = require('chalk'); | ||
let sendError = function(msg){ | ||
msg = '\ntty-table error: ' + msg + '\n'; | ||
console.log(msg); | ||
process.exit(1); | ||
}; | ||
//note that this is the first run | ||
var alreadyRendered = false; | ||
var previousHeight = 0; | ||
let alreadyRendered = false; | ||
let previousHeight = 0; | ||
var dataFormat = 'csv'; | ||
let dataFormat = 'csv'; | ||
switch(true){ | ||
case(yargs.argv.format.toString().match(/json/i) !== null): | ||
dataFormat = 'json'; | ||
break; | ||
default: | ||
var csv = require('csv'); | ||
case(typeof yargs.argv.format === 'undefined'): | ||
break; | ||
case(yargs.argv.format.toString().match(/json/i) !== null): | ||
dataFormat = 'json'; | ||
break; | ||
default: | ||
} | ||
//look for options-* | ||
let options = {}; | ||
Object.keys(yargs.argv).forEach(function(key){ | ||
let keyParts = key.split('-'); | ||
if(keyParts[0]==='options'){ | ||
options[keyParts[1]]=yargs.argv[key]; | ||
} | ||
}); | ||
//look for header-n-* | ||
//Object.keys(yargs.argv).forEach(function(key){ | ||
// let keyParts = key.split('-'); | ||
// if(keyParts[0] === 'header'){ | ||
// //find out which column we're setting an option on | ||
// let column = keyParts[1]; | ||
// if(typeof header[column] === 'undefined'){ | ||
// header[column] = {} | ||
// } | ||
// header[column][keyParts[2]] = yargs.argv[key]; | ||
// } | ||
//}); | ||
//if header is specified, we'll need to have a size on it | ||
//because diffent dataFormats | ||
var runTable = function(input){ | ||
var header = [], | ||
body = input, | ||
//footer = [], | ||
options = {}; | ||
let runTable = function(input){ | ||
let header = [], | ||
body = input; | ||
//footer = [], | ||
var Table = require('./public.js'); | ||
var t1 = Table.setup(header,body,options); | ||
//hide cursor | ||
console.log('\u001b[?25l'); | ||
//wipe existing if already rendered | ||
if(alreadyRendered){ | ||
let Table = require('./public.js'); | ||
let t1 = Table.setup(header,body,options); | ||
//hide cursor | ||
console.log('\u001b[?25l'); | ||
//wipe existing if already rendered | ||
if(alreadyRendered){ | ||
//move cursor up number to the top of the previous print | ||
//before deleting | ||
console.log('\u001b['+(previousHeight+3)+'A'); | ||
//delete to end of terminal | ||
console.log('\u001b[0J'); | ||
} | ||
else{ | ||
alreadyRendered = true; | ||
} | ||
console.log(t1.render()); | ||
//reset the previous height to the height of this output | ||
//for when we next clear the print | ||
previousHeight = t1.height; | ||
//move cursor up number to the top of the previous print | ||
//before deleting | ||
console.log('\u001b['+(previousHeight+3)+'A'); | ||
//delete to end of terminal | ||
console.log('\u001b[0J'); | ||
} | ||
else{ | ||
alreadyRendered = true; | ||
} | ||
console.log(t1.render()); | ||
//reset the previous height to the height of this output | ||
//for when we next clear the print | ||
previousHeight = t1.height; | ||
@@ -89,37 +117,40 @@ }; | ||
//handle dataFormats | ||
switch(true){ | ||
case(dataFormat==='json'): | ||
try { | ||
var data = JSON.parse(chunk); | ||
} | ||
catch(e){ | ||
var msg = Chalk.bgRed.white(msg); | ||
msg = msg + "\n\nPlease check to make sure that your input data consists of JSON or specify a different format with the --format flag."; | ||
sendError(msg); | ||
} | ||
runTable(data); | ||
break; | ||
default: | ||
var formatterOptions = {}; | ||
Object.keys(yargs.argv).forEach(function(key){ | ||
if(key.slice(0,4) === 'csv-'){ | ||
formatterOptions[key.slice(4)] = yargs.argv[key]; | ||
} | ||
}); | ||
csv.parse(chunk,formatterOptions,function(err, data){ | ||
//validate csv | ||
if(typeof data === 'undefined'){ | ||
var msg = "CSV parse error."; | ||
msg = Chalk.bgRed.white(msg); | ||
msg = msg + "\n\nPlease check to make sure that your input data consists of comma separated values or specify a different format with the --format flag."; | ||
sendError(msg); | ||
} | ||
runTable(data); | ||
}); | ||
} | ||
//handle dataFormats | ||
switch(true){ | ||
case(dataFormat==='json'): | ||
let data,msg; | ||
try { | ||
data = JSON.parse(chunk); | ||
} | ||
catch(e){ | ||
msg = Chalk.bgRed.white(msg); | ||
msg = msg + "\n\nPlease check to make sure that your input data consists of JSON or specify a different format with the --format flag."; | ||
sendError(msg); | ||
} | ||
runTable(data); | ||
break; | ||
default: | ||
let formatterOptions = {}; | ||
Object.keys(yargs.argv).forEach(function(key){ | ||
if(key.slice(0,4) === 'csv-' && typeof(yargs.argv[key]) !== 'undefined'){ | ||
formatterOptions[key.slice(4)] = yargs.argv[key]; | ||
} | ||
}); | ||
csv.parse(chunk,formatterOptions,function(err, data){ | ||
//validate csv | ||
if(typeof data === 'undefined'){ | ||
let msg = "CSV parse error."; | ||
msg = Chalk.bgRed.white(msg); | ||
msg = msg + '\n\n' + err; | ||
msg = msg + '\n\n' + 'Please check to make sure that your input data consists of valid comma separated values or specify a different format with the --format flag.'; | ||
sendError(msg); | ||
} | ||
runTable(data); | ||
}); | ||
} | ||
}); | ||
if (process.platform === "win32") { | ||
var rl = require("readline").createInterface({ | ||
let rl = require("readline").createInterface({ | ||
input: process.stdin, | ||
@@ -140,4 +171,4 @@ output: process.stdout | ||
process.on('exit', function() { | ||
//show cursor | ||
console.log('\u001b[?25h'); | ||
//show cursor | ||
console.log('\u001b[?25h'); | ||
}); | ||
@@ -144,0 +175,0 @@ |
//yargs help descriptions | ||
var yargs = require('yargs'); | ||
let yargs = require('yargs'); | ||
yargs.option('csv-*',{ | ||
describe:'Set a custom option for node-csv-parse. \nYou can see a complete list of options at http://csv.adaltas.com/parse/.' | ||
describe:'Set a custom option for node-csv-parse. \nYou can see a complete list of options at http://csv.adaltas.com/parse/.' | ||
}); | ||
yargs.option('header-n-*',{ | ||
describe:'Set a custom option for a header column where "n" is the order of the column and "*" is the name of the option.' | ||
describe:'Set a custom option for a header column where "n" is the order of the column and "*" is the name of the option.' | ||
}); | ||
yargs.option('format',{ | ||
describe:'Set input data format', | ||
choices:['json','csv'], | ||
default:'csv' | ||
describe:'Set input data format', | ||
choices:['json','csv'], | ||
default:'csv' | ||
}); | ||
@@ -18,7 +18,7 @@ yargs.example('cat somefile.json | tty-table --format=json','Send JSON file to tty-table.'); | ||
yargs.version(function(){ | ||
var fs = require('fs'); | ||
var path =__dirname+'/../package.json'; | ||
var contents = fs.readFileSync(path,'utf-8'); | ||
var json = JSON.parse(contents); | ||
return json.version; | ||
let fs = require('fs'); | ||
let path =__dirname+'/../package.json'; | ||
let contents = fs.readFileSync(path,'utf-8'); | ||
let json = JSON.parse(contents); | ||
return json.version; | ||
}); | ||
@@ -25,0 +25,0 @@ yargs.epilog('Copyight github.com/tecfu 2017'); |
45
test.js
@@ -1,16 +0,29 @@ | ||
let test = (arg) => { | ||
switch(true){ | ||
case(arg === 1): | ||
let a = arg+1; | ||
break; | ||
case(arg === 2): | ||
let a = arg+2; | ||
break; | ||
default: | ||
let a = 3; | ||
} | ||
return a; | ||
} | ||
let a = test(1); | ||
console.log(a); | ||
let exec = require('child_process').exec, child; | ||
child = exec('cat ./examples/data/data.csv | node ./src/terminal-adapter.js', | ||
function (error, stdout, stderr) { | ||
console.log('stdout: ' + stdout); | ||
console.log('stderr: ' + stderr); | ||
//if (error !== null) { | ||
// grunt.log.error('Exec error: ' + error); | ||
//} | ||
//var expected1 = fs.readFileSync('./examples/cli-output.txt',{encoding : 'utf-8'}); | ||
////example result should match saved output | ||
//stdout.should.equal(expected1); | ||
//deferred(); | ||
}); | ||
// | ||
// | ||
//let fs = require('fs'); | ||
//let csv = require('csv'); | ||
//let data = `security,price | ||
//aapl,92.50 | ||
//ibm,120.15`; | ||
//data = fs.readFileSync('./examples/data/data.csv','utf8'); | ||
// | ||
//console.log(data); | ||
// | ||
//let records = csv.parse(data,function(err,data){ | ||
// console.log(data); | ||
//}); | ||
// | ||
// |
@@ -9,27 +9,27 @@ var chai = require("chai"); | ||
//Get list of all test scripts | ||
//Test all example scripts against their saved output | ||
var list = glob.sync('examples/*.js'); | ||
list.forEach(function(element,index,array){ | ||
describe(element,function(){ | ||
it('Should match ' + element + '-output.txt',function(deferred){ | ||
//Matching test | ||
describe(element,function(){ | ||
it('Should match ' + element + '-output.txt',function(deferred){ | ||
var exec = require('child_process').exec, child; | ||
var exec = require('child_process').exec, child; | ||
child = exec('node ./'+element+' --color=always', | ||
function (error, stdout, stderr) { | ||
//console.log('stdout: ' + stdout); | ||
//console.log('stderr: ' + stderr); | ||
if (error !== null) { | ||
grunt.log.error('Exec error: ' + error); | ||
} | ||
var subname = element.split('.')[0]; | ||
var expected1 = fs.readFileSync('./'+subname+'-output.txt',{encoding : 'utf-8'}); | ||
child = exec('node ./'+element+' --color=always', | ||
function (error, stdout, stderr) { | ||
//console.log('stdout: ' + stdout); | ||
//console.log('stderr: ' + stderr); | ||
if (error !== null) { | ||
grunt.log.error('Exec error: ' + error); | ||
} | ||
var subname = element.split('.')[0]; | ||
var expected1 = fs.readFileSync('./'+subname+'-output.txt',{encoding : 'utf-8'}); | ||
stdout.should.equal(expected1); | ||
deferred(); | ||
}); | ||
}); | ||
}); | ||
//example result should match saved output | ||
stdout.should.equal(expected1); | ||
deferred(); | ||
}); | ||
}); | ||
}); | ||
}); |
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
1503785
47
20048
8
15
221
5
+ Addeduse-strict@^1.0.1
+ Addeduse-strict@1.0.1(transitive)