Method: TidyJson::Formatter#format_node

Defined in:
lib/tidy_json/formatter.rb

#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.

Parameters:

  • node (#to_s)

    A visible attribute of obj.

  • obj ({Object => #to_s}, <#to_s>)

    The enumerable object containing node.

Returns:

  • (String)

    A formatted string representation of node.



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