xprint 0.5.2 → 0.9.1

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/version.rb +1 -1
  3. data/lib/xprint.rb +236 -31
  4. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2be8f204460b6491697acbaf5330c863f18f2e912122cc208a772a1fdfb28098
4
- data.tar.gz: 6a0c9623de984721f74f890f73a4b5039b7c75b7249c346da5fb293a52c5b72d
3
+ metadata.gz: 72c5d81ad083539ab972c38b51405d5275034ce535f4014696257dbec0d6e5ab
4
+ data.tar.gz: 950f5d948e5098902d02d25eea8a62c1ec146a0dd58bb052bed139df50d06512
5
5
  SHA512:
6
- metadata.gz: 52f41f9883f320b7b3dfd281bc37ad439cb69f8a41939a09c057f1635970f3048733b8019e4840a5c17523735caab0d8437fcfb070dd31a0c05114b50e138ace
7
- data.tar.gz: 6f7e1cb37ac8894cc2123ef9ffa1212f97b663ba3c9098605a0cc1c1c8e93bf1bd95a7b8e6a462f7dc77e8071e6b77fc100c8321ea014e035fabc6d1f403a4d7
6
+ metadata.gz: 33fb5f501119a0cb8015797c93f72516276eb332a03b9dba5f01696965a2ab2b8d06659724c8e12dcb3c9dd287df0311a6a11b48e9bef51fdf5bc329e9d114b5
7
+ data.tar.gz: 11492f4674dcd327edf54cfe909c1c830236ce798f34c830a8ac5f74b36e860ea3548d44af465a72a5ca73af90c8ff5ce3d92f8f8fc429baff92e8d0c2bafaa4
@@ -1,3 +1,3 @@
1
1
  module XPrint
2
- VERSION = '0.5.2'
2
+ VERSION = '0.9.1'
3
3
  end
@@ -1,44 +1,204 @@
1
+ require 'bigdecimal'
2
+ require 'date'
3
+ require 'yaml'
4
+
1
5
  module XPrint
2
6
  @data_classes = [
3
7
  String, Integer, Float, TrueClass, FalseClass, NilClass,
4
- Symbol
8
+ Symbol, Date, Time, DateTime, BigDecimal, Rational
5
9
  ]
6
10
  @hash_name_classes = @data_classes + [Proc]
7
- @tab = "\t"
8
- @show_indexes = true
11
+ @tab = " "
12
+ @indexes = true
9
13
  @full_proc_path = false
14
+ @braces = true
15
+ @date_format = '%F'
16
+ @time_format = '%c'
17
+ @datetime_format = '%FT%T%:z'
18
+ @color = true
19
+ @colors = {
20
+ attribute: :blue,
21
+ bigdecimal: :darkcyan,
22
+ classname: :darkgreen,
23
+ classobject: :green,
24
+ date: :red,
25
+ datetime: :purple,
26
+ false: :darkred,
27
+ float: :cyan,
28
+ index: :darkgrey,
29
+ integer: :cyan,
30
+ module: :green,
31
+ nil: :darkpurple,
32
+ proc: :darkyellow,
33
+ rational: :darkcyan,
34
+ string: :yellow,
35
+ struct: :green,
36
+ symbol: :darkblue,
37
+ time: :darkblue,
38
+ true: :darkgreen
39
+ }
40
+ @color_codes = {
41
+ black: "\e[30m",
42
+ blue: "\e[94m",
43
+ darkblue: "\e[34m",
44
+ cyan: "\e[96m",
45
+ darkcyan: "\e[36m",
46
+ green: "\e[92m",
47
+ darkgreen: "\e[32m",
48
+ grey: "\e[37m",
49
+ darkgrey: "\e[90m",
50
+ red: "\e[91m",
51
+ darkred: "\e[31m",
52
+ purple: "\e[95m",
53
+ darkpurple: "\e[35m",
54
+ yellow: "\e[93m",
55
+ darkyellow: "\e[33m",
56
+ reset: "\e[0m"
57
+ }
10
58
 
11
59
  def self.set(**kwargs)
12
- @tab = kwargs[:tab] unless kwargs[:tab].nil?
13
- @show_indexes = kwargs[:show_indexes] unless kwargs[:show_indexes].nil?
60
+ set_vars = {
61
+ tab: ->(data) { @tab = data },
62
+ indexes: ->(data) { @indexes = data },
63
+ full_proc_path: ->(data) { @full_proc_path = data },
64
+ braces: ->(data) { @braces = data },
65
+ date_format: ->(data) { @date_format = data },
66
+ time_format: ->(data) { @time_format = data },
67
+ datetime_format: ->(data) { @datetime_format = data },
68
+ color: ->(data) { @color = data }
69
+ }
70
+
71
+ kwargs.each do |keyword, arg|
72
+ if set_vars.key? keyword
73
+ set_vars[keyword].(arg)
74
+ end
75
+ end
76
+
77
+ return
78
+ end
79
+
80
+ def self.load_file(config)
81
+ config_data = YAML.load( File.read config )
82
+ config_data = self.symbolize_keys(config_data)
14
83
 
15
- unless @full_proc_path.nil?
16
- @full_proc_path = kwargs[:full_proc_path]
84
+ if config_data.key? :general
85
+ self.set **config_data[:general]
86
+ end
87
+
88
+ if config_data.key? :colors
89
+ color_data = config_data[:colors]
90
+
91
+ color_data.each do |name, color|
92
+ color_data[name] = color.to_sym
93
+ end
94
+
95
+ self.set_color_for **config_data[:colors]
96
+ end
97
+
98
+ if config_data.key? :'color codes'
99
+ self.set_color_code_for **config_data[:'color codes']
100
+ end
101
+ end
102
+
103
+ def self.load(config)
104
+ calling_file = caller_locations.first.absolute_path
105
+ base_dir = File.dirname calling_file
106
+ relative_config = File.expand_path config, base_dir
107
+
108
+ self.load_file relative_config
109
+ end
110
+
111
+ private_class_method def self.symbolize_keys(hash)
112
+ hash.inject({}) do |result, (key, value)|
113
+ new_key = key.to_sym
114
+ new_value = value.is_a?(Hash) ? symbolize_keys(value) : value
115
+
116
+ result[new_key] = new_value
117
+
118
+ result
17
119
  end
18
120
  end
19
121
 
20
- def self.tab()
21
- @tab
122
+ def self.set_color_for(**kwargs)
123
+ kwargs.each do |keyword, arg|
124
+ @colors[keyword] = arg
125
+ end
22
126
  end
23
127
 
24
- def self.show_indexes()
25
- @show_indexes
128
+ def self.set_color_code_for(**kwargs)
129
+ kwargs.each do |keyword, arg|
130
+ @color_codes[keyword] = arg
131
+ end
26
132
  end
27
133
 
28
134
  def self.xp(*args)
29
135
  args.each do |arg|
30
- puts self.xpand(arg, tab: @tab)
136
+ xpanded_text = self.xpand(arg, tab: @tab)
137
+
138
+ unless @braces
139
+ xpanded_text = self.shift_indentation_down(xpanded_text).lstrip()
140
+ end
141
+
142
+ puts xpanded_text
143
+ end
144
+ end
145
+
146
+ private_class_method def self.color_for(colorname)
147
+ @color_codes[colorname]
148
+ end
149
+
150
+ private_class_method def self.reset_color()
151
+ @color_codes[:reset]
152
+ end
153
+
154
+ private_class_method def self.colorize(text, type)
155
+ if @color
156
+ item_color = color_for @colors[type]
157
+ "#{item_color}#{text}#{reset_color}"
158
+ else
159
+ text
160
+ end
161
+ end
162
+
163
+ private_class_method def self.shift_indentation_down(text)
164
+ # Only shift if no
165
+ return text if text.match?(/^\S/)
166
+ result = ''
167
+
168
+ text.each_line do |line|
169
+ result += (
170
+ if line.start_with? @tab
171
+ line[@tab.length..-1]
172
+ else
173
+ line
174
+ end
175
+ )
31
176
  end
177
+
178
+ return result
32
179
  end
33
180
 
34
- def self.xpand(x, indent: '', tab: "\t")
181
+ def self.xpand(x, indent: '', tab: ' ')
35
182
 
36
183
  _indent = "#{tab}#{indent}"
37
-
184
+
38
185
  # X is a "primitive" kind of data that has no subitems, so
39
186
  # we can just print it.
40
- if @data_classes.include? x.class
41
- return x.inspect
187
+ if x.class == String
188
+ return colorize(x.inspect, :string)
189
+ elsif x.class == Integer
190
+ return colorize(x.inspect, :integer)
191
+ elsif x.class == Float
192
+ return colorize(x.inspect, :float)
193
+ elsif x.class == TrueClass
194
+ return colorize(x.inspect, :true)
195
+ elsif x.class == FalseClass
196
+ return colorize(x.inspect, :false)
197
+ elsif x.class == NilClass
198
+ return colorize(x.inspect, :nil)
199
+ elsif x.class == Symbol
200
+ return colorize(x.inspect, :symbol)
201
+
42
202
  # X is a Proc, print more compact version of standard Proc.inspect
43
203
  # text.
44
204
  elsif x.class == Proc
@@ -50,28 +210,40 @@ module XPrint
50
210
  source = source.split('/')[-2..-1].join('/')
51
211
  end
52
212
 
53
- return "<#{type} @ #{source} [Line #{line}]>"
213
+ return colorize("<#{type} @ #{source} [Line #{line}]>", :proc)
214
+
215
+ elsif x.class == Class
216
+ return colorize("<Class #{x}>", :classobject)
217
+
54
218
  # X is an Array, print list of all items.
55
219
  elsif x.class == Array
56
- result = "[\n"
220
+ result = "#{@braces ? '[' : ''}\n"
57
221
 
58
222
  x.each_with_index do |item, index|
59
223
  data = xpand(item, indent: _indent, tab: tab)
60
224
 
61
225
  result += "#{_indent}"
62
- result += "[#{index}] " if @show_indexes
226
+ if @indexes
227
+ adjustment = x.length.to_s.length + 3
228
+ # Account for characters used for color coding.
229
+ adjustment += 9 if @color
230
+
231
+ result += "#{colorize("[#{index}]", :index)} ".
232
+ ljust(adjustment)
233
+ end
63
234
  result += "#{data}"
64
235
 
65
236
  unless index + 1 == x.length
66
- result += ", \n"
237
+ result += "#{@braces ? ', ' : ''} \n"
67
238
  end
68
239
  end
69
240
 
70
- result += "\n#{indent}]"
241
+ result += "\n#{indent}]" if @braces
71
242
  return result
243
+
72
244
  # X is a Hash, print all keys and values.
73
245
  elsif x.class == Hash
74
- result = "{\n"
246
+ result = "#{@braces ? '{' : ''}\n"
75
247
 
76
248
  longest_key = (
77
249
  x.keys.filter do |k, v|
@@ -84,6 +256,13 @@ module XPrint
84
256
  )
85
257
 
86
258
  longest_key = 0 if longest_key.nil?
259
+
260
+ # Color codes throw the text length, so we need to add the
261
+ # length of the color code and the code to reset the color
262
+ # that wrap around the colored word.
263
+ # The color code is like "\e[99m" and the reset "\e[0m",
264
+ # so the total length to add when using color is 9.
265
+ longest_key += 9 if @color
87
266
 
88
267
  x.each_with_index do |(key, value), index|
89
268
  data_key = "#{xpand(key, indent: _indent, tab: tab)}"
@@ -101,36 +280,64 @@ module XPrint
101
280
  result += "#{_indent}#{data_key} => #{data_value}"
102
281
 
103
282
  unless index + 1 == x.length
104
- result += ", \n"
283
+ result += "#{@braces ? ', ' : ''} \n"
105
284
  end
106
285
  end
107
286
 
108
- result += "\n#{indent}}"
287
+ result += "\n#{indent}}" if @braces
109
288
 
110
289
  return result
290
+
291
+ # X is a commonly used special kind of object.
292
+ elsif x.class == DateTime
293
+ datetime = x.strftime @datetime_format
294
+ return colorize("DateTime(#{datetime})", :datetime)
295
+
296
+ elsif x.class == Date
297
+ date = x.strftime @date_format
298
+ return colorize("Date(#{date})", :date)
299
+
300
+ elsif x.class == Time
301
+ time = x.strftime @time_format
302
+ return colorize("Time(#{time})", :time)
303
+
304
+ elsif x.class == BigDecimal
305
+ return colorize("BigDecimal(#{x.to_s('f')})", :bigdecimal)
306
+
307
+ elsif x.class == Rational
308
+ return colorize("Rational(#{x})", :rational)
309
+
111
310
  # X is a Structure; essentially a special case of X being an object.
112
311
  elsif x.is_a? Struct
113
- result = "Struct #{x.class}(\n"
312
+ struct_word = colorize('Struct', :struct)
313
+ classname = colorize(x.class, :struct)
314
+ result = "#{struct_word} #{classname}#{@braces ? '(' : ''}\n"
114
315
  longest_item = x.members.map { |m| m.to_s.length }.max()
115
316
 
116
317
  x.each_pair do |name, value|
117
- attr_name = name.to_s.ljust(longest_item)
318
+ attr_name = colorize(name.to_s.ljust(longest_item), :attribute)
118
319
  attr_data = xpand(value, indent: _indent, tab: tab)
119
320
 
120
321
  result += "#{_indent}#{attr_name} = #{attr_data}\n"
121
322
  end
122
323
 
123
- result += "#{indent})"
324
+ result += "#{indent})" if @braces
124
325
 
125
326
  return result
327
+
126
328
  # X is any arbitrary object; print all instance variables.
127
329
  else
128
- result = "#{x.class}(\n"
330
+ is_module = x.class == Module
331
+ classname = is_module ? "Module #{x}" : x.class
332
+ classname = colorize(classname, is_module ? :module : :classname)
333
+ result = "#{classname}#{@braces ? '(' : ''}"
129
334
  ivars = x.instance_variables
335
+ result += "\n" if ivars.length > 0
130
336
  longest_var = ivars.map { |v| v.to_s.length }.max()
131
337
 
132
338
  ivars.each_with_index do |var, index|
133
339
  attr_name = var.to_s.ljust(longest_var)
340
+ attr_name = colorize(attr_name, :attribute)
134
341
  attr_data = xpand(
135
342
  x.instance_variable_get(var),
136
343
  indent: _indent,
@@ -140,7 +347,7 @@ module XPrint
140
347
  result += "#{_indent}#{attr_name} = #{attr_data}\n"
141
348
  end
142
349
 
143
- result += "#{indent})"
350
+ result += "#{ivars.length > 0 ? indent: ''})" if @braces
144
351
 
145
352
  return result
146
353
  end
@@ -154,5 +361,3 @@ end
154
361
  def xpand(item, tab: "\t")
155
362
  XPrint::xpand(item, tab: tab)
156
363
  end
157
-
158
- xp ->{}
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xprint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - JCabr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-20 00:00:00.000000000 Z
11
+ date: 2020-07-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Gem that allows for pretty printing data over multiple lines and with
14
- indentation, and works with objects as well as basic data types.
14
+ indentation, and works with objects as well as basic data types. Also allows color,
15
+ and loading settings via a YAML config file.
15
16
  email:
16
17
  - jcabr.dev@gmail.com
17
18
  executables: []