Module: JSON

Defined in:
lib/neatjson.rb

Class Method Summary collapse

Class Method Details

.neat_generate(object, opts = {}) ⇒ String

Returns the JSON representation of the object.

Returns:

  • (String)

    the JSON representation of the object.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/neatjson.rb', line 25

def self.neat_generate(object,opts={})
	opts[:wrap] = 80 unless opts.key?(:wrap)
	opts[:wrap] = -1 if opts[:wrap]==true
	opts[:indent]         ||= "  "
	opts[:array_padding]  ||= opts[:padding]      || 0
	opts[:object_padding] ||= opts[:padding]      || 0
	opts[:after_comma]    ||= opts[:around_comma] || 0
	opts[:before_comma]   ||= opts[:around_comma] || 0
	opts[:before_colon]   ||= opts[:around_colon] || 0
	opts[:after_colon]    ||= opts[:around_colon] || 0
	raise ":indent option must only be whitespace" if opts[:indent]=~/\S/

	apad  = " " * opts[:array_padding]
	opad  = " " * opts[:object_padding]
	comma = "#{' '*opts[:before_comma]},#{' '*opts[:after_comma]}"
	colon = "#{' '*opts[:before_colon]}:#{' '*opts[:after_colon]}"

	build = ->(o,indent) do
		case o
			when String               then "#{indent}#{o.inspect}"
			when Symbol               then "#{indent}#{o.to_s.inspect}"
			when TrueClass,FalseClass then "#{indent}#{o}"
			when NilClass             then "#{indent}null"
			when Numeric
				if opts[:decimals]
					"#{indent}%.#{opts[:decimals]}f" % o
				else
					"#{indent}#{o}"
				end

			when Array
				pieces = o.map{ |v| build[v,''] }
				one_line = "#{indent}[#{apad}#{pieces.join comma}#{apad}]"
				if !opts[:wrap] || (one_line.length <= opts[:wrap])
					one_line
				elsif opts[:short]
					pieces = o.map{ |v| build[ v,"#{indent} #{apad}" ] }
					pieces[0].sub! /^#{indent} #{apad}/, "#{indent}[#{apad}"
					pieces.last << apad << "]"
					pieces.join ",\n"
				else
					indent2 = "#{indent}#{opts[:indent]}"
					"#{indent}[\n#{o.map{ |x| build[ x, indent2 ] }.join ",\n"}\n#{indent}]"
				end

			when Hash
				keyvals = o.map{ |k,v| [ k.to_s.inspect, build[v,''] ] }
				keyvals = keyvals.sort_by(&:first) if opts[:sorted]
				keyvals = keyvals.map{ |a,b| [a,b].join(colon) }.join(comma)
				one_line = "#{indent}{#{opad}#{keyvals}#{opad}}"
				if !opts[:wrap] || (one_line.length <= opts[:wrap])
					one_line
				else
					if opts[:short]
						keyvals = o.map{ |k,v| ["#{indent} #{opad}#{k.to_s.inspect}",v] }
						keyvals = keyvals.sort_by(&:first) if opts[:sorted]
						keyvals[0][0].sub! "#{indent} ", "#{indent}{"
						if opts[:aligned]
							longest = keyvals.map(&:first).map(&:length).max
							keyvals.each{ |k,v| k.replace( "%-#{longest}s" % k ) }
						end
						keyvals.map! do |k,v|
							indent2 = " "*"#{k}#{colon}".length
							one_line = "#{k}#{colon}#{build[v,'']}"
							if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash))
								"#{k}#{colon}#{build[v,indent2].lstrip}"
							else
								one_line
							end
						end
						keyvals.last << opad << "}"
						keyvals.join ",\n"
					else
						keyvals = o.map{ |k,v| ["#{indent}#{opts[:indent]}#{k.to_s.inspect}",v] }
						keyvals = keyvals.sort_by(&:first) if opts[:sorted]
						if opts[:aligned]
							longest = keyvals.map(&:first).map(&:length).max
							keyvals.each{ |k,v| k.replace( "%-#{longest}s" % k ) }
						end
						indent2 = "#{indent}#{opts[:indent]}"
						keyvals.map! do |k,v|
							one_line = "#{k}#{colon}#{build[v,'']}"
							if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash))
								"#{k}#{colon}#{build[v,indent2].lstrip}"
							else
								one_line
							end
						end
						"#{indent}{\n#{keyvals.join(",\n")}\n#{indent}}"
					end
				end

			else
				"#{indent}#{o.to_json(opts)}"
		end
	end

	build[object,'']
end