neatjson 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/neatjson.rb +117 -0
- metadata +43 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eeaca511388e6d3cad43037baa89da3a8a09150e
|
4
|
+
data.tar.gz: cfe5814113721a431a545d54f72897de17a6e79c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 60071be202ba2346d54125b8e37c0f7eef1d3636f0271c822efdfb0d1dfcca94b9cde15b732087bd689caa78af018eba7c996a036e718b0a42bf69a573bc8838
|
7
|
+
data.tar.gz: 1c81000e0dd2b8d79f63eb51dba7a0ddf2356a4624768c32713abf5ede4ef6a0c879c9ddb3acd4b2fed04c3a133cbd9d59742632034d2ab69e1339e3996a3f7c
|
data/lib/neatjson.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'json'
|
2
|
+
module JSON
|
3
|
+
# Generate the JSON string representation for an object,
|
4
|
+
# with a variety of formatting options.
|
5
|
+
#
|
6
|
+
# @author Gavin Kistner <!@phrogz.net>
|
7
|
+
# @param object [Object] the object to serialize
|
8
|
+
# @param opts [Hash] the formatting options
|
9
|
+
# @option opts [Integer] :wrap (80) The maximum line width before wrapping. Use `false` to never wrap, or `true` to always wrap.
|
10
|
+
# @option opts [String] :indent (" ") Whitespace used to indent each level when wrapping (without the :short option).
|
11
|
+
# @option opts [Boolean] :short (false) Keep the output 'short' when wrapping, putting opening brackets on the same line as the first value, and closing brackets on the same line as the last item.
|
12
|
+
# @option opts [Boolean] :sorted (false) Sort the keys for objects to be in alphabetical order.
|
13
|
+
# @option opts [Boolean] :aligned (false) When wrapping objects, align the colons (only per object).
|
14
|
+
# @option opts [Integer] :decimals (null) Decimal precision to use for numbers; omit to keep numberic values precise.
|
15
|
+
# @option opts [Integer] :padding (0) Number of spaces to put inside brackets/braces for both arrays and objects.
|
16
|
+
# @option opts [Integer] :array_padding (0) Number of spaces to put inside brackets for arrays. Overrides `:padding`.
|
17
|
+
# @option opts [Integer] :object_padding (0) Number of spaces to put inside braces for objects. Overrides `:padding`.
|
18
|
+
# @option opts [Integer] :around_comma (0) Number of spaces to put before/after commas (for both arrays and objects).
|
19
|
+
# @option opts [Integer] :before_comma (0) Number of spaces to put before commas (for both arrays and objects).
|
20
|
+
# @option opts [Integer] :after_comma (0) Number of spaces to put after commas (for both arrays and objects).
|
21
|
+
# @option opts [Integer] :around_colon (0) Number of spaces to put before/after colons (for objects).
|
22
|
+
# @option opts [Integer] :before_colon (0) Number of spaces to put before colons (for objects).
|
23
|
+
# @option opts [Integer] :after_colon (0) Number of spaces to put after colons (for objects).
|
24
|
+
# @return [String] the JSON representation of the object.
|
25
|
+
def self.neat_generate(object,opts={})
|
26
|
+
opts[:wrap] = 80 unless opts.key?(:wrap)
|
27
|
+
opts[:wrap] = -1 if opts[:wrap]==true
|
28
|
+
opts[:indent] ||= " "
|
29
|
+
opts[:array_padding] ||= opts[:padding] || 0
|
30
|
+
opts[:object_padding] ||= opts[:padding] || 0
|
31
|
+
opts[:after_comma] ||= opts[:around_comma] || 0
|
32
|
+
opts[:before_comma] ||= opts[:around_comma] || 0
|
33
|
+
opts[:before_colon] ||= opts[:around_colon] || 0
|
34
|
+
opts[:after_colon] ||= opts[:around_colon] || 0
|
35
|
+
raise ":indent option must only be whitespace" if opts[:indent]=~/\S/
|
36
|
+
|
37
|
+
apad = " " * opts[:array_padding]
|
38
|
+
opad = " " * opts[:object_padding]
|
39
|
+
comma = "#{' '*opts[:before_comma]},#{' '*opts[:after_comma]}"
|
40
|
+
colon = "#{' '*opts[:before_colon]}:#{' '*opts[:after_colon]}"
|
41
|
+
|
42
|
+
build = ->(o,indent) do
|
43
|
+
case o
|
44
|
+
when String then "#{indent}#{o.inspect}"
|
45
|
+
when Symbol then "#{indent}#{o.to_s.inspect}"
|
46
|
+
when TrueClass,FalseClass then "#{indent}#{o}"
|
47
|
+
when NilClass then "#{indent}null"
|
48
|
+
when Numeric
|
49
|
+
if opts[:decimals]
|
50
|
+
"#{indent}%.#{opts[:decimals]}f" % o
|
51
|
+
else
|
52
|
+
"#{indent}#{o}"
|
53
|
+
end
|
54
|
+
|
55
|
+
when Array
|
56
|
+
pieces = o.map{ |v| build[v,''] }
|
57
|
+
one_line = "#{indent}[#{apad}#{pieces.join comma}#{apad}]"
|
58
|
+
if !opts[:wrap] || (one_line.length <= opts[:wrap])
|
59
|
+
one_line
|
60
|
+
elsif opts[:short]
|
61
|
+
pieces = o.map{ |v| build[ v,"#{indent} #{apad}" ] }
|
62
|
+
pieces[0] = build[ o.first, "#{indent}[#{apad}" ]
|
63
|
+
pieces.last << apad << "]"
|
64
|
+
pieces.join ",\n"
|
65
|
+
else
|
66
|
+
indent2 = "#{indent}#{opts[:indent]}"
|
67
|
+
"#{indent}[\n#{o.map{ |x| build[ x, indent2 ] }.join ",\n"}\n#{indent}]"
|
68
|
+
end
|
69
|
+
|
70
|
+
when Hash
|
71
|
+
keyvals = o.map{ |k,v| [ k.to_s.inspect, build[v,''] ] }
|
72
|
+
keyvals = keyvals.sort_by(&:first) if opts[:sorted]
|
73
|
+
keyvals = keyvals.map{ |a,b| [a,b].join(colon) }.join(comma)
|
74
|
+
one_line = "#{indent}{#{opad}#{keyvals}#{opad}}"
|
75
|
+
if !opts[:wrap] || (one_line.length <= opts[:wrap])
|
76
|
+
one_line
|
77
|
+
else
|
78
|
+
if opts[:short]
|
79
|
+
keyvals = o.map{ |k,v| ["#{indent} #{opad}#{k.to_s.inspect}",v] }
|
80
|
+
keyvals = keyvals.sort_by(&:first) if opts[:sorted]
|
81
|
+
keyvals[0][0].sub! "#{indent} ", "#{indent}{"
|
82
|
+
if opts[:aligned]
|
83
|
+
longest = keyvals.map(&:first).map(&:length).max
|
84
|
+
keyvals.each{ |k,v| k.replace( "%-#{longest}s" % k ) }
|
85
|
+
end
|
86
|
+
pieces = keyvals.map{ |k,v| "#{k}#{colon}#{build[v,'']}" }
|
87
|
+
pieces.last << opad << "}"
|
88
|
+
pieces.join ",\n"
|
89
|
+
else
|
90
|
+
keyvals = o.map{ |k,v| ["#{indent}#{opts[:indent]}#{k.to_s.inspect}",v] }
|
91
|
+
keyvals = keyvals.sort_by(&:first) if opts[:sorted]
|
92
|
+
if opts[:aligned]
|
93
|
+
longest = keyvals.map(&:first).map(&:length).max
|
94
|
+
keyvals.each{ |k,v| k.replace( "%-#{longest}s" % k ) }
|
95
|
+
end
|
96
|
+
indent2 = "#{indent}#{opts[:indent]}"
|
97
|
+
keyvals.map! do |k,v|
|
98
|
+
one_line = "#{k}#{colon}#{build[v,'']}"
|
99
|
+
if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash))
|
100
|
+
"#{k}#{colon}#{build[v,indent2].lstrip}"
|
101
|
+
else
|
102
|
+
one_line
|
103
|
+
end
|
104
|
+
end
|
105
|
+
"#{indent}{\n#{keyvals.join(",\n")}\n#{indent}}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
else
|
110
|
+
"#{indent}#{o.to_json(opts)}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
build[object,'']
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
metadata
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: neatjson
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gavin Kistner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email: gavin@phrogz.net
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/neatjson.rb
|
20
|
+
homepage: http://github.com/Phrogz/NeatJSON
|
21
|
+
licenses: []
|
22
|
+
metadata: {}
|
23
|
+
post_install_message:
|
24
|
+
rdoc_options: []
|
25
|
+
require_paths:
|
26
|
+
- lib
|
27
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - '>='
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '0'
|
32
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
requirements: []
|
38
|
+
rubyforge_project:
|
39
|
+
rubygems_version: 2.0.14
|
40
|
+
signing_key:
|
41
|
+
specification_version: 4
|
42
|
+
summary: Pretty, powerful JSON generation.
|
43
|
+
test_files: []
|