-
Notifications
You must be signed in to change notification settings - Fork 30.3k
Commit
PR-URL: #18137 Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -332,6 +332,47 @@ console.log('count:', count); | |
|
||
See [`util.format()`][] for more information. | ||
|
||
### console.table(tabularData[, properties]) | ||
<!-- YAML | ||
added: REPLACEME | ||
--> | ||
|
||
* `tabularData` {any} | ||
* `properties` {string[]} Alternate properties for constructing the table. | ||
|
||
Try to construct a table with the columns of the properties of `tabularData` | ||
(or use `properties`) and rows of `tabularData` and logit. Falls back to just | ||
logging the argument if it can’t be parsed as tabular. | ||
|
||
```js | ||
// These can't be parsed as tabular data | ||
console.table(Symbol()); | ||
// Symbol() | ||
|
||
console.table(undefined); | ||
// undefined | ||
``` | ||
|
||
```js | ||
console.table([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }]); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Trott
Member
|
||
// ┌─────────┬─────┬─────┐ | ||
// │ (index) │ a │ b │ | ||
// ├─────────┼─────┼─────┤ | ||
// │ 0 │ 1 │ 'Y' │ | ||
// │ 1 │ 'Z' │ 2 │ | ||
// └─────────┴─────┴─────┘ | ||
``` | ||
|
||
```js | ||
console.table([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }], ['a']); | ||
// ┌─────────┬─────┐ | ||
// │ (index) │ a │ | ||
// ├─────────┼─────┤ | ||
// │ 0 │ 1 │ | ||
// │ 1 │ 'Z' │ | ||
// └─────────┴─────┘ | ||
``` | ||
|
||
### console.time(label) | ||
<!-- YAML | ||
added: v0.1.104 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
'use strict'; | ||
|
||
const { Buffer } = require('buffer'); | ||
const { removeColors } = require('internal/util'); | ||
const HasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); | ||
|
||
const tableChars = { | ||
/* eslint-disable node-core/non-ascii-character */ | ||
middleMiddle: '─', | ||
rowMiddle: '┼', | ||
topRight: '┐', | ||
topLeft: '┌', | ||
leftMiddle: '├', | ||
topMiddle: '┬', | ||
bottomRight: '┘', | ||
bottomLeft: '└', | ||
bottomMiddle: '┴', | ||
rightMiddle: '┤', | ||
left: '│ ', | ||
right: ' │', | ||
middle: ' │ ', | ||
/* eslint-enable node-core/non-ascii-character */ | ||
}; | ||
|
||
const countSymbols = (string) => { | ||
const normalized = removeColors(string).normalize('NFC'); | ||
return Buffer.from(normalized, 'UCS-2').byteLength / 2; | ||
}; | ||
|
||
const renderRow = (row, columnWidths) => { | ||
let out = tableChars.left; | ||
for (var i = 0; i < row.length; i++) { | ||
const cell = row[i]; | ||
const len = countSymbols(cell); | ||
const needed = (columnWidths[i] - len) / 2; | ||
// round(needed) + ceil(needed) will always add up to the amount | ||
// of spaces we need while also left justifying the output. | ||
out += `${' '.repeat(needed)}${cell}${' '.repeat(Math.ceil(needed))}`; | ||
if (i !== row.length - 1) | ||
out += tableChars.middle; | ||
} | ||
out += tableChars.right; | ||
return out; | ||
}; | ||
|
||
const table = (head, columns) => { | ||
const rows = []; | ||
const columnWidths = head.map((h) => countSymbols(h)); | ||
const longestColumn = columns.reduce((n, a) => Math.max(n, a.length), 0); | ||
|
||
for (var i = 0; i < head.length; i++) { | ||
const column = columns[i]; | ||
for (var j = 0; j < longestColumn; j++) { | ||
if (!rows[j]) | ||
rows[j] = []; | ||
const v = rows[j][i] = HasOwnProperty(column, j) ? column[j] : ''; | ||
const width = columnWidths[i] || 0; | ||
const counted = countSymbols(v); | ||
columnWidths[i] = Math.max(width, counted); | ||
} | ||
} | ||
|
||
const divider = columnWidths.map((i) => | ||
tableChars.middleMiddle.repeat(i + 2)); | ||
|
||
const tl = tableChars.topLeft; | ||
const tr = tableChars.topRight; | ||
const lm = tableChars.leftMiddle; | ||
let result = `${tl}${divider.join(tableChars.topMiddle)}${tr} | ||
${renderRow(head, columnWidths)} | ||
${lm}${divider.join(tableChars.rowMiddle)}${tableChars.rightMiddle} | ||
`; | ||
|
||
for (const row of rows) | ||
result += `${renderRow(row, columnWidths)}\n`; | ||
|
||
result += `${tableChars.bottomLeft}${ | ||
divider.join(tableChars.bottomMiddle)}${tableChars.bottomRight}`; | ||
|
||
return result; | ||
}; | ||
|
||
module.exports = table; |
Should be
Right?