Skip to content

Instantly share code, notes, and snippets.

@rahulsom
Last active April 5, 2018 21:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rahulsom/200a4c7c336cf895718a05e7b13916d4 to your computer and use it in GitHub Desktop.
Save rahulsom/200a4c7c336cf895718a05e7b13916d4 to your computer and use it in GitHub Desktop.
Shorter Pretty Printed JSON
.idea
out/
.idea_modules/
*.iml
@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)
}
}
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": [["compressible@2.0.10", "/Users/rahul/src/hubot-api-ai-poc"]],
"_from": "compressible@2.0.10",
"_id": "compressible@2.0.10",
"_inBundle": false,
"_integrity": "sha1-/tocf3YXkScyspv4zyYlKiC57s0=",
"_location": "/compressible",
"_phantomChildren": {},
"_requested": {"type": "version", "registry": true, "raw": "compressible@2.0.10", "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": "doug@somethingdoug.com"},
{"name": "Jonathan Ong", "email": "me@jongleberry.com", "url": "http://jongleberry.com"},
{"name": "Jeremiah Senkpiel", "email": "fishrock123@rocketmail.com", "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