Last active
April 5, 2018 21:49
-
-
Save rahulsom/200a4c7c336cf895718a05e7b13916d4 to your computer and use it in GitHub Desktop.
Shorter Pretty Printed JSON
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.idea | |
out/ | |
.idea_modules/ | |
*.iml |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Grab(group = 'org.fusesource.jansi', module = 'jansi', version = '1.17') | |
import groovy.json.JsonSlurper | |
import groovy.transform.CompileStatic | |
import org.fusesource.jansi.Ansi | |
import org.fusesource.jansi.AnsiConsole | |
@CompileStatic | |
class ShortJson { | |
private static final String INDENT = ' ' | |
private static final int MAX_LINE = 200 | |
public static final String HIDE = Ansi.ansi().fg(Ansi.Color.BLACK) | |
public static final String RESET = Ansi.ansi().reset() | |
public static final LC = "${HIDE}{${RESET}" | |
public static final RC = "${HIDE}}${RESET}" | |
public static final LB = "${HIDE}[${RESET}" | |
public static final RB = "${HIDE}]${RESET}" | |
public static final COMMA = "${HIDE},${RESET}" | |
public static final LK = Ansi.ansi().fgBright(Ansi.Color.BLUE).a('"') | |
public static final QUOT = '"' | |
static String printValue(def v, int offset = 0) { | |
def sw = new StringWriter() | |
if (v instanceof String) { | |
sw.print "${INDENT * offset}\"$v\"" | |
} else if (v instanceof Number) { | |
sw.print Ansi.ansi().a(INDENT * offset).fgBright(Ansi.Color.YELLOW).a(v).reset() | |
} else if (v instanceof List) { | |
def innerList = writeList(v, offset) | |
if (pLen(trim(innerList)) < MAX_LINE - offset * INDENT.size() && !innerList.contains("{")) { | |
sw.print trim(innerList) | |
} else { | |
sw.print innerList | |
} | |
} else if (v instanceof Map) { | |
def innerMap = writeMap(v, offset) | |
if (pLen(trim(innerMap)) < MAX_LINE - offset * INDENT.size()) { | |
sw.print trim(innerMap) | |
} else { | |
sw.print innerMap | |
} | |
} else if (v instanceof Boolean) { | |
sw.print Ansi.ansi().a(INDENT * offset).fgBright(Ansi.Color.GREEN).a(v).reset() | |
} else if (v == null) { | |
sw.print Ansi.ansi().a(INDENT * offset).fgBright(Ansi.Color.RED).a(v).reset() | |
} | |
sw.toString() | |
} | |
private static int pLen(String input) { | |
plain(input).length() | |
} | |
static String plain(String input) { | |
input.replace(HIDE, ''). | |
replace(Ansi.ansi().fgBright(Ansi.Color.GREEN).toString(), ''). | |
replace(Ansi.ansi().fgBright(Ansi.Color.RED).toString(), ''). | |
replace(Ansi.ansi().fgBright(Ansi.Color.BLUE).toString(), ''). | |
replace(Ansi.ansi().fgBright(Ansi.Color.YELLOW).toString(), ''). | |
replace(RESET, '') | |
} | |
private static String writeList(List list, int offset) { | |
def sw = new StringWriter() | |
sw.println LB | |
offset++ | |
int index = 0 | |
list.each { v -> | |
if (index++) { | |
sw.println COMMA | |
} | |
sw.print printValue(v, offset) | |
} | |
offset-- | |
sw.println "" | |
sw.print "${INDENT * offset}${RB}" | |
sw.toString() | |
} | |
private static String trim(String innerList) { | |
innerList. | |
replaceAll(/\n/, ' '). | |
replaceAll(/([^ ]) +/, '$1 '). | |
replace("$LC $RC", "${HIDE}{}${RESET}"). | |
replace("$LB $RB", "${HIDE}[]${RESET}"). | |
replace("$LB $LB", "${HIDE}[[${RESET}"). | |
replace("$RB $RB", "${HIDE}]]${RESET}"). | |
replace("$LB $LC", "${HIDE}[{${RESET}"). | |
replace("$RC $RB", "${HIDE}}]${RESET}"). | |
replace("$QUOT $RC", "$QUOT$RC"). | |
replace("$LC $LK", "${LC}$LK"). | |
replace("$LC $QUOT", "${LC}$QUOT"). | |
replace("$QUOT $RB", "$QUOT$RB"). | |
replace("$LB $LK", "${LB}$LK"). | |
replace("$LB $QUOT", "${LB}$QUOT"). | |
replace("$RC $RC", "${HIDE}}}${RESET}"). | |
replace("$RB $RC", "${HIDE}]}${RESET}") | |
} | |
private static String writeMap(Map<String, Object> map, int offset) { | |
def sw = new StringWriter() | |
sw.println "${INDENT * offset}$LC" | |
offset += 1 | |
int index = 0 | |
map.each { k, v -> | |
if (index++) { | |
sw.println COMMA | |
} | |
sw.print Ansi.ansi().a(INDENT * offset).fgBright(Ansi.Color.BLUE).a('"').a(k).a('": ').reset() | |
sw.print printValue(v, offset).replaceFirst(/^ +/, '') | |
} | |
offset -= 1 | |
sw.println "" | |
sw.print "${INDENT * offset}$RC" | |
sw.toString() | |
} | |
static void main(String[] args) { | |
AnsiConsole.systemInstall() | |
def reader = args[0] == '-' ? System.in.newReader() : new File(args[0]).newReader() | |
def json = new JsonSlurper().parse(reader) | |
println printValue(json, 0) | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import groovy.json.JsonSlurper | |
@Grab('org.spockframework:spock-core:1.1-groovy-2.4') | |
import spock.lang.Specification | |
import static ShortJson.printValue | |
import static ShortJson.plain | |
class ShortJsonSpec extends Specification { | |
void "primitive arrays should be flattened"() { | |
expect: | |
plain(printValue([1, 2, 3])) == '[ 1, 2, 3 ]' | |
} | |
void "hash arrays should not be flattened"() { | |
expect: | |
plain(printValue([[:], [:]])) == '''\ | |
[ | |
{}, | |
{} | |
]'''.stripIndent() | |
} | |
void "simple maps should be flattened"() { | |
expect: | |
plain(printValue([first: 'Rahul', last: 'Somasunderam'])) == '{"first": "Rahul", "last": "Somasunderam"}' | |
} | |
void "complex json regression"() { | |
def str = '''\ | |
{ | |
"_args": [["[email protected]", "/Users/rahul/src/hubot-api-ai-poc"]], | |
"_from": "[email protected]", | |
"_id": "[email protected]", | |
"_inBundle": false, | |
"_integrity": "sha1-/tocf3YXkScyspv4zyYlKiC57s0=", | |
"_location": "/compressible", | |
"_phantomChildren": {}, | |
"_requested": {"type": "version", "registry": true, "raw": "[email protected]", "name": "compressible", "escapedName": "compressible", "saveSpec": null, "fetchSpec": "2.0.10"}, | |
"_requiredBy": [], | |
"_resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.10.tgz", | |
"_spec": "2.0.10", | |
"_where": "/Users/rahul/src/hubot-api-ai-poc", | |
"bugs": {"url": "https://github.com/jshttp/compressible/issues"}, | |
"contributors": [ | |
{"name": "Douglas Christopher Wilson", "email": "[email protected]"}, | |
{"name": "Jonathan Ong", "email": "[email protected]", "url": "http://jongleberry.com"}, | |
{"name": "Jeremiah Senkpiel", "email": "[email protected]", "url": "https://searchbeam.jit.su"} | |
], | |
"dependencies": {"mime-db": ">= 1.27.0 < 2"}, | |
"description": "Compressible Content-Type / mime checking", | |
"devDependencies": { | |
"eslint": "3.18.0", | |
"eslint-config-standard": "7.1.0", | |
"eslint-plugin-markdown": "1.0.0-beta.4", | |
"eslint-plugin-promise": "3.5.0", | |
"eslint-plugin-standard": "2.1.1", | |
"istanbul": "0.4.5", | |
"mocha": "~1.21.5" | |
}, | |
"engines": {"node": ">= 0.6"}, | |
"files": ["HISTORY.md", "LICENSE", "README.md", "index.js"], | |
"homepage": "https://github.com/jshttp/compressible#readme", | |
"keywords": ["compress", "gzip", "mime", "content-type"], | |
"license": "MIT", | |
"name": "compressible", | |
"repository": {"type": "git", "url": "git+https://github.com/jshttp/compressible.git"}, | |
"scripts": { | |
"lint": "eslint --plugin markdown --ext js,md .", | |
"test": "mocha --reporter spec --bail --check-leaks test/", | |
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks", | |
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot --check-leaks" | |
}, | |
"version": "2.0.10" | |
}'''.stripIndent() | |
expect: | |
plain(printValue(new JsonSlurper().parseText(str))) == str | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment