Skip to content

Commit

Permalink
feat: Alternatively accept number of spaces for the indent parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
prantlf committed Dec 27, 2019
1 parent 80964f7 commit 4c25739
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 32 deletions.
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ By default, `jsonlint` will either report a syntax error with details or pretty-
-E, --extensions [ext] file extensions to process for directory walk
(default: ["json","JSON"])
-i, --in-place overwrite the input files
-t, --indent [char] characters to use for indentation
(default: " ")
-t, --indent [num|char] number of spaces or specific characters
to use for indentation (default: 2)
-c, --compact compact error display
-M, --mode [mode] set other parsing flags according to a format
type (default: "json")
Expand Down Expand Up @@ -190,7 +190,7 @@ You can parse a JSON string to an array of tokens and print it back to a string
const { tokenize } = require('@prantlf/jsonlint')
const tokens = tokenize('string with JSON data', { rawTokens: true })
const { print } = require('@prantlf/jsonlint/lib/printer')
const output = print(tokens, { indent: ' ' })
const output = print(tokens, { indent: 2 })
```

The [`tokenize`](#tokenizing) method accepts options in the second optional parameter. See the [`tokenize`](#tokenizing) method above for more information.
Expand All @@ -199,7 +199,7 @@ The [`print`](#pretty-printing) method accepts an object `options` as the second

| Option | Description |
| --------------------------- | ------------------------------------------------------- |
| `indent` | whitespace characters to be used as an indentation unit |
| `indent` | count of spaces or the specific characters to be used as an indentation unit |
| `pruneComments` | will omit all tokens with comments |
| `stripObjectKeys` | will not print quotes around object keys which are JavaScript identifier names |

Expand All @@ -213,13 +213,13 @@ print(tokens, {})
// (Just introduce line breaks.)
print(tokens, { indent: '' })
// Print to multiple lines with object and array indentation. (Just like
//`JSON.stringify(json, undefined, ' ')` would do it, but retaining comments.)
print(tokens, { indent: ' ' })
//`JSON.stringify(json, undefined, 2)` would do it, but retaining comments.)
print(tokens, { indent: 2 })
// Print to multiple lines with object and array indentation, omit comments.
// (Just like `JSON.stringify(json, undefined, ' ')` would do it.)
print(tokens, { indent: ' ', pruneComments: true })
// Print to multiple lines with indentation enabled and JSON5 object keys.
print(tokens, { indent: ' ', stripObjectKeys: true })
print(tokens, { indent: '\t', stripObjectKeys: true })
```

### Tokenizing
Expand Down Expand Up @@ -305,8 +305,9 @@ ${reason}`)

Copyright (C) 2012-2019 Zachary Carter, Ferdinand Prantl

Licensed under the MIT license.
Licensed under the [MIT License].

[MIT License]: http://en.wikipedia.org/wiki/MIT_License
[pure JavaScript version]: http://prantlf.github.com/jsonlint/
[jsonlint.com]: http://jsonlint.com
[JSON]: https://tools.ietf.org/html/rfc8259
Expand Down
2 changes: 1 addition & 1 deletion lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var options = require('commander')
.option('-s, --sort-keys', 'sort object keys (not when prettifying)')
.option('-E, --extensions [ext]', 'file extensions to process for directory walk', collectExtensions, ['json', 'JSON'])
.option('-i, --in-place', 'overwrite the input files')
.option('-t, --indent [char]', 'characters to use for indentation', ' ')
.option('-t, --indent [num|char]', 'number of spaces or specific characters to use for indentation', 2)
.option('-c, --compact', 'compact error display')
.option('-M, --mode [mode]', 'set other parsing flags according to a format type', 'json')
.option('-C, --comments', 'recognize and ignore JavaScript-style comments')
Expand Down
40 changes: 21 additions & 19 deletions lib/formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,70 +20,72 @@
return new Array(count + 1).join(s)
}

function format (json, indentChars) {
function format (json, indent) {
var i = 0
var il = 0
var tab = indentChars !== undefined ? indentChars : ' '
var newJson = ''
var length = 0
var indentString = indent !== undefined
? typeof indent === 'number'
? ' '.repeat(indent) : indent : ' '
var outputString = ''
var indentLevel = 0
var inString = false
var currentChar = null
var inString
var currentChar

for (i = 0, il = json.length; i < il; i += 1) {
for (i = 0, length = json.length; i < length; i += 1) {
currentChar = json.charAt(i)
switch (currentChar) {
case '{':
case '[':
if (!inString) {
newJson += currentChar + '\n' + repeat(tab, indentLevel + 1)
outputString += currentChar + '\n' + repeat(indentString, indentLevel + 1)
indentLevel += 1
} else {
newJson += currentChar
outputString += currentChar
}
break
case '}':
case ']':
if (!inString) {
indentLevel -= 1
newJson += '\n' + repeat(tab, indentLevel) + currentChar
outputString += '\n' + repeat(indentString, indentLevel) + currentChar
} else {
newJson += currentChar
outputString += currentChar
}
break
case ',':
if (!inString) {
newJson += ',\n' + repeat(tab, indentLevel)
outputString += ',\n' + repeat(indentString, indentLevel)
} else {
newJson += currentChar
outputString += currentChar
}
break
case ':':
if (!inString) {
newJson += ': '
outputString += ': '
} else {
newJson += currentChar
outputString += currentChar
}
break
case ' ':
case '\n':
case '\t':
if (inString) {
newJson += currentChar
outputString += currentChar
}
break
case '"':
if (i > 0 && json.charAt(i - 1) !== '\\') {
inString = !inString
}
newJson += currentChar
outputString += currentChar
break
default:
newJson += currentChar
outputString += currentChar
break
}
}

return newJson
return outputString
}

exports.format = format
Expand Down
4 changes: 2 additions & 2 deletions lib/jsonlint.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ declare module '@prantlf/jsonlint/lib/validator' {

declare module '@prantlf/jsonlint/lib/printer' {
interface PrintOptions {
indent?: string
indent?: number | string
pruneComments?: boolean
stripObjectKeys?: boolean
}
Expand All @@ -100,7 +100,7 @@ declare module '@prantlf/jsonlint/lib/printer' {
* import { tokenize } from '@prantlf/jsonlint'
* import { print } from '@prantlf/jsonlint/lib/printer'
* const tokens = tokenize('string with JSON data', { rawTokens: true })
* const outputString = print(tokens, { indent: ' ' })
* const outputString = print(tokens, { indent: 2 })
* ```
*
* @param tokens - an array of JSON tokens
Expand Down
3 changes: 3 additions & 0 deletions lib/printer.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
}

var indentString = options.indent
if (typeof indentString === 'number') {
indentString = ' '.repeat(indentString)
}
// Setting the indent to an empty string enables pretty-printing too.
// It will just insert line breaks without any indentation.
var prettyPrint = indentString !== undefined
Expand Down
2 changes: 1 addition & 1 deletion test/print.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ addTest('introduce line breaks', function () {
})

addTest('apply indent', function () {
var output = print(tokens, { indent: ' ' })
var output = print(tokens, { indent: 2 })
assert.equal(output, '/* start */\n{\n "a": 1, // c\n "0b": [\n 2,\n 3\n ]\n}')
})

Expand Down
3 changes: 3 additions & 0 deletions test/typings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ addTest('print', () => {
const result = print(tokens)
assert.equal(result, '{}')
print(tokens, {})
print(tokens, { indent: 2 })
print(tokens, { indent: ' ' })
print(tokens, { pruneComments: true })
print(tokens, { stripObjectKeys: true })
assert.ok(true)
})

Expand Down
2 changes: 1 addition & 1 deletion web/jsonlint.html
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ <h2>Result</h2>
var tokens = jsonlint.tokenize(source, parserOptions)
// TODO: Support sorting tor the tokenized input too.
return jsonlintPrinter.print(tokens, {
indent: ' ',
indent: 2,
pruneComments: document.getElementById('prune-comments').checked,
stripObjectKeys: document.getElementById('strip-object-keys').checked
})
Expand Down

0 comments on commit 4c25739

Please sign in to comment.