Skip to content

Commit

Permalink
util: support array of formats in util.styleText
Browse files Browse the repository at this point in the history
PR-URL: #52040
Fixes: #52035
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
  • Loading branch information
marco-ippolito authored Mar 15, 2024
1 parent d60a871 commit 9a1e01c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
14 changes: 12 additions & 2 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -1800,7 +1800,8 @@ console.log(util.stripVTControlCharacters('\u001B[4mvalue\u001B[0m'));
added: v21.7.0
-->
* `format` {string} A text format defined in `util.inspect.colors`.
* `format` {string | Array} A text format or an Array
of text formats defined in `util.inspect.colors`.
* `text` {string} The text to to be formatted.
This function returns a formatted text considering the `format` passed.
Expand All @@ -1822,7 +1823,16 @@ console.log(errorMessage);
```cjs
console.log(
util.styleText('underline', util.styleText('italic', 'My italic underlined message')),
util.styleText(['underline', 'italic'], 'My italic underlined message'),
);
```
When passing an array of formats, the order of the format applied
is left to right so the following style might overwrite the previous one.
```cjs
console.log(
util.styleText(['red', 'green'], 'text'), // green
);
```
Expand Down
27 changes: 25 additions & 2 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,17 +199,40 @@ function pad(n) {
}

/**
* @param {string} format
* @param {string} code
* @returns {string}
*/
function escapeStyleCode(code) {
return `\u001b[${code}m`;
}

/**
* @param {string | string[]} format
* @param {string} text
* @returns {string}
*/
function styleText(format, text) {
validateString(text, 'text');
if (ArrayIsArray(format)) {
let left = '';
let right = '';
for (const key of format) {
const formatCodes = inspect.colors[key];
if (formatCodes == null) {
validateOneOf(key, 'format', ObjectKeys(inspect.colors));
}
left += escapeStyleCode(formatCodes[0]);
right = `${escapeStyleCode(formatCodes[1])}${right}`;
}

return `${left}${text}${right}`;
}

const formatCodes = inspect.colors[format];
if (formatCodes == null) {
validateOneOf(format, 'format', ObjectKeys(inspect.colors));
}
return `\u001b[${formatCodes[0]}m${text}\u001b[${formatCodes[1]}m`;
return `${escapeStyleCode(formatCodes[0])}${text}${escapeStyleCode(formatCodes[1])}`;
}

const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
Expand Down
10 changes: 9 additions & 1 deletion test/parallel/test-util-styletext.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const util = require('util');
Symbol(),
() => {},
{},
[],
].forEach((invalidOption) => {
assert.throws(() => {
util.styleText(invalidOption, 'test');
Expand All @@ -33,3 +32,12 @@ assert.throws(() => {
});

assert.strictEqual(util.styleText('red', 'test'), '\u001b[31mtest\u001b[39m');

assert.strictEqual(util.styleText(['bold', 'red'], 'test'), '\u001b[1m\u001b[31mtest\u001b[39m\u001b[22m');
assert.strictEqual(util.styleText(['bold', 'red'], 'test'), util.styleText('bold', util.styleText('red', 'test')));

assert.throws(() => {
util.styleText(['invalid'], 'text');
}, {
code: 'ERR_INVALID_ARG_VALUE',
});

0 comments on commit 9a1e01c

Please sign in to comment.