@@ -5,7 +5,9 @@ module.exports = {
55 /**
66 * @typedef TokenStreamItem
77 * @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
911 */
1012
1113 /**
@@ -15,29 +17,46 @@ module.exports = {
1517 * * In arrays each value is transformed individually
1618 * * Values that are empty (empty arrays or strings only containing whitespace)
1719 *
18- * @param {string | TokenStreamItem | Array<string|TokenStreamItem> } tokenStream
19- * @returns {Array<string|Array<string|any[]>> }
20+ * @param {Array<string|TokenStreamItem> } tokenStream
21+ * @returns {SimplifiedTokenStream }
2022 */
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+ }
3453 }
3554 } ,
3655
3756 /**
3857 *
39- * @param {ReadonlyArray<string|ReadonlyArray<string|any[]> > } tokenStream
40- * @param {number } [indentationLevel=0 ]
58+ * @param {Readonly<SimplifiedTokenStream > } tokenStream
59+ * @param {number } [indentationLevel]
4160 */
4261 prettyprint ( tokenStream , indentationLevel = 1 ) {
4362 const indentChar = ' ' ;
@@ -49,6 +68,7 @@ module.exports = {
4968 out += "[\n"
5069 tokenStream . forEach ( ( item , i ) => {
5170 out += indentation ;
71+ let extraNewline = false ;
5272
5373 if ( typeof item === 'string' ) {
5474 out += JSON . stringify ( item ) ;
@@ -65,10 +85,16 @@ module.exports = {
6585 }
6686
6787 out += ']' ;
88+
89+ extraNewline = ! ! item [ 'newline-after' ] ;
6890 }
6991
7092 const lineEnd = ( i === tokenStream . length - 1 ) ? '\n' : ',\n' ;
7193 out += lineEnd ;
94+
95+ if ( extraNewline ) {
96+ out += '\n' ;
97+ }
7298 } )
7399 out += indentation . substr ( indentChar . length ) + ']'
74100 return out ;
0 commit comments