1
0
mirror of synced 2025-12-17 11:58:13 +08:00

Adding forceformat option: format invalid output just like jsonlint.com

When using jsonlint.com, even invalid JSON is pretty printed. It seemed
like a good option to have in the cli version as well. This is simply
inserting the char-by-char formatter from
https://github.com/umbrae/jsonlintdotcom and adding an option to cli.js.
This commit is contained in:
Lance Roggendorff
2012-09-12 23:11:11 -05:00
parent 1d7ed8ab13
commit 92ac817d17
2 changed files with 130 additions and 7 deletions

View File

@@ -4,6 +4,7 @@ var fs = require("fs");
var path = require("path");
var parser = require("./jsonlint").parser;
var JSV = require("JSV").JSV;
var formatter = require("./formatter.js").formatter;
var options = require("nomnom")
.script("jsonlint")
@@ -50,10 +51,16 @@ var options = require("nomnom")
help: 'which specification of JSON Schema the validation file uses'
},
quiet: {
flag: true,key: "value",
flag: true,
key: "value",
string: '-q, --quiet',
"default": false,
help: 'do not print the parsed json to STDOUT'
},
forcePrettyPrint: {
flag: true,
string: '-p, --pretty-print',
help: 'force pretty printing even if invalid'
}
}).parse();
@@ -66,8 +73,11 @@ if (options.compact) {
}
function parse (source) {
var parsed,
formatted;
try {
var parsed = options.sort ?
parsed = options.sort ?
sortObject(parser.parse(source)) :
parser.parse(source);
@@ -81,12 +91,33 @@ function parse (source) {
}
return JSON.stringify(parsed,null,options.indent);
} catch (e) {
if ( options.forcePrettyPrint ) {
/* From https://github.com/umbrae/jsonlintdotcom:
* If we failed to validate, run our manual formatter and then re-validate so that we
* can get a better line number. On a successful validate, we don't want to run our
* manual formatter because the automatic one is faster and probably more reliable.
*/
try {
formatted = formatter.formatJson(source, options.indent);
// Re-parse so exception output gets better line numbers
parsed = parser.parse(formatted);
} catch (e) {
if (! options.compact) {
console.error(e);
}
return formatted;
process.exit(1);
}
} else {
if (! options.compact) {
console.error(e);
}
process.exit(1);
}
}
}
function schemaError (str, err) {

92
lib/formatter.js Normal file
View File

@@ -0,0 +1,92 @@
#!/usr/bin/env node
/**
* Manual formatter taken straight from https://github.com/umbrae/jsonlintdotcom
**/
/*jslint white: true, devel: true, onevar: true, browser: true, undef: true, nomen: true, regexp: true, plusplus: false, bitwise: true, newcap: true, maxerr: 50, indent: 4 */
/**
* jsl.format - Provide json reformatting in a character-by-character approach, so that even invalid JSON may be reformatted (to the best of its ability).
*
**/
var formatter = (function () {
function repeat(s, count) {
return new Array(count + 1).join(s);
}
function formatJson(json, indentChars) {
var i = 0,
il = 0,
tab = (typeof indentChars !== "undefined") ? indentChars : " ",
newJson = "",
indentLevel = 0,
inString = false,
currentChar = null;
for (i = 0, il = json.length; i < il; i += 1) {
currentChar = json.charAt(i);
switch (currentChar) {
case '{':
case '[':
if (!inString) {
newJson += currentChar + "\n" + repeat(tab, indentLevel + 1);
indentLevel += 1;
} else {
newJson += currentChar;
}
break;
case '}':
case ']':
if (!inString) {
indentLevel -= 1;
newJson += "\n" + repeat(tab, indentLevel) + currentChar;
} else {
newJson += currentChar;
}
break;
case ',':
if (!inString) {
newJson += ",\n" + repeat(tab, indentLevel);
} else {
newJson += currentChar;
}
break;
case ':':
if (!inString) {
newJson += ": ";
} else {
newJson += currentChar;
}
break;
case ' ':
case "\n":
case "\t":
if (inString) {
newJson += currentChar;
}
break;
case '"':
if (i > 0 && json.charAt(i - 1) !== '\\') {
inString = !inString;
}
newJson += currentChar;
break;
default:
newJson += currentChar;
break;
}
}
return newJson;
}
return { "formatJson": formatJson };
}());
if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
exports.formatter = formatter;
}