简体   繁体   中英

Printing printing JSON in Ruby - with line wrapping

What is the best way to pretty print JSON in Ruby with smart line wrapping , the way the "json" output formatter in underscore-cli handles it?

For instance, a regular JSON pretty printer would output:

{
  "a": [
    "b",
    "c"
  ],
  "d": {
    "e": "f"
  },
  "g": [
    "some longer string"
  ]
}

But I'm looking for a configurable pretty printer in Ruby that, like underscore-cli, notices that small structures make for pointlessly short lines, and so outputs something like this:

{
  "a": [ "b", "c" ],
  "d": { "e": "f" },
  "g": [ "some longer string" ]
}

I've played around with the options available in JSON.generate() (space, space_before, etc.), to no avail.

I'm writing a script which generates multiple JSON files intended to be reasonably comprehensible by humans (should the need arise) --- I can't expect underscore to be available everywhere so I can't (and ugh, wouldn't want to) just pipe the output through underscore, but the default JSON.pretty_generate() outputs files which are far less readable with around three times as many lines as underscore (2,200 lines vs 750).

Ruby 2.0.0p481.

If your requirements are minimal you can play around with JSON#generate opts to avoid using extra gems. Though I completely agree neatjson makes it cleaner.

A quick example:

a = {"a"=>["b", "c"], "d"=>{"e"=>"f"}, "g"=>["some longer string"]}
puts JSON.pretty_generate(a,  array_nl:'')
#{
#  "a": [    "b",    "c"  ],
#  "d": {
#    "e": "f"
#  },
#  "g": [    "some longer string"  ]
#}

As soon as you just want to do the only thing, I would go with simple gsubbing (it is safe here):

▶ #                                  ⇓ ldelim  ⇓ not nest ⇓ cnt ⇓ rdelim
▶ puts JSON.pretty_generate(a).gsub(/(?<=\[|\{)[^\[\{\]\}]{,30}(?=\]|\})/m) do |m| 
  m.gsub(/\s+/, ' ').strip
end
#⇒ {
#  "a": ["b", "c"],
#  "d": {"e": "f"},
#  "g": ["some longer string"]
# }

It is configurable for the length of allowed “inlines” (30 in the example above) and ready to print output as you want (to surround inlines with spaces, just update the return value in block, given to gsub .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM