Class: TidyJson::Formatter Private
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
A purpose-built JSON formatter.
Instance Attribute Summary collapse
-
#format ⇒ Hash
readonly
private
The JSON format options specified by this
Formatter
instance.
Instance Method Summary collapse
-
#format_node(node, obj) ⇒ String
private
Returns the given
node
as pretty-printed JSON. -
#initialize(opts = {}) ⇒ Formatter
constructor
private
Returns a new instance of
Formatter
. -
#node_to_str(node, tabs = 0) ⇒ String
private
Returns a JSON-appropriate string representation of
node
. -
#trim(node) ⇒ String
private
Removes any trailing comma from serialized object members.
Constructor Details
#initialize(opts = {}) ⇒ Formatter
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Formatter
.
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 |
# File 'lib/tidy_json/formatter.rb', line 40 def initialize(opts = {}) # The number of times to reduce the left indent of a nested array's # opening bracket @left_bracket_offset = 0 # True if printing a nested array @need_offset = false valid_indent = (2..12).step(2).include?(opts[:indent]) valid_space_before = (1..8).include?(opts[:space_before]) valid_space_after = (1..8).include?(opts[:space]) # don't test for the more explicit :integer? method because it's defined # for floating point numbers also valid_depth = opts[:max_nesting] >= 0 \ if opts[:max_nesting].respond_to?(:times) valid_newline = ->(str) { str.respond_to?(:strip) && str.strip.empty? } @format = { indent: "\s" * (valid_indent ? opts[:indent] : 2), space_before: "\s" * (valid_space_before ? opts[:space_before] : 0), space: "\s" * (valid_space_after ? opts[:space] : 1), object_nl: (valid_newline.call(opts[:object_nl]) ? opts[:object_nl] : "\n"), array_nl: (valid_newline.call(opts[:array_nl]) ? opts[:array_nl] : "\n"), max_nesting: valid_depth ? opts[:max_nesting] : 100, escape_slash: opts[:escape_slash] || false, ascii_only: opts[:ascii_only] || false, allow_nan: opts[:allow_nan] || false, sorted: opts[:sort] || false } end |
Instance Attribute Details
#format ⇒ Hash (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the JSON format options specified by this Formatter
instance.
11 12 13 |
# File 'lib/tidy_json/formatter.rb', line 11 def format @format end |
Instance Method Details
#format_node(node, obj) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the given node
as pretty-printed JSON.
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/tidy_json/formatter.rb', line 78 def format_node(node, obj) str = '' indent = @format[:indent] is_last = (obj.length <= 1) || (obj.instance_of?(Array) && (obj.size.pred == obj.rindex(node))) if node.instance_of?(Array) str << '[' str << "\n" unless node.empty? # format array elements node.each do |elem| if elem.instance_of?(Hash) str << "#{indent * 2}{" str << "\n" unless elem.empty? elem.each_with_index do |inner_h, h_idx| str << "#{indent * 3}\"#{inner_h.first}\": " str << node_to_str(inner_h.last, 4) str << ',' unless h_idx == elem.to_a.length.pred str << "\n" end str << (indent * 2).to_s unless elem.empty? str << '}' # element a scalar, or a nested array else is_nested_array = elem.instance_of?(Array) && elem.any? { |e| e.instance_of?(Array) } if is_nested_array @left_bracket_offset = \ elem.take_while { |e| e.instance_of?(Array) }.size end str << (indent * 2) << node_to_str(elem) end str << ",\n" unless node.index(elem) == node.length.pred end str << "\n#{indent}" unless node.empty? str << ']' str << ",\n" unless is_last elsif node.instance_of?(Hash) str << '{' str << "\n" unless node.empty? # format elements as key-value pairs node.each_with_index do |h, idx| # format values which are hashes themselves if h.last.instance_of?(Hash) key = "#{indent * 2}\"#{h.first || "<##{h.last.class.name.downcase}>"}\": " str << key << '{' str << "\n" unless h.last.empty? h.last.each_with_index do |inner_h, inner_h_idx| str << "#{indent * 3}\"#{inner_h.first}\": " str << node_to_str(inner_h.last, 4) str << ",\n" unless inner_h_idx == h.last.to_a.length.pred end str << "\n#{indent * 2}" unless h.last.empty? str << '}' # format scalar values else str << "#{indent * 2}\"#{h.first}\": " << node_to_str(h.last) end str << ",\n" unless idx == node.to_a.length.pred end str << "\n#{indent}" unless node.empty? str << '}' str << ',' unless is_last str << "\n" # scalars else str << node_to_str(node) str << ',' unless is_last str << "\n" end trim str.gsub(/(#{indent})+[\n\r]+/, '') .gsub(/\},+/, '},') .gsub(/\],+/, '],') end |
#node_to_str(node, tabs = 0) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a JSON-appropriate string representation of node
.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/tidy_json/formatter.rb', line 178 def node_to_str(node, tabs = 0) graft = '' tabs += 2 if tabs.zero? if @need_offset tabs -= 1 @left_bracket_offset -= 1 end indent = @format[:indent] * (tabs / 2) if node.nil? then graft << 'null' elsif node.instance_of?(Hash) format_node(node, node).scan(/.*$/) do |n| graft << "\n" << indent << n end elsif node.instance_of?(Array) @need_offset = @left_bracket_offset.positive? format_node(node, {}).scan(/.*$/) do |n| graft << "\n" << indent << n end elsif !node.instance_of?(String) then graft << node.to_s else graft << "\"#{node.gsub('"', '\\"')}\"" end graft.strip end |
#trim(node) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Removes any trailing comma from serialized object members.
218 219 220 221 222 223 224 225 226 |
# File 'lib/tidy_json/formatter.rb', line 218 def trim(node) if (extra_comma = /(?<trail>,\s*[\]}]\s*)$/.match(node)) node.sub(extra_comma[:trail], extra_comma[:trail] .slice(1, node.length.pred) .sub(/^\s/, "\n")) else node end end |