Phrogz / NeatJSON

Pretty-print your JSON in Ruby, JS, or Lua with more power than JSON.stringify or JSON.pretty_generate
http://phrogz.net/JS/NeatJSON
MIT License
108 stars 19 forks source link
javascript json lua ruby

NeatJSON

Gem Version

Pretty-print your JSON in Ruby or JavaScript or Lua with more power than is provided by JSON.pretty_generate (Ruby) or JSON.stringify (JS). For example, like Ruby's pp (pretty print), NeatJSON can keep objects on one line if they fit, but break them over multiple lines if needed.

Features:

Table of Contents

Installation

Usage

Ruby:

require 'neatjson'
json = JSON.neat_generate( value, options )

JavaScript (web):

<script type="text/javascript" src="https://github.com/Phrogz/NeatJSON/raw/master/neatjson.js"></script>
<script type="text/javascript">
    var json = neatJSON( value, options );
</script>

Node.js:

const { neatJSON } = require('neatjson');
var json = neatJSON( value, options );

Lua:

local neatJSON = require'neatjson'
local json = neatJSON(value, options)

Examples

The following are all in Ruby, but similar options apply in JavaScript and Lua.

require 'neatjson'

o = { b:42.005, a:[42,17], longer:true, str:"yes\nplease" }

puts JSON.neat_generate(o)
#=> {"b":42.005,"a":[42,17],"longer":true,"str":"yes\nplease"}

puts JSON.neat_generate(o, sort:true)
#=> {"a":[42,17],"b":42.005,"longer":true,"str":"yes\nplease"}

puts JSON.neat_generate(o,sort:true,padding:1,after_comma:1)
#=> { "a":[ 42, 17 ], "b":42.005, "longer":true, "str":"yes\nplease" }

puts JSON.neat_generate(o, sort:true, wrap:40)
#=> {
#=>   "a":[42,17],
#=>   "b":42.005,
#=>   "longer":true,
#=>   "str":"yes\nplease"
#=> }

puts JSON.neat_generate(o, sort:true, wrap:40, decimals:2)
#=> {
#=>   "a":[42,17],
#=>   "b":42.01,
#=>   "longer":true,
#=>   "str":"yes\nplease"
#=> }

puts JSON.neat_generate(o, sort:->(k){ k.length }, wrap:40, aligned:true)
#=> {
#=>   "a"     :[42,17],
#=>   "b"     :42.005,
#=>   "str"   :"yes\nplease",
#=>   "longer":true
#=> }

puts JSON.neat_generate(o, sort:true, wrap:40, aligned:true, around_colon:1)
#=> {
#=>   "a"      : [42,17],
#=>   "b"      : 42.005,
#=>   "longer" : true,
#=>   "str"    : "yes\nplease"
#=> }

puts JSON.neat_generate(o, sort:true, wrap:40, aligned:true, around_colon:1, short:true)
#=> {"a"      : [42,17],
#=>  "b"      : 42.005,
#=>  "longer" : true,
#=>  "str"    : "yes\nplease"}

a = [1,2,[3,4,[5]]]
puts JSON.neat_generate(a)
#=> [1,2,[3,4,[5]]]

puts JSON.pretty_generate(a) # oof!
#=> [
#=>   1,
#=>   2,
#=>   [
#=>     3,
#=>     4,
#=>     [
#=>       5
#=>     ]
#=>   ]
#=> ]

puts JSON.neat_generate( a, wrap:true, short:true )
#=> [1,
#=>  2,
#=>  [3,
#=>   4,
#=>   [5]]]

data = ["foo","bar",{dogs:42,piggies:{color:'pink', tasty:true},
        barn:{jimmy:[1,2,3,4,5],jammy:3.141592653,hot:"pajammy"},cats:7}]

opts = { short:true, wrap:60, decimals:3, sort:true, aligned:true,
         padding:1, after_comma:1, around_colon_n:1 }

puts JSON.neat_generate( data, opts )
#=> [ "foo",
#=>   "bar",
#=>   { "barn"    : { "hot"   : "pajammy",
#=>                   "jammy" : 3.142,
#=>                   "jimmy" : [ 1, 2, 3, 4, 5 ] },
#=>     "cats"    : 7,
#=>     "dogs"    : 42,
#=>     "piggies" : { "color":"pink", "tasty":true } } ]

Options

You may pass any of the following options to neat_generate (Ruby) or neatJSON (JavaScript/Lua).

Note: camelCase option names below use snake_case in Ruby. For example:

// JavaScript
var json = neatJSON( myValue, { arrayPadding:1, afterComma:1, beforeColonN:2 } );
-- Lua
local json = neatJSON( myValue, { arrayPadding=1, afterComma=1, beforeColonN=2 } )
# Ruby
json = JSON.neat_generate my_value, array_padding:1, after_comma:1, before_colon_n:2

You may omit the 'value' and/or 'object' parameters in your sort lambda if desired. For example:

# Ruby sorting examples
obj = {e:3, a:2, c:3, b:2, d:1, f:3}

JSON.neat_generate obj, sort:true                              # sort by key name
#=> {"a":2,"b":2,"c":3,"d":1,"e":3,"f":3}

JSON.neat_generate obj, sort:->(k){ k }                        # sort by key name (long way)
#=> {"a":2,"b":2,"c":3,"d":1,"e":3,"f":3}

JSON.neat_generate obj, sort:->(k,v){ [-v,k] }                 # sort by descending value, then by ascending key
#=> {"c":3,"e":3,"f":3,"a":2,"b":2,"d":1}

JSON.neat_generate obj, sort:->(k,v,h){ h.values.count(v) }    # sort by count of keys with same value
#=> {"d":1,"a":2,"b":2,"e":3,"c":3,"f":3}
// JavaScript sorting examples
var obj = {e:3, a:2, c:3, b:2, d:1, f:3};

neatJSON( obj, {sort:true} );                                              // sort by key name
// {"a":2,"b":2,"c":3,"d":1,"e":3,"f":3}

neatJSON( obj, { sort:function(k){ return k }} );                          // sort by key name (long way)
// {"a":2,"b":2,"c":3,"d":1,"e":3,"f":3}

neatJSON( obj, { sort:function(k,v){ return -v }} );                       // sort by descending value
// {"e":3,"c":3,"f":3,"a":2,"b":2,"d":1}

var countByValue = {};
for (var k in obj) countByValue[obj[k]] = (countByValue[obj[k]]||0) + 1;
neatJSON( obj, { sort:function(k,v){ return countByValue[v] } } );         // sort by count of same value
// {"d":1,"a":2,"b":2,"e":3,"c":3,"f":3}

Note that the JavaScript and Lua versions of NeatJSON do not provide a mechanism for cascading sort in the same manner as Ruby.

License & Contact

NeatJSON is copyright ©2015–2023 by Gavin Kistner and is released under the MIT License. See the LICENSE.txt file for more details.

For bugs or feature requests please open issues on GitHub. For other communication you can email the author directly.

TODO (aka Known Limitations)

History