@@ -5,7 +5,9 @@ module.exports = {
5
5
/**
6
6
* @typedef TokenStreamItem
7
7
* @property {string } type
8
- * @property {string | TokenStreamItem | Array<string|TokenStreamItem> } content
8
+ * @property {string | Array<string|TokenStreamItem> } content
9
+ *
10
+ * @typedef {Array<string | [string, string | Array]> } SimplifiedTokenStream
9
11
*/
10
12
11
13
/**
@@ -15,29 +17,46 @@ module.exports = {
15
17
* * In arrays each value is transformed individually
16
18
* * Values that are empty (empty arrays or strings only containing whitespace)
17
19
*
18
- * @param {string | TokenStreamItem | Array<string|TokenStreamItem> } tokenStream
19
- * @returns {Array<string|Array<string|any[]>> }
20
+ * @param {Array<string|TokenStreamItem> } tokenStream
21
+ * @returns {SimplifiedTokenStream }
20
22
*/
21
- simplify ( tokenStream ) {
22
- if ( Array . isArray ( tokenStream ) ) {
23
- return tokenStream
24
- . map ( value => this . simplify ( value ) )
25
- . filter ( value => {
26
- return ! ( Array . isArray ( value ) && ! value . length ) && ! ( typeof value === "string" && ! value . trim ( ) . length ) ;
27
- } ) ;
28
- }
29
- else if ( typeof tokenStream === "object" ) {
30
- return [ tokenStream . type , this . simplify ( tokenStream . content ) ] ;
31
- }
32
- else {
33
- return tokenStream ;
23
+ simplify : function simplify ( tokenStream ) {
24
+ return tokenStream
25
+ . map ( innerSimple )
26
+ . filter ( ( value , i , arr ) => {
27
+ if ( typeof value === "string" && ! value . trim ( ) . length ) {
28
+ // string contains only spaces
29
+ if ( i > 0 && i < arr . length - 1 && value . split ( / \r \n ? | \n / g) . length > 2 ) {
30
+ // in a valid token stream there are no adjacent strings, so we know that the previous
31
+ // element is a (simplified) token
32
+ arr [ i - 1 ] [ 'newline-after' ] = true ;
33
+ }
34
+ return false ;
35
+ }
36
+ return true ;
37
+ } ) ;
38
+
39
+ /**
40
+ * @param {string | TokenStreamItem } value
41
+ * @returns {string | [string, string | Array] }
42
+ */
43
+ function innerSimple ( value ) {
44
+ if ( typeof value === "object" ) {
45
+ if ( Array . isArray ( value . content ) ) {
46
+ return [ value . type , simplify ( value . content ) ] ;
47
+ } else {
48
+ return [ value . type , value . content ] ;
49
+ }
50
+ } else {
51
+ return value ;
52
+ }
34
53
}
35
54
} ,
36
55
37
56
/**
38
57
*
39
- * @param {ReadonlyArray<string|ReadonlyArray<string|any[]> > } tokenStream
40
- * @param {number } [indentationLevel=0 ]
58
+ * @param {Readonly<SimplifiedTokenStream > } tokenStream
59
+ * @param {number } [indentationLevel]
41
60
*/
42
61
prettyprint ( tokenStream , indentationLevel = 1 ) {
43
62
const indentChar = ' ' ;
@@ -49,6 +68,7 @@ module.exports = {
49
68
out += "[\n"
50
69
tokenStream . forEach ( ( item , i ) => {
51
70
out += indentation ;
71
+ let extraNewline = false ;
52
72
53
73
if ( typeof item === 'string' ) {
54
74
out += JSON . stringify ( item ) ;
@@ -65,10 +85,16 @@ module.exports = {
65
85
}
66
86
67
87
out += ']' ;
88
+
89
+ extraNewline = ! ! item [ 'newline-after' ] ;
68
90
}
69
91
70
92
const lineEnd = ( i === tokenStream . length - 1 ) ? '\n' : ',\n' ;
71
93
out += lineEnd ;
94
+
95
+ if ( extraNewline ) {
96
+ out += '\n' ;
97
+ }
72
98
} )
73
99
out += indentation . substr ( indentChar . length ) + ']'
74
100
return out ;
0 commit comments