awesome_print 0.4.0 → 1.0.0
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.
- data/.gitignore +22 -0
- data/CHANGELOG +8 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +26 -0
- data/README.md +52 -14
- data/Rakefile +2 -46
- data/lib/ap.rb +3 -17
- data/lib/awesome_print.rb +16 -12
- data/lib/{ap → awesome_print}/core_ext/array.rb +0 -0
- data/lib/{ap → awesome_print}/core_ext/class.rb +0 -0
- data/lib/{ap → awesome_print}/core_ext/kernel.rb +2 -2
- data/lib/awesome_print/core_ext/logger.rb +20 -0
- data/lib/{ap → awesome_print}/core_ext/method.rb +0 -0
- data/lib/{ap → awesome_print}/core_ext/object.rb +0 -0
- data/lib/{ap → awesome_print}/core_ext/string.rb +8 -5
- data/lib/awesome_print/ext/action_view.rb +18 -0
- data/lib/awesome_print/ext/active_record.rb +40 -0
- data/lib/awesome_print/ext/active_support.rb +40 -0
- data/lib/awesome_print/ext/mongo_mapper.rb +38 -0
- data/lib/awesome_print/ext/mongoid.rb +39 -0
- data/lib/awesome_print/ext/nokogiri.rb +45 -0
- data/lib/awesome_print/formatter.rb +350 -0
- data/lib/awesome_print/inspector.rb +140 -0
- data/{rails/init.rb → lib/awesome_print/version.rb} +5 -4
- data/spec/colors_spec.rb +106 -0
- data/spec/{awesome_print_spec.rb → formats_spec.rb} +187 -37
- data/spec/methods_spec.rb +20 -0
- data/spec/objects_spec.rb +79 -0
- data/spec/spec_helper.rb +1 -1
- metadata +49 -53
- data/VERSION +0 -1
- data/init.rb +0 -1
- data/lib/ap/awesome_print.rb +0 -352
- data/lib/ap/core_ext/logger.rb +0 -18
- data/lib/ap/mixin/action_view.rb +0 -17
- data/lib/ap/mixin/active_record.rb +0 -54
- data/lib/ap/mixin/active_support.rb +0 -46
- data/lib/ap/mixin/mongo_mapper.rb +0 -54
- data/spec/action_view_spec.rb +0 -25
- data/spec/active_record_spec.rb +0 -136
- data/spec/colorization_spec.rb +0 -84
- data/spec/logger_spec.rb +0 -43
- data/spec/mongo_mapper_spec.rb +0 -63
- data/spec/string_spec.rb +0 -20
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module MongoMapper
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.send :alias_method, :cast_without_mongo_mapper, :cast
|
11
|
+
base.send :alias_method, :cast, :cast_with_mongo_mapper
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add MongoMapper class names to the dispatcher pipeline.
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
def cast_with_mongo_mapper(object, type)
|
17
|
+
cast = cast_without_mongo_mapper(object, type)
|
18
|
+
if defined?(::MongoMapper::Document) && object.is_a?(Class) && (object.ancestors & [ ::MongoMapper::Document, ::MongoMapper::EmbeddedDocument ]).size > 0
|
19
|
+
cast = :mongo_mapper_class
|
20
|
+
end
|
21
|
+
cast
|
22
|
+
end
|
23
|
+
|
24
|
+
# Format MongoMapper class object.
|
25
|
+
#------------------------------------------------------------------------------
|
26
|
+
def awesome_mongo_mapper_class(object)
|
27
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:keys)
|
28
|
+
|
29
|
+
data = object.keys.sort.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
|
30
|
+
hash[c.first] = (c.last.type || "undefined").to_s.underscore.intern
|
31
|
+
hash
|
32
|
+
end
|
33
|
+
"class #{object} < #{object.superclass} " << awesome_hash(data)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
AwesomePrint::Formatter.send(:include, AwesomePrint::MongoMapper)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module Mongoid
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.send :alias_method, :cast_without_mongoid, :cast
|
11
|
+
base.send :alias_method, :cast, :cast_with_mongoid
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add Mongoid class names to the dispatcher pipeline.
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
def cast_with_mongoid(object, type)
|
17
|
+
cast = cast_without_mongoid(object, type)
|
18
|
+
if defined?(::Mongoid::Document) && object.is_a?(Class) && object.ancestors.include?(::Mongoid::Document)
|
19
|
+
cast = :mongoid_class
|
20
|
+
end
|
21
|
+
cast
|
22
|
+
end
|
23
|
+
|
24
|
+
# Format Mongoid class object.
|
25
|
+
#------------------------------------------------------------------------------
|
26
|
+
def awesome_mongoid_class(object)
|
27
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:fields)
|
28
|
+
|
29
|
+
data = object.fields.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
|
30
|
+
hash[c[1].name] = (c[1].type || "undefined").to_s.underscore.intern
|
31
|
+
# hash[c[1].name] = (c[1].type || "undefined").to_s.underscore.intern rescue c[1].type
|
32
|
+
hash
|
33
|
+
end
|
34
|
+
"class #{object} < #{object.superclass} " << awesome_hash(data)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
AwesomePrint::Formatter.send(:include, AwesomePrint::Mongoid)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module Nokogiri
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.send :alias_method, :cast_without_nokogiri, :cast
|
11
|
+
base.send :alias_method, :cast, :cast_with_nokogiri
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add Nokogiri XML Node and NodeSet names to the dispatcher pipeline.
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
def cast_with_nokogiri(object, type)
|
17
|
+
cast = cast_without_nokogiri(object, type)
|
18
|
+
if (defined?(::Nokogiri::XML::Node) && object.is_a?(::Nokogiri::XML::Node)) ||
|
19
|
+
(defined?(::Nokogiri::XML::NodeSet) && object.is_a?(::Nokogiri::XML::NodeSet))
|
20
|
+
cast = :nokogiri_xml_node
|
21
|
+
end
|
22
|
+
cast
|
23
|
+
end
|
24
|
+
|
25
|
+
#------------------------------------------------------------------------------
|
26
|
+
def awesome_nokogiri_xml_node(object)
|
27
|
+
if object.is_a?(::Nokogiri::XML::NodeSet) && object.empty?
|
28
|
+
return "[]"
|
29
|
+
end
|
30
|
+
xml = object.to_xml(:indent => 2)
|
31
|
+
#
|
32
|
+
# Colorize tag, id/class name, and contents.
|
33
|
+
#
|
34
|
+
xml.gsub!(/(<)(\/?[A-Za-z1-9]+)/) { |tag| "#{$1}#{colorize($2, :keyword)}" }
|
35
|
+
xml.gsub!(/(id|class)="[^"]+"/i) { |id| colorize(id, :class) }
|
36
|
+
xml.gsub!(/>([^<]+)</) do |contents|
|
37
|
+
contents = colorize($1, :trueclass) if contents && !contents.empty?
|
38
|
+
">#{contents}<"
|
39
|
+
end
|
40
|
+
xml
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
AwesomePrint::Formatter.send(:include, AwesomePrint::Nokogiri)
|
@@ -0,0 +1,350 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
require "cgi"
|
7
|
+
require "shellwords"
|
8
|
+
|
9
|
+
module AwesomePrint
|
10
|
+
class Formatter
|
11
|
+
|
12
|
+
CORE = [ :array, :hash, :class, :file, :dir, :bigdecimal, :rational, :struct, :method, :unboundmethod ]
|
13
|
+
DEFAULT_LIMIT_SIZE = 7
|
14
|
+
|
15
|
+
def initialize(inspector)
|
16
|
+
@inspector = inspector
|
17
|
+
@options = inspector.options
|
18
|
+
@indentation = @options[:indent].abs
|
19
|
+
end
|
20
|
+
|
21
|
+
# Main entry point to format an object.
|
22
|
+
#------------------------------------------------------------------------------
|
23
|
+
def format(object, type = nil)
|
24
|
+
core_class = cast(object, type)
|
25
|
+
awesome = if core_class != :self
|
26
|
+
send(:"awesome_#{core_class}", object) # Core formatters.
|
27
|
+
else
|
28
|
+
awesome_self(object, type) # Catch all that falls back on object.inspect.
|
29
|
+
end
|
30
|
+
@options[:html] ? "<pre>#{awesome}</pre>" : awesome
|
31
|
+
end
|
32
|
+
|
33
|
+
# Hook this when adding custom formatters.
|
34
|
+
#------------------------------------------------------------------------------
|
35
|
+
def cast(object, type)
|
36
|
+
CORE.grep(type)[0] || :self
|
37
|
+
end
|
38
|
+
|
39
|
+
# Pick the color and apply it to the given string as necessary.
|
40
|
+
#------------------------------------------------------------------------------
|
41
|
+
def colorize(s, type)
|
42
|
+
s = CGI.escapeHTML(s) if @options[:html]
|
43
|
+
if @options[:plain] || !@options[:color][type] || !@inspector.colorize?
|
44
|
+
s
|
45
|
+
else
|
46
|
+
s.send(@options[:color][type], @options[:html])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Catch all method to format an arbitrary object.
|
54
|
+
#------------------------------------------------------------------------------
|
55
|
+
def awesome_self(object, type)
|
56
|
+
return awesome_object(object) if object.instance_variables.any?
|
57
|
+
colorize(object.inspect.to_s, type)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Format an array.
|
61
|
+
#------------------------------------------------------------------------------
|
62
|
+
def awesome_array(a)
|
63
|
+
return "[]" if a == []
|
64
|
+
|
65
|
+
if a.instance_variable_defined?('@__awesome_methods__')
|
66
|
+
methods_array(a)
|
67
|
+
elsif @options[:multiline]
|
68
|
+
width = (a.size - 1).to_s.size
|
69
|
+
|
70
|
+
data = a.inject([]) do |arr, item|
|
71
|
+
index = indent
|
72
|
+
index << colorize("[#{arr.size.to_s.rjust(width)}] ", :array) if @options[:index]
|
73
|
+
indented do
|
74
|
+
arr << (index << @inspector.awesome(item))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
data = limited(data, width) if should_be_limited?
|
79
|
+
"[\n" << data.join(",\n") << "\n#{outdent}]"
|
80
|
+
else
|
81
|
+
"[ " << a.map{ |item| @inspector.awesome(item) }.join(", ") << " ]"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Format a hash. If @options[:indent] if negative left align hash keys.
|
86
|
+
#------------------------------------------------------------------------------
|
87
|
+
def awesome_hash(h)
|
88
|
+
return "{}" if h == {}
|
89
|
+
|
90
|
+
keys = @options[:sort_keys] ? h.keys.sort { |a, b| a.to_s <=> b.to_s } : h.keys
|
91
|
+
data = keys.map do |key|
|
92
|
+
plain_single_line do
|
93
|
+
[ @inspector.awesome(key), h[key] ]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
width = data.map { |key, | key.size }.max || 0
|
98
|
+
width += @indentation if @options[:indent] > 0
|
99
|
+
|
100
|
+
data = data.map do |key, value|
|
101
|
+
indented do
|
102
|
+
align(key, width) << colorize(" => ", :hash) << @inspector.awesome(value)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
data = limited(data, width, :hash => true) if should_be_limited?
|
107
|
+
if @options[:multiline]
|
108
|
+
"{\n" << data.join(",\n") << "\n#{outdent}}"
|
109
|
+
else
|
110
|
+
"{ #{data.join(', ')} }"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Format an object.
|
115
|
+
#------------------------------------------------------------------------------
|
116
|
+
def awesome_object(o)
|
117
|
+
vars = o.instance_variables.map do |var|
|
118
|
+
property = var[1..-1].to_sym
|
119
|
+
accessor = if o.respond_to?(:"#{property}=")
|
120
|
+
o.respond_to?(property) ? :accessor : :writer
|
121
|
+
else
|
122
|
+
o.respond_to?(property) ? :reader : nil
|
123
|
+
end
|
124
|
+
if accessor
|
125
|
+
[ "attr_#{accessor} :#{property}", var ]
|
126
|
+
else
|
127
|
+
[ var.to_s, var ]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
data = vars.sort.map do |declaration, var|
|
132
|
+
key = left_aligned do
|
133
|
+
align(declaration, declaration.size)
|
134
|
+
end
|
135
|
+
|
136
|
+
unless @options[:plain]
|
137
|
+
if key =~ /(@\w+)/
|
138
|
+
key.sub!($1, colorize($1, :variable))
|
139
|
+
else
|
140
|
+
key.sub!(/(attr_\w+)\s(\:\w+)/, "#{colorize('\\1', :keyword)} #{colorize('\\2', :method)}")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
indented do
|
144
|
+
key << colorize(" = ", :hash) + @inspector.awesome(o.instance_variable_get(var))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
if @options[:multiline]
|
148
|
+
"#<#{awesome_instance(o)}\n#{data.join(%Q/,\n/)}\n#{outdent}>"
|
149
|
+
else
|
150
|
+
"#<#{awesome_instance(o)} #{data.join(', ')}>"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Format a Struct.
|
155
|
+
#------------------------------------------------------------------------------
|
156
|
+
def awesome_struct(s)
|
157
|
+
#
|
158
|
+
# The code is slightly uglier because of Ruby 1.8.6 quirks:
|
159
|
+
# awesome_hash(Hash[s.members.zip(s.values)]) <-- ArgumentError: odd number of arguments for Hash)
|
160
|
+
# awesome_hash(Hash[*s.members.zip(s.values).flatten]) <-- s.members returns strings, not symbols.
|
161
|
+
#
|
162
|
+
hash = {}
|
163
|
+
s.each_pair { |key, value| hash[key] = value }
|
164
|
+
awesome_hash(hash)
|
165
|
+
end
|
166
|
+
|
167
|
+
# Format Class object.
|
168
|
+
#------------------------------------------------------------------------------
|
169
|
+
def awesome_class(c)
|
170
|
+
if superclass = c.superclass # <-- Assign and test if nil.
|
171
|
+
colorize("#{c.inspect} < #{superclass}", :class)
|
172
|
+
else
|
173
|
+
colorize(c.inspect, :class)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Format File object.
|
178
|
+
#------------------------------------------------------------------------------
|
179
|
+
def awesome_file(f)
|
180
|
+
ls = File.directory?(f) ? `ls -adlF #{f.path.shellescape}` : `ls -alF #{f.path.shellescape}`
|
181
|
+
colorize(ls.empty? ? f.inspect : "#{f.inspect}\n#{ls.chop}", :file)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Format Dir object.
|
185
|
+
#------------------------------------------------------------------------------
|
186
|
+
def awesome_dir(d)
|
187
|
+
ls = `ls -alF #{d.path.shellescape}`
|
188
|
+
colorize(ls.empty? ? d.inspect : "#{d.inspect}\n#{ls.chop}", :dir)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Format BigDecimal and Rational objects by convering them to Float.
|
192
|
+
#------------------------------------------------------------------------------
|
193
|
+
def awesome_bigdecimal(n)
|
194
|
+
colorize(n.to_f.inspect, :bigdecimal)
|
195
|
+
end
|
196
|
+
alias :awesome_rational :awesome_bigdecimal
|
197
|
+
|
198
|
+
# Format a method.
|
199
|
+
#------------------------------------------------------------------------------
|
200
|
+
def awesome_method(m)
|
201
|
+
name, args, owner = method_tuple(m)
|
202
|
+
"#{colorize(owner, :class)}##{colorize(name, :method)}#{colorize(args, :args)}"
|
203
|
+
end
|
204
|
+
alias :awesome_unboundmethod :awesome_method
|
205
|
+
|
206
|
+
# Format object instance.
|
207
|
+
#------------------------------------------------------------------------------
|
208
|
+
def awesome_instance(o)
|
209
|
+
"#{o.class}:0x%08x" % (o.__id__ * 2)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Format object.methods array.
|
213
|
+
#------------------------------------------------------------------------------
|
214
|
+
def methods_array(a)
|
215
|
+
object = a.instance_variable_get('@__awesome_methods__')
|
216
|
+
tuples = a.map do |name|
|
217
|
+
tuple = if object.respond_to?(name, true) # Is this a regular method?
|
218
|
+
the_method = object.method(name) rescue nil # Avoid potential ArgumentError if object#method is overridden.
|
219
|
+
if the_method && the_method.respond_to?(:arity) # Is this original object#method?
|
220
|
+
method_tuple(the_method) # Yes, we are good.
|
221
|
+
end
|
222
|
+
elsif object.respond_to?(:instance_method) # Is this an unbound method?
|
223
|
+
method_tuple(object.instance_method(name))
|
224
|
+
end
|
225
|
+
tuple || [ name.to_s, '(?)', '' ] # Return WTF default if all the above fails.
|
226
|
+
end
|
227
|
+
|
228
|
+
width = (tuples.size - 1).to_s.size
|
229
|
+
name_width = tuples.map { |item| item[0].size }.max || 0
|
230
|
+
args_width = tuples.map { |item| item[1].size }.max || 0
|
231
|
+
|
232
|
+
data = tuples.inject([]) do |arr, item|
|
233
|
+
index = indent
|
234
|
+
index << "[#{arr.size.to_s.rjust(width)}]" if @options[:index]
|
235
|
+
indented do
|
236
|
+
arr << "#{index} #{colorize(item[0].rjust(name_width), :method)}#{colorize(item[1].ljust(args_width), :args)} #{colorize(item[2], :class)}"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
"[\n" << data.join("\n") << "\n#{outdent}]"
|
241
|
+
end
|
242
|
+
|
243
|
+
# Return [ name, arguments, owner ] tuple for a given method.
|
244
|
+
#------------------------------------------------------------------------------
|
245
|
+
def method_tuple(method)
|
246
|
+
if method.respond_to?(:parameters) # Ruby 1.9.2+
|
247
|
+
# See http://ruby.runpaint.org/methods#method-objects-parameters
|
248
|
+
args = method.parameters.inject([]) do |arr, (type, name)|
|
249
|
+
name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
|
250
|
+
arr << case type
|
251
|
+
when :req then name.to_s
|
252
|
+
when :opt, :rest then "*#{name}"
|
253
|
+
when :block then "&#{name}"
|
254
|
+
else '?'
|
255
|
+
end
|
256
|
+
end
|
257
|
+
else # See http://ruby-doc.org/core/classes/Method.html#M001902
|
258
|
+
args = (1..method.arity.abs).map { |i| "arg#{i}" }
|
259
|
+
args[-1] = "*#{args[-1]}" if method.arity < 0
|
260
|
+
end
|
261
|
+
|
262
|
+
if method.to_s =~ /(Unbound)*Method: (.*?)[#\.]/
|
263
|
+
owner = "#{$2}#{$1 ? '(unbound)' : ''}".gsub('(', ' (')
|
264
|
+
end
|
265
|
+
|
266
|
+
[ method.name.to_s, "(#{args.join(', ')})", owner.to_s ]
|
267
|
+
end
|
268
|
+
|
269
|
+
# Format hash keys as plain string regardless of underlying data type.
|
270
|
+
#------------------------------------------------------------------------------
|
271
|
+
def plain_single_line
|
272
|
+
plain, multiline = @options[:plain], @options[:multiline]
|
273
|
+
@options[:plain], @options[:multiline] = true, false
|
274
|
+
yield
|
275
|
+
ensure
|
276
|
+
@options[:plain], @options[:multiline] = plain, multiline
|
277
|
+
end
|
278
|
+
|
279
|
+
# Utility methods.
|
280
|
+
#------------------------------------------------------------------------------
|
281
|
+
def align(value, width)
|
282
|
+
if @options[:multiline]
|
283
|
+
if @options[:indent] > 0
|
284
|
+
value.rjust(width)
|
285
|
+
elsif @options[:indent] == 0
|
286
|
+
indent + value.ljust(width)
|
287
|
+
else
|
288
|
+
indent[0, @indentation + @options[:indent]] + value.ljust(width)
|
289
|
+
end
|
290
|
+
else
|
291
|
+
value
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def indented
|
296
|
+
@indentation += @options[:indent].abs
|
297
|
+
yield
|
298
|
+
ensure
|
299
|
+
@indentation -= @options[:indent].abs
|
300
|
+
end
|
301
|
+
|
302
|
+
def left_aligned
|
303
|
+
current, @options[:indent] = @options[:indent], 0
|
304
|
+
yield
|
305
|
+
ensure
|
306
|
+
@options[:indent] = current
|
307
|
+
end
|
308
|
+
|
309
|
+
def indent
|
310
|
+
' ' * @indentation
|
311
|
+
end
|
312
|
+
|
313
|
+
def outdent
|
314
|
+
' ' * (@indentation - @options[:indent].abs)
|
315
|
+
end
|
316
|
+
|
317
|
+
# To support limited output.
|
318
|
+
#------------------------------------------------------------------------------
|
319
|
+
def should_be_limited?
|
320
|
+
@options[:limit] == true or (@options[:limit].is_a?(Fixnum) and @options[:limit] > 0)
|
321
|
+
end
|
322
|
+
|
323
|
+
def get_limit_size
|
324
|
+
@options[:limit] == true ? DEFAULT_LIMIT_SIZE : @options[:limit]
|
325
|
+
end
|
326
|
+
|
327
|
+
def limited(data, width, is_hash = false)
|
328
|
+
limit = get_limit_size
|
329
|
+
if data.length <= limit
|
330
|
+
data
|
331
|
+
else
|
332
|
+
# Calculate how many elements to be displayed above and below the separator.
|
333
|
+
head = limit / 2
|
334
|
+
tail = head - (limit - 1) % 2
|
335
|
+
|
336
|
+
# Add the proper elements to the temp array and format the separator.
|
337
|
+
temp = data[0, head] + [ nil ] + data[-tail, tail]
|
338
|
+
|
339
|
+
if is_hash
|
340
|
+
temp[head] = "#{indent}#{data[head].strip} .. #{data[data.length - tail - 1].strip}"
|
341
|
+
else
|
342
|
+
temp[head] = "#{indent}[#{head.to_s.rjust(width)}] .. [#{data.length - tail - 1}]"
|
343
|
+
end
|
344
|
+
|
345
|
+
temp
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
end
|
350
|
+
end
|