trouble-in-terror-town/node_modules/cli-table/lib/index.js
Mikolaj 2bbacbea09 did some more work on networking and removed EOS in favor of LRM
did some more work on networking and removed EOS in favor of Light Reflective Mirror
2022-05-31 15:04:31 +02:00

304 lines
7.7 KiB
JavaScript

/**
* Module dependencies.
*/
var colors = require('colors/safe')
, utils = require('./utils')
, repeat = utils.repeat
, truncate = utils.truncate
, pad = utils.pad;
/**
* Table constructor
*
* @param {Object} options
* @api public
*/
function Table (options){
this.options = utils.options({
chars: {
'top': '─'
, 'top-mid': '┬'
, 'top-left': '┌'
, 'top-right': '┐'
, 'bottom': '─'
, 'bottom-mid': '┴'
, 'bottom-left': '└'
, 'bottom-right': '┘'
, 'left': '│'
, 'left-mid': '├'
, 'mid': '─'
, 'mid-mid': '┼'
, 'right': '│'
, 'right-mid': '┤'
, 'middle': '│'
}
, truncate: '…'
, colWidths: []
, colAligns: []
, style: {
'padding-left': 1
, 'padding-right': 1
, head: ['red']
, border: ['grey']
, compact : false
}
, head: []
}, options);
if (options && options.rows) {
for (var i = 0; i < options.rows.length; i++) {
this.push(options.rows[i]);
}
}
}
/**
* Inherit from Array.
*/
Table.prototype.__proto__ = Array.prototype;
/**
* Width getter
*
* @return {Number} width
* @api public
*/
Table.prototype.__defineGetter__('width', function (){
var str = this.toString().split("\n");
if (str.length) return str[0].length;
return 0;
});
/**
* Render to a string.
*
* @return {String} table representation
* @api public
*/
Table.prototype.render
Table.prototype.toString = function (){
var ret = ''
, options = this.options
, style = options.style
, head = options.head
, chars = options.chars
, truncater = options.truncate
, colWidths = options.colWidths || new Array(this.head.length)
, totalWidth = 0;
if (!head.length && !this.length) return '';
if (!colWidths.length){
var all_rows = this.slice(0);
if (head.length) { all_rows = all_rows.concat([head]) };
all_rows.forEach(function(cells){
// horizontal (arrays)
if (typeof cells === 'object' && cells.length) {
extractColumnWidths(cells);
// vertical (objects)
} else {
var header_cell = Object.keys(cells)[0]
, value_cell = cells[header_cell];
colWidths[0] = Math.max(colWidths[0] || 0, get_width(header_cell) || 0);
// cross (objects w/ array values)
if (typeof value_cell === 'object' && value_cell.length) {
extractColumnWidths(value_cell, 1);
} else {
colWidths[1] = Math.max(colWidths[1] || 0, get_width(value_cell) || 0);
}
}
});
};
totalWidth = (colWidths.length == 1 ? colWidths[0] : colWidths.reduce(
function (a, b){
return a + b
})) + colWidths.length + 1;
function extractColumnWidths(arr, offset) {
var offset = offset || 0;
arr.forEach(function(cell, i){
colWidths[i + offset] = Math.max(colWidths[i + offset] || 0, get_width(cell) || 0);
});
};
function get_width(obj) {
return typeof obj == 'object' && obj.width != undefined
? obj.width
: ((typeof obj == 'object' ? utils.strlen(obj.text) : utils.strlen(obj)) + (style['padding-left'] || 0) + (style['padding-right'] || 0))
}
// draws a line
function line (line, left, right, intersection){
var width = 0
, line =
left
+ repeat(line, totalWidth - 2)
+ right;
colWidths.forEach(function (w, i){
if (i == colWidths.length - 1) return;
width += w + 1;
line = line.substr(0, width) + intersection + line.substr(width + 1);
});
return applyStyles(options.style.border, line);
};
// draws the top line
function lineTop (){
var l = line(chars.top
, chars['top-left'] || chars.top
, chars['top-right'] || chars.top
, chars['top-mid']);
if (l)
ret += l + "\n";
};
function generateRow (items, style) {
var cells = []
, max_height = 0;
// prepare vertical and cross table data
if (!Array.isArray(items) && typeof items === "object") {
var key = Object.keys(items)[0]
, value = items[key]
, first_cell_head = true;
if (Array.isArray(value)) {
items = value;
items.unshift(key);
} else {
items = [key, value];
}
}
// transform array of item strings into structure of cells
items.forEach(function (item, i) {
var contents = item.toString().split("\n").reduce(function (memo, l) {
memo.push(string(l, i));
return memo;
}, [])
var height = contents.length;
if (height > max_height) { max_height = height };
cells.push({ contents: contents , height: height });
});
// transform vertical cells into horizontal lines
var lines = new Array(max_height);
cells.forEach(function (cell, i) {
cell.contents.forEach(function (line, j) {
if (!lines[j]) { lines[j] = [] };
if (style || (first_cell_head && i === 0 && options.style.head)) {
line = applyStyles(options.style.head, line)
}
lines[j].push(line);
});
// populate empty lines in cell
for (var j = cell.height, l = max_height; j < l; j++) {
if (!lines[j]) { lines[j] = [] };
lines[j].push(string('', i));
}
});
var ret = "";
lines.forEach(function (line, index) {
if (ret.length > 0) {
ret += "\n" + applyStyles(options.style.border, chars.left);
}
ret += line.join(applyStyles(options.style.border, chars.middle)) + applyStyles(options.style.border, chars.right);
});
return applyStyles(options.style.border, chars.left) + ret;
};
function applyStyles(styles, subject) {
if (!subject)
return '';
styles.forEach(function(style) {
subject = colors[style](subject);
});
return subject;
};
// renders a string, by padding it or truncating it
function string (str, index){
var str = String(typeof str == 'object' && str.text ? str.text : str)
, length = utils.strlen(str)
, width = colWidths[index]
- (style['padding-left'] || 0)
- (style['padding-right'] || 0)
, align = options.colAligns[index] || 'left';
return repeat(' ', style['padding-left'] || 0)
+ (length == width ? str :
(length < width
? pad(str, ( width + (str.length - length) ), ' ', align == 'left' ? 'right' :
(align == 'middle' ? 'both' : 'left'))
: (truncater ? truncate(str, width, truncater) : str))
)
+ repeat(' ', style['padding-right'] || 0);
};
if (head.length){
lineTop();
ret += generateRow(head, style.head) + "\n"
}
if (this.length)
this.forEach(function (cells, i){
if (!head.length && i == 0)
lineTop();
else {
if (!style.compact || i<(!!head.length) ?1:0 || cells.length == 0){
var l = line(chars.mid
, chars['left-mid']
, chars['right-mid']
, chars['mid-mid']);
if (l)
ret += l + "\n"
}
}
if (cells.hasOwnProperty("length") && !cells.length) {
return
} else {
ret += generateRow(cells) + "\n";
};
});
var l = line(chars.bottom
, chars['bottom-left'] || chars.bottom
, chars['bottom-right'] || chars.bottom
, chars['bottom-mid']);
if (l)
ret += l;
else
// trim the last '\n' if we didn't add the bottom decoration
ret = ret.slice(0, -1);
return ret;
};
/**
* Module exports.
*/
module.exports = Table;
module.exports.version = '0.0.1';