11'use strict'
22
3- var isEmpty = require ( 'is-empty' )
43var color = require ( './color' )
54
65module . exports = color ? inspect : /* istanbul ignore next */ noColor
@@ -10,6 +9,7 @@ noColor.color = inspect
109inspect . noColor = noColor
1110noColor . noColor = noColor
1211
12+ var bold = ansiColor ( 1 , 22 )
1313var dim = ansiColor ( 2 , 22 )
1414var yellow = ansiColor ( 33 , 39 )
1515var green = ansiColor ( 32 , 39 )
@@ -21,7 +21,10 @@ var colorExpression = /(?:(?:\u001B\[)|\u009B)(?:\d{1,3})?(?:(?:;\d{0,3})*)?[A-M
2121// we format differently.
2222// We don’t ignore `data` though.
2323// Also includes `name` (from xast) and `tagName` (from `hast`).
24- var ignore = [ 'type' , 'value' , 'children' , 'position' , 'name' , 'tagName' ]
24+ var ignore = [ 'type' , 'value' , 'children' , 'position' ]
25+ var ignoreString = [ 'name' , 'tagName' ]
26+
27+ var dataOnly = [ 'data' , 'attributes' , 'properties' ]
2528
2629// Inspects a node, without using color.
2730function noColor ( node ) {
@@ -37,103 +40,139 @@ function inspect(node, options) {
3740 showPositions = true
3841 }
3942
40- return inspectValue ( node , '' )
43+ return inspectValue ( node )
4144
42- function inspectValue ( node , pad ) {
45+ function inspectValue ( node ) {
4346 if ( node && Boolean ( node . length ) && typeof node === 'object' ) {
44- return inspectAll ( node , pad )
47+ return inspectNodes ( node )
4548 }
4649
4750 if ( node && node . type ) {
48- return inspectTree ( node , pad )
51+ return inspectTree ( node )
4952 }
5053
51- return inspectNonTree ( node , pad )
54+ return inspectNonTree ( node )
5255 }
5356
54- function inspectNonTree ( value , pad ) {
55- return formatNesting ( pad ) + String ( value )
57+ function inspectNonTree ( value ) {
58+ return JSON . stringify ( value )
5659 }
5760
58- function inspectAll ( nodes , pad ) {
61+ function inspectNodes ( nodes ) {
5962 var length = nodes . length
6063 var index = - 1
6164 var result = [ ]
6265 var node
6366 var tail
67+ var value
6468
6569 while ( ++ index < length ) {
6670 node = nodes [ index ]
6771 tail = index === length - 1
6872
73+ value =
74+ dim ( ( tail ? '└' : '├' ) + '─' + index ) +
75+ ' ' +
76+ indent ( inspectValue ( node ) , ( tail ? ' ' : dim ( '│' ) ) + ' ' , true )
77+
78+ result . push ( value )
79+ }
80+
81+ return result . join ( '\n' )
82+ }
83+
84+ function inspectFields ( object ) {
85+ var nonEmpty = object . children && object . children . length
86+ var result = [ ]
87+ var key
88+ var value
89+ var formatted
90+
91+ for ( key in object ) {
92+ value = object [ key ]
93+
94+ if (
95+ value === undefined ||
96+ ignore . indexOf ( key ) !== - 1 ||
97+ ( ignoreString . indexOf ( key ) !== - 1 && typeof value === 'string' )
98+ ) {
99+ continue
100+ }
101+
102+ if (
103+ value &&
104+ typeof value === 'object' &&
105+ typeof value . type === 'string' &&
106+ dataOnly . indexOf ( key ) === - 1
107+ ) {
108+ formatted = inspectTree ( value )
109+ } else if (
110+ Array . isArray ( value ) &&
111+ value [ 0 ] &&
112+ typeof value [ 0 ] === 'object' &&
113+ typeof value [ 0 ] . type === 'string'
114+ ) {
115+ formatted = '\n' + inspectNodes ( value )
116+ } else {
117+ formatted = inspectNonTree ( value )
118+ }
119+
69120 result . push (
70- formatNesting ( pad + ( tail ? '└' : '├' ) + '─ ' ) ,
71- inspectValue ( node , pad + ( tail ? ' ' : '│' ) + ' ' ) ,
72- tail ? '' : '\n'
121+ key + dim ( ':' ) + ( / \s / . test ( formatted . charAt ( 0 ) ) ? '' : ' ' ) + formatted
73122 )
74123 }
75124
76- return result . join ( '' )
125+ return indent ( result . join ( '\n' ) , ( nonEmpty ? dim ( '│' ) : ' ' ) + ' ')
77126 }
78127
79128 function inspectTree ( node , pad ) {
80- var result = formatNode ( node , pad )
81- var content = inspectAll ( node . children || [ ] , pad )
82- return content ? result + '\n' + content : result
83- }
84-
85- // Colored nesting formatter.
86- function formatNesting ( value ) {
87- return value ? dim ( value ) : ''
129+ var result = [ formatNode ( node , pad ) ]
130+ var fields = inspectFields ( node )
131+ var content = inspectNodes ( node . children || [ ] )
132+ if ( fields ) result . push ( fields )
133+ if ( content ) result . push ( content )
134+ return result . join ( '\n' )
88135 }
89136
90137 // Colored node formatter.
91138 function formatNode ( node ) {
92- var result = [ node . type ]
139+ var result = [ bold ( node . type ) ]
93140 var kind = node . tagName || node . name
94141 var position = node . position || { }
95142 var location = showPositions
96143 ? stringifyPosition ( position . start , position . end )
97144 : ''
98- var attributes = [ ]
99- var key
100- var value
101145
102- if ( kind ) {
146+ if ( typeof kind === 'string' ) {
103147 result . push ( '<' , kind , '>' )
104148 }
105149
106150 if ( node . children ) {
107151 result . push ( dim ( '[' ) , yellow ( node . children . length ) , dim ( ']' ) )
108152 } else if ( typeof node . value === 'string' ) {
109- result . push ( dim ( ': ' ) , green ( JSON . stringify ( node . value ) ) )
153+ result . push ( ' ' , green ( inspectNonTree ( node . value , '' ) ) )
110154 }
111155
112156 if ( location ) {
113- result . push ( ' (' , location , ')' )
157+ result . push ( ' ' , dim ( '(' ) , location , dim ( ')' ) )
114158 }
115159
116- for ( key in node ) {
117- value = node [ key ]
118-
119- if (
120- ignore . indexOf ( key ) !== - 1 ||
121- value === null ||
122- value === undefined ||
123- ( typeof value === 'object' && isEmpty ( value ) )
124- ) {
125- continue
126- }
160+ return result . join ( '' )
161+ }
162+ }
127163
128- attributes . push ( '[' + key + '=' + JSON . stringify ( value ) + ']' )
129- }
164+ function indent ( value , indentation , ignoreFirst ) {
165+ var lines = value . split ( '\n' )
166+ var index = ignoreFirst ? 0 : - 1
167+ var length = lines . length
130168
131- if ( attributes . length !== 0 ) {
132- result = result . concat ( ' ' , attributes )
133- }
169+ if ( value === '' ) return ''
134170
135- return result . join ( '' )
171+ while ( ++ index < length ) {
172+ lines [ index ] = indentation + lines [ index ]
136173 }
174+
175+ return lines . join ( '\n' )
137176}
138177
139178// Compile a position.
0 commit comments