console: use getStringWidth() for character width calculation
This is more accurate for displayed full-width characters (e.g. CJK ones) and makes the calculations match the ones we use in the readline module. Fixes: https://github.com/nodejs/node/issues/29299 PR-URL: https://github.com/nodejs/node/pull/29300 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
2cc757f0c7
commit
9e23eeffd0
@ -2,8 +2,7 @@
|
||||
|
||||
const { Math, ObjectPrototype } = primordials;
|
||||
|
||||
const { Buffer } = require('buffer');
|
||||
const { removeColors } = require('internal/util');
|
||||
const { getStringWidth } = require('internal/readline/utils');
|
||||
|
||||
// The use of Unicode characters below is the only non-comment use of non-ASCII
|
||||
// Unicode characters in Node.js built-in modules. If they are ever removed or
|
||||
@ -29,16 +28,11 @@ const tableChars = {
|
||||
/* 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 len = getStringWidth(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.
|
||||
@ -52,7 +46,7 @@ const renderRow = (row, columnWidths) => {
|
||||
|
||||
const table = (head, columns) => {
|
||||
const rows = [];
|
||||
const columnWidths = head.map((h) => countSymbols(h));
|
||||
const columnWidths = head.map((h) => getStringWidth(h));
|
||||
const longestColumn = columns.reduce((n, a) => Math.max(n, a.length), 0);
|
||||
|
||||
for (var i = 0; i < head.length; i++) {
|
||||
@ -63,7 +57,7 @@ const table = (head, columns) => {
|
||||
const value = rows[j][i] =
|
||||
ObjectPrototype.hasOwnProperty(column, j) ? column[j] : '';
|
||||
const width = columnWidths[i] || 0;
|
||||
const counted = countSymbols(value);
|
||||
const counted = getStringWidth(value);
|
||||
columnWidths[i] = Math.max(width, counted);
|
||||
}
|
||||
}
|
||||
|
@ -258,3 +258,21 @@ test([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }], `
|
||||
└─────────┴──${line}──┘
|
||||
`);
|
||||
}
|
||||
|
||||
test({ foo: '¥', bar: '¥' }, `
|
||||
┌─────────┬────────┐
|
||||
│ (index) │ Values │
|
||||
├─────────┼────────┤
|
||||
│ foo │ '¥' │
|
||||
│ bar │ '¥' │
|
||||
└─────────┴────────┘
|
||||
`);
|
||||
|
||||
test({ foo: '你好', bar: 'hello' }, `
|
||||
┌─────────┬─────────┐
|
||||
│ (index) │ Values │
|
||||
├─────────┼─────────┤
|
||||
│ foo │ '你好' │
|
||||
│ bar │ 'hello' │
|
||||
└─────────┴─────────┘
|
||||
`);
|
||||
|
Loading…
x
Reference in New Issue
Block a user