forked from httptoolkit/httpsnippet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode-builder.js
More file actions
131 lines (113 loc) · 3.08 KB
/
code-builder.js
File metadata and controls
131 lines (113 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
'use strict'
const formatString = require('./format')
/**
* Helper object to format and aggragate lines of code.
* Lines are aggregated in a `code` array, and need to be joined to obtain a proper code snippet.
*
* @class
*
* @param {string} indentation Desired indentation character for aggregated lines of code
* @param {string} join Desired character to join each line of code
*/
class CodeBuilder {
constructor (indentation, join) {
this.code = []
this.indentation = indentation
this.lineJoin = join || '\n'
this.indentLevel = 0
}
/**
* Increase indentation level
* @returns {this}
*/
indent () {
this.indentLevel++
return this
}
/**
* Decrease indentation level
* @returns {this}
*/
unindent () {
this.indentLevel--
return this
}
/**
* Reset indentation level
* @returns {this}
*/
reindent () {
this.indentLevel = 0
return this
}
/**
* Add given indentation level to given string and format the string (variadic)
* @param {number} [indentationLevel=0] - Desired level of indentation for this line
* @param {string} line - Line of code. Can contain formatting placeholders
* @param {...anyobject} - Parameter to bind to `line`'s formatting placeholders
* @return {string}
*
* @example
* var builder = CodeBuilder('\t')
*
* builder.buildLine('console.log("hello world")')
* // returns: 'console.log("hello world")'
*
* builder.buildLine(2, 'console.log("hello world")')
* // returns: 'console.log("\t\thello world")'
*
* builder.buildLine(2, 'console.log("%q %q")', 'hello', 'world')
* // returns: 'console.log("\t\thello world")'
*/
buildLine (indentationLevel, line, ...format) {
let lineIndentation = ''
if (typeof indentationLevel !== 'number') {
return this.buildLine(0, ...arguments)
}
if (!line) return
indentationLevel += this.indentLevel
while (indentationLevel > 0) {
lineIndentation += this.indentation
indentationLevel--
}
// custom format option: escape %q
line = lineIndentation + line
return formatString(line, ...format)
}
/**
* Invoke buildLine() and add the line at the top of current lines
* @param {number} [indentationLevel=0] Desired level of indentation for this line
* @param {string} line Line of code
* @return {this}
*/
unshift () {
this.code.unshift(this.buildLine.apply(this, arguments))
return this
}
/**
* Invoke buildLine() and add the line at the bottom of current lines
* @param {number} [indentationLevel=0] Desired level of indentation for this line
* @param {string} line Line of code
* @return {this}
*/
push () {
this.code.push(this.buildLine.apply(this, arguments))
return this
}
/**
* Add an empty line at the end of current lines
* @return {this}
*/
blank () {
this.code.push(null)
return this
}
/**
* Concatenate all current lines using the given lineJoin
* @return {string}
*/
join () {
return this.code.join(this.lineJoin)
}
}
module.exports = CodeBuilder