@@ -25,6 +25,7 @@ const {
25
25
ArrayIsArray,
26
26
ArrayPrototypePop,
27
27
ArrayPrototypePush,
28
+ ArrayPrototypeReduce,
28
29
Error,
29
30
ErrorCaptureStackTrace,
30
31
FunctionPrototypeBind,
@@ -36,6 +37,8 @@ const {
36
37
ObjectSetPrototypeOf,
37
38
ObjectValues,
38
39
ReflectApply,
40
+ RegExp,
41
+ RegExpPrototypeSymbolReplace,
39
42
StringPrototypeToWellFormed,
40
43
} = primordials ;
41
44
@@ -137,8 +140,7 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
137
140
// If the format is not an array, convert it to an array
138
141
const formatArray = ArrayIsArray ( format ) ? format : [ format ] ;
139
142
140
- let left = '' ;
141
- let right = '' ;
143
+ const codes = [ ] ;
142
144
for ( const key of formatArray ) {
143
145
if ( key === 'none' ) continue ;
144
146
const formatCodes = inspect . colors [ key ] ;
@@ -147,11 +149,48 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
147
149
validateOneOf ( key , 'format' , ObjectKeys ( inspect . colors ) ) ;
148
150
}
149
151
if ( skipColorize ) continue ;
150
- left += escapeStyleCode ( formatCodes [ 0 ] ) ;
151
- right = `${ escapeStyleCode ( formatCodes [ 1 ] ) } ${ right } ` ;
152
+ ArrayPrototypePush ( codes , formatCodes ) ;
152
153
}
153
154
154
- return skipColorize ? text : `${ left } ${ text } ${ right } ` ;
155
+ if ( skipColorize ) {
156
+ return text ;
157
+ }
158
+
159
+ // Build opening codes
160
+ let openCodes = '' ;
161
+ for ( let i = 0 ; i < codes . length ; i ++ ) {
162
+ openCodes += escapeStyleCode ( codes [ i ] [ 0 ] ) ;
163
+ }
164
+
165
+ // Process the text to handle nested styles
166
+ let processedText ;
167
+ if ( codes . length > 0 ) {
168
+ processedText = ArrayPrototypeReduce (
169
+ codes ,
170
+ ( text , code ) => RegExpPrototypeSymbolReplace (
171
+ new RegExp ( `\\u001b\\[${ code [ 1 ] } m` , 'g' ) ,
172
+ text ,
173
+ ( match , offset ) => {
174
+ // Check if there's more content after this reset
175
+ if ( offset + match . length < text . length ) {
176
+ return escapeStyleCode ( code [ 0 ] ) ;
177
+ }
178
+ return match ;
179
+ } ,
180
+ ) ,
181
+ text ,
182
+ ) ;
183
+ } else {
184
+ processedText = text ;
185
+ }
186
+
187
+ // Build closing codes in reverse order
188
+ let closeCodes = '' ;
189
+ for ( let i = codes . length - 1 ; i >= 0 ; i -- ) {
190
+ closeCodes += escapeStyleCode ( codes [ i ] [ 1 ] ) ;
191
+ }
192
+
193
+ return `${ openCodes } ${ processedText } ${ closeCodes } ` ;
155
194
}
156
195
157
196
/**
0 commit comments