@@ -112,6 +112,55 @@ function escapeStyleCode(code) {
112112 return `\u001b[${ code } m` ;
113113}
114114
115+ /**
116+ * @param {number } code
117+ * @returns {number }
118+ */
119+ function hexToNibble ( code ) {
120+ // '0'-'9'
121+ if ( code >= 48 && code <= 57 ) return code - 48 ;
122+ // 'A'-'F'
123+ if ( code >= 65 && code <= 70 ) return code - 55 ;
124+ // 'a'-'f'
125+ if ( code >= 97 && code <= 102 ) return code - 87 ;
126+ return - 1 ;
127+ }
128+
129+ const hastagCharcode = 35
130+
131+ /**
132+ * Parses a hex color in #RGB or #RRGGBB form.
133+ * Returns RGB bytes on success, otherwise undefined
134+ * .
135+ * @param {string } format
136+ * @returns {[number, number, number] | undefined }
137+ */
138+ function parseHexColor ( format ) {
139+ if ( format . length !== 4 && format . length !== 7 ) return ;
140+
141+ if ( format . length === 4 ) {
142+ const r = hexToNibble ( format . charCodeAt ( 1 ) ) ;
143+ const g = hexToNibble ( format . charCodeAt ( 2 ) ) ;
144+ const b = hexToNibble ( format . charCodeAt ( 3 ) ) ;
145+
146+ if ( ( r | g | b ) < 0 ) return ;
147+
148+ // Duplicate nibbles: #RGB -> #RRGGBB
149+ return [ ( r << 4 ) | r , ( g << 4 ) | g , ( b << 4 ) | b ] ;
150+ }
151+
152+ const r1 = hexToNibble ( format . charCodeAt ( 1 ) ) ;
153+ const r2 = hexToNibble ( format . charCodeAt ( 2 ) ) ;
154+ const g1 = hexToNibble ( format . charCodeAt ( 3 ) ) ;
155+ const g2 = hexToNibble ( format . charCodeAt ( 4 ) ) ;
156+ const b1 = hexToNibble ( format . charCodeAt ( 5 ) ) ;
157+ const b2 = hexToNibble ( format . charCodeAt ( 6 ) ) ;
158+
159+ if ( ( r1 | r2 | g1 | g2 | b1 | b2 ) < 0 ) return ;
160+
161+ return [ ( r1 << 4 ) | r2 , ( g1 << 4 ) | g2 , ( b1 << 4 ) | b2 ] ;
162+ }
163+
115164/**
116165 * @param {string | string[] } format
117166 * @param {string } text
@@ -144,6 +193,15 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
144193 const codes = [ ] ;
145194 for ( const key of formatArray ) {
146195 if ( key === 'none' ) continue ;
196+
197+ if ( typeof key === 'string' && key . charCodeAt ( 0 ) === hastagCharcode ) {
198+ const rgb = parseHexColor ( key ) ;
199+ if ( rgb !== undefined && ! skipColorize ) {
200+ ArrayPrototypePush ( codes , [ `38;2;${ rgb [ 0 ] } ;${ rgb [ 1 ] } ;${ rgb [ 2 ] } ` , 39 ] ) ;
201+ }
202+ continue ;
203+ }
204+
147205 const formatCodes = inspect . colors [ key ] ;
148206 // If the format is not a valid style, throw an error
149207 if ( formatCodes == null ) {
0 commit comments