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:
Anna Henningsen 2019-08-25 01:39:54 +02:00 committed by Anto Aravinth
parent 2cc757f0c7
commit 9e23eeffd0
2 changed files with 22 additions and 10 deletions

View File

@ -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);
}
}

View File

@ -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'
`);