@@ -108,6 +108,9 @@ function escapeStyleCode(code) {
108
108
return `\u001b[${ code } m` ;
109
109
}
110
110
111
+ // eslint-disable-next-line no-control-regex
112
+ const endingRegex = / \u001b \[ [ 3 4 ] 9 m / g;
113
+
111
114
/**
112
115
* @param {string | string[] } format
113
116
* @param {string } text
@@ -134,24 +137,58 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
134
137
skipColorize = ! lazyUtilColors ( ) . shouldColorize ( stream ) ;
135
138
}
136
139
140
+ if ( skipColorize ) {
141
+ return text ;
142
+ }
143
+
137
144
// If the format is not an array, convert it to an array
138
145
const formatArray = ArrayIsArray ( format ) ? format : [ format ] ;
139
146
140
- let left = '' ;
141
- let right = '' ;
147
+ // Collect the codes we're applying
148
+ const codes = [ ] ;
142
149
for ( const key of formatArray ) {
143
150
if ( key === 'none' ) continue ;
144
151
const formatCodes = inspect . colors [ key ] ;
145
152
// If the format is not a valid style, throw an error
146
153
if ( formatCodes == null ) {
147
154
validateOneOf ( key , 'format' , ObjectKeys ( inspect . colors ) ) ;
148
155
}
149
- if ( skipColorize ) continue ;
150
- left += escapeStyleCode ( formatCodes [ 0 ] ) ;
151
- right = `${ escapeStyleCode ( formatCodes [ 1 ] ) } ${ right } ` ;
156
+
157
+ codes . push ( formatCodes ) ;
158
+ }
159
+
160
+ if ( codes . length === 0 ) {
161
+ return text ;
162
+ }
163
+
164
+ // Build opening codes
165
+ let openCodes = '' ;
166
+ for ( const { 0 : open } of codes ) {
167
+ openCodes += escapeStyleCode ( open ) ;
168
+ }
169
+
170
+ // Process the text to handle nested styles
171
+ const processedText = text . replace ( endingRegex , ( match , offset ) => {
172
+ // Check if there's more content after this reset
173
+ if ( offset + match . length < text . length ) {
174
+ for ( const { 0 : open } of codes ) {
175
+ // Check if this is a foreground color (30-37, 90-97) or Background color (40-47, 100-107)
176
+ if ( ( open >= 30 && open <= 37 ) || ( open >= 90 && open <= 97 ) ||
177
+ ( open >= 40 && open <= 47 ) || ( open >= 100 && open <= 107 ) ) {
178
+ return escapeStyleCode ( open ) ;
179
+ }
180
+ }
181
+ }
182
+ return match ;
183
+ } ) ;
184
+
185
+ // Build closing codes in reverse order
186
+ let closeCodes = '' ;
187
+ for ( let i = codes . length - 1 ; i >= 0 ; i -- ) {
188
+ closeCodes += escapeStyleCode ( codes [ i ] [ 1 ] ) ;
152
189
}
153
190
154
- return skipColorize ? text : `${ left } ${ text } ${ right } ` ;
191
+ return `${ openCodes } ${ processedText } ${ closeCodes } ` ;
155
192
}
156
193
157
194
/**
0 commit comments