neatjson 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/neatjson.rb +117 -0
  3. 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: []