Skip to content

Commit 6a76774

Browse files
marco-ippolitojcbhmr
authored andcommitted
util: support array of formats in util.styleText
PR-URL: nodejs#52040 Fixes: nodejs#52035 Reviewed-By: Chemi Atlow <[email protected]> Reviewed-By: Paolo Insogna <[email protected]>
1 parent 2afe8cb commit 6a76774

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

doc/api/util.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,7 +1806,8 @@ console.log(util.stripVTControlCharacters('\u001B[4mvalue\u001B[0m'));
18061806
added: v21.7.0
18071807
-->
18081808
1809-
* `format` {string} A text format defined in `util.inspect.colors`.
1809+
* `format` {string | Array} A text format or an Array
1810+
of text formats defined in `util.inspect.colors`.
18101811
* `text` {string} The text to to be formatted.
18111812
18121813
This function returns a formatted text considering the `format` passed.
@@ -1828,7 +1829,16 @@ console.log(errorMessage);
18281829
18291830
```cjs
18301831
console.log(
1831-
util.styleText('underline', util.styleText('italic', 'My italic underlined message')),
1832+
util.styleText(['underline', 'italic'], 'My italic underlined message'),
1833+
);
1834+
```
1835+
1836+
When passing an array of formats, the order of the format applied
1837+
is left to right so the following style might overwrite the previous one.
1838+
1839+
```cjs
1840+
console.log(
1841+
util.styleText(['red', 'green'], 'text'), // green
18321842
);
18331843
```
18341844

lib/util.js

Lines changed: 25 additions & 2 deletions
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

Lines changed: 9 additions & 1 deletion
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)