Skip to content

Commit 9a1e01c

Browse files
util: support array of formats in util.styleText
PR-URL: #52040 Fixes: #52035 Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Paolo Insogna <paolo@cowtech.it>
1 parent d60a871 commit 9a1e01c

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

doc/api/util.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -1800,7 +1800,8 @@ console.log(util.stripVTControlCharacters('\u001B[4mvalue\u001B[0m'));
18001800
added: v21.7.0
18011801
-->
18021802
1803-
* `format` {string} A text format defined in `util.inspect.colors`.
1803+
* `format` {string | Array} A text format or an Array
1804+
of text formats defined in `util.inspect.colors`.
18041805
* `text` {string} The text to to be formatted.
18051806
18061807
This function returns a formatted text considering the `format` passed.
@@ -1822,7 +1823,16 @@ console.log(errorMessage);
18221823
18231824
```cjs
18241825
console.log(
1825-
util.styleText('underline', util.styleText('italic', 'My italic underlined message')),
1826+
util.styleText(['underline', 'italic'], 'My italic underlined message'),
1827+
);
1828+
```
1829+
1830+
When passing an array of formats, the order of the format applied
1831+
is left to right so the following style might overwrite the previous one.
1832+
1833+
```cjs
1834+
console.log(
1835+
util.styleText(['red', 'green'], 'text'), // green
18261836
);
18271837
```
18281838

lib/util.js

+25-2
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,40 @@ function pad(n) {
199199
}
200200

201201
/**
202-
* @param {string} format
202+
* @param {string} code
203+
* @returns {string}
204+
*/
205+
function escapeStyleCode(code) {
206+
return `\u001b[${code}m`;
207+
}
208+
209+
/**
210+
* @param {string | string[]} format
203211
* @param {string} text
204212
* @returns {string}
205213
*/
206214
function styleText(format, text) {
207215
validateString(text, 'text');
216+
if (ArrayIsArray(format)) {
217+
let left = '';
218+
let right = '';
219+
for (const key of format) {
220+
const formatCodes = inspect.colors[key];
221+
if (formatCodes == null) {
222+
validateOneOf(key, 'format', ObjectKeys(inspect.colors));
223+
}
224+
left += escapeStyleCode(formatCodes[0]);
225+
right = `${escapeStyleCode(formatCodes[1])}${right}`;
226+
}
227+
228+
return `${left}${text}${right}`;
229+
}
230+
208231
const formatCodes = inspect.colors[format];
209232
if (formatCodes == null) {
210233
validateOneOf(format, 'format', ObjectKeys(inspect.colors));
211234
}
212-
return `\u001b[${formatCodes[0]}m${text}\u001b[${formatCodes[1]}m`;
235+
return `${escapeStyleCode(formatCodes[0])}${text}${escapeStyleCode(formatCodes[1])}`;
213236
}
214237

215238
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',

test/parallel/test-util-styletext.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const util = require('util');
1212
Symbol(),
1313
() => {},
1414
{},
15-
[],
1615
].forEach((invalidOption) => {
1716
assert.throws(() => {
1817
util.styleText(invalidOption, 'test');
@@ -33,3 +32,12 @@ assert.throws(() => {
3332
});
3433

3534
assert.strictEqual(util.styleText('red', 'test'), '\u001b[31mtest\u001b[39m');
35+
36+
assert.strictEqual(util.styleText(['bold', 'red'], 'test'), '\u001b[1m\u001b[31mtest\u001b[39m\u001b[22m');
37+
assert.strictEqual(util.styleText(['bold', 'red'], 'test'), util.styleText('bold', util.styleText('red', 'test')));
38+
39+
assert.throws(() => {
40+
util.styleText(['invalid'], 'text');
41+
}, {
42+
code: 'ERR_INVALID_ARG_VALUE',
43+
});

0 commit comments

Comments
 (0)