Skip to content

Commit a5107ea

Browse files
authored
Merge pull request #2 from uWynell/feature-upgrade-codebuilder
Add %v and %q options to format in CodeBuilder.buildLine and some handy indentation methods
2 parents 8a82fcb + 2401900 commit a5107ea

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

src/helpers/code-builder.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22

3-
const util = require('util')
3+
const formatString = require('./format')
44

55
/**
66
* Helper object to format and aggragate lines of code.
@@ -13,6 +13,7 @@ const util = require('util')
1313
*/
1414
const CodeBuilder = function (indentation, join) {
1515
this.code = []
16+
this.indentLevel = 0
1617
this.indentation = indentation
1718
this.lineJoin = join || '\n'
1819
}
@@ -42,7 +43,7 @@ CodeBuilder.prototype.buildLine = function (indentationLevel, line) {
4243
if (Object.prototype.toString.call(indentationLevel) === '[object String]') {
4344
slice = 1
4445
line = indentationLevel
45-
indentationLevel = 0
46+
indentationLevel = this.indentLevel
4647
} else if (indentationLevel === null) {
4748
return null
4849
}
@@ -55,7 +56,7 @@ CodeBuilder.prototype.buildLine = function (indentationLevel, line) {
5556
const format = Array.prototype.slice.call(arguments, slice, arguments.length)
5657
format.unshift(lineIndentation + line)
5758

58-
return util.format.apply(this, format)
59+
return formatString.apply(this, format)
5960
}
6061

6162
/**
@@ -100,4 +101,31 @@ CodeBuilder.prototype.join = function () {
100101
return this.code.join(this.lineJoin)
101102
}
102103

104+
/**
105+
* Increase indentation level
106+
* @returns {this}
107+
*/
108+
CodeBuilder.prototype.indent = function () {
109+
this.indentLevel++
110+
return this
111+
}
112+
113+
/**
114+
* Decrease indentation level
115+
* @returns {this}
116+
*/
117+
CodeBuilder.prototype.unindent = function () {
118+
this.indentLevel--
119+
return this
120+
}
121+
122+
/**
123+
* Reset indentation level
124+
* @returns {this}
125+
*/
126+
CodeBuilder.prototype.reindent = function () {
127+
this.indentLevel = 0
128+
return this
129+
}
130+
103131
module.exports = CodeBuilder

src/helpers/format.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
const util = require('util')
2+
3+
function quote (value) {
4+
if (typeof value !== 'string') value = JSON.stringify(value)
5+
return JSON.stringify(value)
6+
}
7+
8+
function escape (value) {
9+
const q = quote(value)
10+
return q && q.slice(1, -1)
11+
}
12+
13+
/**
14+
* Wraps the `util.format` function and adds the %q and %v format options,
15+
* where `%q` - escape tricky characters, like newline or quotes
16+
* and `%v` - JSON-stringify-if-necessary
17+
*
18+
* @param {string} value
19+
* @param {...string} format
20+
*
21+
* @example
22+
* format('foo("%q")', { bar: 'baz' })
23+
* // output: foo("{\"bar\":\"baz\"}")
24+
*
25+
* format('foo(%v)', { bar: 'baz' })
26+
* // output: foo({"bar":"baz"})
27+
*
28+
* @returns {string} Formatted string
29+
*/
30+
function format (value, ...format) {
31+
if (typeof value !== 'string') return ''
32+
33+
let i = 0
34+
value = value.replace(/(?<!%)%[sdifjoOcqv]/g, (m) => {
35+
// JSON-stringify
36+
if (m === '%v') {
37+
const [elem] = format.splice(i, 1)
38+
return JSON.stringify(elem)
39+
}
40+
// JSON-stringify, remove quotes (means, escape)
41+
if (m === '%q') {
42+
const [elem] = format.splice(i, 1)
43+
return escape(elem)
44+
}
45+
i += 1
46+
return m
47+
})
48+
49+
const ret = util.format(value, ...format)
50+
return ret
51+
}
52+
53+
module.exports = format

0 commit comments

Comments
 (0)