diff --git a/README.md b/README.md index 581891b..3cf0ca9 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,19 @@ It has the exact same signature of `JSON.stringify` but it also adds an optional The maximum fixed character width (for instance 80). +Alternatively, the second parameter can be an object with the `replacer` and `space` keys corresponding to the +standard `JSON.stringify` parameters and a `maxwidth` key for the maximum fixed character width. When the +second parameter is an object, space defaults to 2 space and maxwidth defaults to 80 characters. There are +also some additional keys for even finer control: + +* `sortkeys` (boolean) If true, json objects will be sorted by key, rather than printed in the order they are + stored. Defaults to false. +* `spacearrays` (string) Space to leave around single line arrays, defaults to a single space (`' '`), which + produces output like `[ 1, 2, 3 ]`. Set to an empty string and it will output `[1, 2, 3]`. +* `spaceobjects` (string) As above but for objects, not arrays, defaults to a single space (`' '`), which + produces output like `{ "foo": "bar", "bar": 42 }`. Set to an empty string and it will output + `{"foo": "bar", "bar": 42}`. + ## Examples: ```js @@ -20,6 +33,12 @@ var obj = { str: "Hello World", num: 42, smallarray: [ 1, 2, 3, "foo", {} ], sma ### With 100 fixed-spaces: +```js +console.log(beautify(obj, { maxwidth: 100})); +``` + +or: + ```js console.log(beautify(obj, null, 2, 100)); ``` @@ -37,6 +56,12 @@ console.log(beautify(obj, null, 2, 100)); ### With 80 fixed-spaces: +```js +console.log(beautify(obj, {})); +``` + +or: + ```js console.log(beautify(obj, null, 2, 80)); ``` @@ -62,3 +87,31 @@ console.log(beautify(obj, null, 2, 80)); } } ``` + +### Sorting keys + +```js +console.log(beautify(obj, { sortkeys: true })); +``` + +```json +{ + "bigarray": [ + 1, + 2, + 3, + "foo", + { "arr": [ 1, 2, 3, "foo", {} ], "bar": 42, "foo": "bar" } + ], + "bigobject": { + "a": { "b": { "c": 42 } }, + "bar": 42, + "foo": [ 1, 2, 3, "foo", {} ], + "foobar": "FooBar" + }, + "num": 42, + "smallarray": [ 1, 2, 3, "foo", {} ], + "smallobject": { "bar": 42, "foo": "bar" }, + "str": "Hello World" +} +``` diff --git a/index.js b/index.js index e7988ef..f1e3508 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,7 @@ var gap, '"': '\\"', '\\': '\\\\' }, + options, rep; function quote(string) { @@ -120,7 +121,7 @@ function str(key, holder, limit) { ? ( gap.length + partial.join(', ').length + 4 > limit ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : - '[ ' + partial.join(', ') + ' ]' + '[' + options.spacearrays + partial.join(', ') + options.spacearrays + ']' ) : '[' + partial.join(',') + ']'; gap = mind; @@ -162,6 +163,12 @@ function str(key, holder, limit) { } } +// Sort keys if applicable + + if (options.sortkeys) { + partial.sort(); + } + // Join all of the member texts together, separated with commas, // and wrap them in braces. @@ -171,7 +178,7 @@ function str(key, holder, limit) { ? ( gap.length + partial.join(', ').length + 4 > limit ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : - '{ ' + partial.join(', ') + ' }' + '{' + options.spaceobjects + partial.join(', ') + options.spaceobjects + '}' ) : '{' + partial.join(',') + '}'; gap = mind; @@ -180,7 +187,7 @@ function str(key, holder, limit) { } -function beautify (value, replacer, space, limit) { +function beautify (value, replacer, space, maxwidth) { // The stringify method takes a value and an optional replacer, and an optional // space parameter, and returns a JSON text. The replacer can be a function @@ -188,43 +195,63 @@ function beautify (value, replacer, space, limit) { // A default replacer method can be provided. Use of the space parameter can // produce text that is more easily readable. - var i; - gap = ''; - indent = ''; +// Alternatively, the method can take a value and a config object with the +// replacer, space and maxwidth parameters as keys. + + var i; + gap = ''; + indent = ''; + options = {}; + +// If second and no further parameters are supplied, and it isn't a replacer, +// it is an options object + if (replacer && !isReplacer(replacer) && !space && !maxwidth) { + options = replacer; + replacer = options.replacer; + space = options.hasOwnProperty('space') ? options.space : ' '; + maxwidth = options.maxwidth || 80; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + if (!isReplacer(replacer)) { + throw new Error('beautifier: wrong replacer parameter'); + } + rep = replacer; + + if (!maxwidth) maxwidth = 0; - if (!limit) limit = 0; + if (!options.hasOwnProperty('spacearrays')) options.spacearrays = ' '; - if (typeof limit !== "number") - throw new Error("beaufifier: limit must be a number"); + if (!options.hasOwnProperty('spaceobjects')) options.spaceobjects = ' '; + + if (typeof maxwidth !== "number") + throw new Error("beaufifier: maxwidth must be a number"); // If the space parameter is a number, make an indent string containing that // many spaces. - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } // If the space parameter is a string, it will be used as the indent string. - } else if (typeof space === 'string') { - indent = space; - } - -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. - - rep = replacer; - if (replacer && typeof replacer !== 'function' && - (typeof replacer !== 'object' || - typeof replacer.length !== 'number')) { - throw new Error('beautifier: wrong replacer parameter'); - } + } else if (typeof space === 'string') { + indent = space; + } // Make a fake root object containing our value under the key of ''. // Return the result of stringifying the value. - return str('', {'': value}, limit); + return str('', {'': value}, maxwidth); +} + +function isReplacer(replacer) { + return !(replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) } module.exports = beautify;