term_utils 0.1.1 → 0.4.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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHORS +1 -0
  3. data/CHANGELOG.md +51 -0
  4. data/COPYING +674 -0
  5. data/README.md +99 -0
  6. data/Rakefile +55 -0
  7. data/doc/TermUtils.html +138 -0
  8. data/doc/TermUtils/AP.html +394 -0
  9. data/doc/TermUtils/AP/Article.html +993 -0
  10. data/doc/TermUtils/AP/ArticleResult.html +584 -0
  11. data/doc/TermUtils/AP/Flag.html +756 -0
  12. data/doc/TermUtils/AP/NoSuchValueError.html +217 -0
  13. data/doc/TermUtils/AP/Parameter.html +1592 -0
  14. data/doc/TermUtils/AP/ParameterResult.html +980 -0
  15. data/doc/TermUtils/AP/ParameterWalkerHooks.html +409 -0
  16. data/doc/TermUtils/AP/ParseError.html +217 -0
  17. data/doc/TermUtils/AP/Parser.html +604 -0
  18. data/doc/TermUtils/AP/Result.html +837 -0
  19. data/doc/TermUtils/AP/Syntax.html +761 -0
  20. data/doc/TermUtils/AP/SyntaxError.html +217 -0
  21. data/doc/TermUtils/AP/Walker.html +686 -0
  22. data/doc/TermUtils/FF.html +128 -0
  23. data/doc/TermUtils/FF/Config.html +774 -0
  24. data/doc/TermUtils/FF/Context.html +585 -0
  25. data/doc/TermUtils/FF/Entry.html +626 -0
  26. data/doc/TermUtils/FF/Query.html +1085 -0
  27. data/doc/TermUtils/PropertyTreeNode.html +2113 -0
  28. data/doc/TermUtils/Tab.html +1486 -0
  29. data/doc/TermUtils/Tab/Column.html +1263 -0
  30. data/doc/TermUtils/Tab/Header.html +536 -0
  31. data/doc/TermUtils/Tab/Holder.html +1210 -0
  32. data/doc/TermUtils/Tab/Printer.html +967 -0
  33. data/doc/TermUtils/Tab/Table.html +1966 -0
  34. data/doc/TermUtils/Tab/TableError.html +217 -0
  35. data/doc/_index.html +387 -0
  36. data/doc/class_list.html +51 -0
  37. data/doc/css/common.css +1 -0
  38. data/doc/css/full_list.css +58 -0
  39. data/doc/css/style.css +496 -0
  40. data/doc/file.README.html +170 -0
  41. data/doc/file_list.html +56 -0
  42. data/doc/frames.html +17 -0
  43. data/doc/index.html +170 -0
  44. data/doc/js/app.js +314 -0
  45. data/doc/js/full_list.js +216 -0
  46. data/doc/js/jquery.js +4 -0
  47. data/doc/method_list.html +1539 -0
  48. data/doc/top-level-namespace.html +110 -0
  49. data/lib/term_utils.rb +11 -0
  50. data/lib/term_utils/ap.rb +70 -0
  51. data/lib/term_utils/ap/article.rb +74 -0
  52. data/lib/term_utils/ap/flag.rb +65 -0
  53. data/lib/term_utils/ap/parameter.rb +144 -0
  54. data/lib/term_utils/ap/parser.rb +211 -0
  55. data/lib/term_utils/ap/result.rb +244 -0
  56. data/lib/term_utils/ap/syntax.rb +96 -0
  57. data/lib/term_utils/ff.rb +27 -0
  58. data/lib/term_utils/ff/config.rb +55 -0
  59. data/lib/term_utils/ff/entry.rb +45 -0
  60. data/lib/term_utils/ff/query.rb +145 -0
  61. data/lib/term_utils/property_tree_node.rb +228 -0
  62. data/lib/term_utils/tab.rb +338 -88
  63. data/term_utils.gemspec +16 -0
  64. metadata +69 -7
@@ -1,3 +1,7 @@
1
+ # frozen-string-literal: true
2
+
3
+ # Copyright (C) 2020 Thomas Baron
4
+ #
1
5
  # This file is part of term_utils.
2
6
  #
3
7
  # term_utils is free software: you can redistribute it and/or modify
@@ -11,93 +15,225 @@
11
15
  #
12
16
  # You should have received a copy of the GNU General Public License
13
17
  # along with term_utils. If not, see <https://www.gnu.org/licenses/>.
18
+
14
19
  module TermUtils
20
+ # The tab module provides a way to print formatted tables.
15
21
  module Tab
22
+ # Represents a table error.
23
+ class TableError < StandardError
24
+ def initialize(msg)
25
+ super
26
+ end
27
+ end
28
+
29
+ # Creates initial column properties.
30
+ # @return [Hash] `:offset`, `:column_separator_width`.
31
+ def self.init_table_props
32
+ { offset: 0, column_separator_width: 2 }
33
+ end
34
+
35
+ # Creates initial column properties.
36
+ # @return [Hash] `:width`, `:align`, `:fixed`, `:ellipsis`, `:format`.
37
+ def self.init_column_props
38
+ { width: 8, align: :left, fixed: false, ellipsis: '?', format: nil }
39
+ end
40
+
41
+ # Assigns table properties.
42
+ # @param target [Hash]
43
+ # @param source [Hash] `:offset`, `:column_separator_width`.
44
+ # @return [Hash]
45
+ def self.assign_table_props(target, source)
46
+ if (source.key? :offset) && (source[:offset].is_a? Integer) && (source[:offset] >= 0)
47
+ target[:offset] = source[:offset]
48
+ end
49
+ if (source.key? :column_separator_width) && (source[:column_separator_width].is_a? Integer) && source[:column_separator_width].positive?
50
+ target[:column_separator_width] = source[:column_separator_width]
51
+ end
52
+ target
53
+ end
54
+
55
+ # Assigns column properties.
56
+ # @param target [Hash]
57
+ # @param source [Hash] `:width`, `:align`, `:fixed`, `:ellipsis`, `:format`.
58
+ # @return [Hash]
59
+ def self.assign_column_props(target, source)
60
+ if (source.key? :width) && (source[:width].is_a? Integer) && source[:width].positive?
61
+ target[:width] = source[:width]
62
+ end
63
+ if (source.key? :align) && %i[left right].index(source[:align])
64
+ target[:align] = source[:align]
65
+ end
66
+ if (source.key? :fixed) && (!!source[:fixed] == source[:fixed])
67
+ target[:fixed] = source[:fixed]
68
+ end
69
+ if (source.key? :ellipsis) && (source[:ellipsis].is_a? String)
70
+ target[:ellipsis] = source[:ellipsis]
71
+ end
72
+ if (source.key? :format) && (source[:ellipsis].nil? || (source[:ellipsis].is_a? Proc) || (source[:ellipsis].is_a? String))
73
+ target[:format] = source[:format]
74
+ end
75
+ target
76
+ end
77
+
78
+ # Aligns and cuts a given string.
79
+ # @param src [String]
80
+ # @param align [Symbol] `:left`, `:right`.
81
+ # @param fixed [Boolean] Whether the column width is fixed.
82
+ # @param width [Integer] The column width.
83
+ # @param ellipsis [String] The ellipsis when not fixed.
84
+ # @return [String]
85
+ def self.align_cut(src, align, fixed, width, ellipsis)
86
+ if align == :left
87
+ # Align left
88
+ if fixed && (src.length > width)
89
+ if ellipsis.length >= width
90
+ ellipsis[0..(width - 1)]
91
+ else
92
+ format '%<value>s%<ellipsis>s', value: src[0..(width - (ellipsis.length + 1))], ellipsis: ellipsis
93
+ end
94
+ else
95
+ src.ljust(width)
96
+ end
97
+ elsif align == :right
98
+ # Align right
99
+ if fixed && (src.length > width)
100
+ if ellipsis.length >= width
101
+ ellipsis[0..(width - 1)]
102
+ else
103
+ format '%<ellipsis>s%<value>s', ellipsis: ellipsis, value: src[(src.length - width + ellipsis.length)..(src.length - 1)]
104
+ end
105
+ else
106
+ src.rjust(width)
107
+ end
108
+ end
109
+ end
110
+
16
111
  # Represents a table.
17
112
  class Table
18
113
  # @return [Symbol]
19
114
  attr_accessor :id
115
+ # @return [Integer]
116
+ attr_accessor :offset
117
+ # @return [Integer]
118
+ attr_accessor :column_separator_width
119
+ # @return [Hash] `:width`, `:align`, `:fixed`, `:ellipsis`, `:format`.
120
+ attr_accessor :column_defaults
20
121
  # @return [Array<Tab::Column>]
21
122
  attr_accessor :columns
123
+
22
124
  # @param opts [Hash]
23
125
  # @option opts [Symbol] :id
126
+ # @option opts [Integer] :offset
127
+ # @option opts [Hash] :column_defaults
24
128
  def initialize(opts = {})
129
+ opts = TermUtils::Tab.init_table_props.merge(opts)
25
130
  @id = opts.fetch(:id, nil)
131
+ @offset = opts.fetch(:offset)
132
+ @column_separator_width = opts.fetch(:column_separator_width)
133
+ @column_defaults = opts.key?(:column_defaults) ? opts[:column_defaults].dup : TermUtils::Tab.default_column_props
26
134
  @columns = []
27
135
  end
136
+
137
+ # Returns the properties of this one.
138
+ # @return [Hash]
139
+ def props
140
+ { offset: @offset, column_separator_width: @column_separator_width }
141
+ end
142
+
143
+ # Sets column default properties.
144
+ # @param opts [Hash]
145
+ # @option opts [Integer] :width
146
+ # @option opts [Symbol] :align
147
+ # @option opts [Boolean] :fixed
148
+ # @option opts [String] :ellipsis
149
+ # @option opts [Proc, String, nil] :format
150
+ def set_column_defaults(opts = {})
151
+ TermUtils::Tab.assign_column_props(@column_defaults, opts)
152
+ end
153
+
28
154
  # Defines a column.
29
155
  # @param id [Symbol]
30
156
  # @param opts [Hash]
31
157
  # @option opts [Integer] :width
158
+ # @option opts [Symbol] :align
159
+ # @option opts [Boolean] :fixed
160
+ # @option opts [String] :ellipsis
161
+ # @option opts [Proc, String, nil] :format
32
162
  # @return [Tab::Column]
33
163
  def define_column(id, opts = {}, &block)
34
164
  col = @columns.find { |c| c.id == id }
35
165
  if col
36
- block.call(col) if block
166
+ block&.call(col)
37
167
  col.validate
38
168
  else
39
169
  opts[:id] = id
40
170
  opts[:index] = @columns.length
41
- col = Column.new(opts)
42
- block.call(col) if block
171
+ col = Column.new(@column_defaults.merge(opts))
172
+ block&.call(col)
43
173
  col.validate
44
174
  @columns << col
45
175
  end
46
176
  col
47
177
  end
178
+
48
179
  # Finds a column.
49
180
  # @param id [Symbol]
50
181
  # @return [Tab::Column, nil]
51
182
  def find_column(id)
52
183
  @columns.find { |c| c.id == id }
53
184
  end
185
+
54
186
  # Creates a new table printer.
55
- # @param io [IO]
56
- # @param values [Array<Object>, Hash<Symbol, Object>]
187
+ # @param io [#puts]
57
188
  # @param opts [Hash]
58
189
  # @option opts [Integer] :offset
59
190
  # @option opts [Integer] :column_separator_width
60
191
  # @return [Tab::Printer]
61
192
  def printer(io, opts = {}, &block)
62
- ptr = Printer.new(self, io, opts)
63
- block.call(ptr) if block
193
+ ptr = Printer.new(self, io, props.merge(opts))
194
+ block&.call(ptr)
64
195
  ptr
65
196
  end
197
+
66
198
  # Prints a header row.
67
- # @param io [IO]
199
+ # @param io [#puts]
68
200
  # @param values [Array<Object>, Hash<Symbol, Object>]
69
201
  # @param opts [Hash]
70
202
  # @option opts [Integer] :offset
71
203
  # @option opts [Integer] :column_separator_width
72
204
  # @return [nil]
205
+ # @raise [TermUtils::Tab::TableError]
73
206
  def print_header(io, values = nil, opts = {})
74
207
  vals = values
75
208
  if values.nil?
76
- vals = @columns.map { |col| col.id.to_s }
209
+ vals = @columns.map { |col| col.header.title }
77
210
  elsif values.is_a? Hash
78
211
  vals = []
79
212
  @columns.each do |col|
80
213
  vals << values[col.id]
81
214
  end
82
215
  end
83
- raise "wrong values (not array)" unless vals.is_a? Array
84
- offset = opts.fetch(:offset, 0)
85
- column_separator_width = opts.fetch(:column_separator_width, 2)
216
+ raise TermUtils::Tab::TableError, 'wrong values (not array)' unless vals.is_a? Array
217
+
218
+ offset = opts.fetch(:offset)
219
+ column_separator_width = opts.fetch(:column_separator_width)
86
220
  sb = StringIO.new
87
- sb << " " * offset if offset > 0
221
+ sb << ' ' * offset if offset.positive?
88
222
  @columns.each do |col|
89
- sb << " " * column_separator_width if col.index > 0
223
+ sb << ' ' * column_separator_width if col.index.positive?
90
224
  sb << col.render_header(vals[col.index])
91
225
  end
92
226
  io.puts sb.string
93
227
  end
228
+
94
229
  # Prints a data row.
95
- # @param io [IO]
230
+ # @param io [#puts]
96
231
  # @param values [Array<Object>, Hash<Symbol, Object>]
97
232
  # @param opts [Hash]
98
233
  # @option opts [Integer] :offset
99
234
  # @option opts [Integer] :column_separator_width
100
235
  # @return [nil]
236
+ # @raise [TermUtils::Tab::TableError]
101
237
  def print_data(io, values, opts = {})
102
238
  vals = values
103
239
  if values.is_a? Hash
@@ -106,34 +242,37 @@ module TermUtils
106
242
  vals << values[col.id]
107
243
  end
108
244
  end
109
- raise "wrong values (not array)" unless vals.is_a? Array
110
- offset = opts.fetch(:offset, 0)
111
- column_separator_width = opts.fetch(:column_separator_width, 2)
245
+ raise TermUtils::Tab::TableError, 'wrong values (not array)' unless vals.is_a? Array
246
+
247
+ offset = opts.fetch(:offset)
248
+ column_separator_width = opts.fetch(:column_separator_width)
112
249
  sb = StringIO.new
113
- sb << " " * offset if offset > 0
250
+ sb << ' ' * offset if offset.positive?
114
251
  @columns.each do |col|
115
- sb << " " * column_separator_width if col.index > 0
252
+ sb << ' ' * column_separator_width if col.index.positive?
116
253
  sb << col.render_data(vals[col.index])
117
254
  end
118
255
  io.puts sb.string
119
256
  end
257
+
120
258
  # Prints a separator row.
121
- # @param io [IO]
259
+ # @param io [#puts]
122
260
  # @param opts [Hash]
123
261
  # @option opts [Integer] :offset
124
262
  # @option opts [Integer] :column_separator_width
125
263
  # @return [nil]
126
264
  def print_separator(io, opts = {})
127
- offset = opts.fetch(:offset, 0)
128
- column_separator_width = opts.fetch(:column_separator_width, 2)
265
+ offset = opts.fetch(:offset)
266
+ column_separator_width = opts.fetch(:column_separator_width)
129
267
  sb = StringIO.new
130
- sb << " " * offset if offset > 0
268
+ sb << ' ' * offset if offset.positive?
131
269
  @columns.each do |col|
132
- sb << " " * column_separator_width if col.index > 0
133
- sb << "-" * col.width
270
+ sb << ' ' * column_separator_width if col.index.positive?
271
+ sb << '-' * col.width
134
272
  end
135
273
  io.puts sb.string
136
274
  end
275
+
137
276
  # Returns column titles.
138
277
  # @return [Hash<Symbol, String>]
139
278
  def titles
@@ -144,6 +283,7 @@ module TermUtils
144
283
  h
145
284
  end
146
285
  end
286
+
147
287
  # Represents a table column.
148
288
  class Column
149
289
  # @return [Symbol]
@@ -160,6 +300,9 @@ module TermUtils
160
300
  attr_accessor :ellipsis
161
301
  # @return [Proc, String, nil]
162
302
  attr_accessor :format
303
+ # @return [TermUtils::Tab::Header]
304
+ attr_accessor :header
305
+
163
306
  # @param opts [Hash]
164
307
  # @option opts [Symbol] :id
165
308
  # @option opts [Integer] :index
@@ -174,64 +317,74 @@ module TermUtils
174
317
  @width = opts.fetch(:width, 8)
175
318
  @align = opts.fetch(:align, :left)
176
319
  @fixed = opts.fetch(:fixed, false)
177
- @ellipsis = opts.fetch(:ellipsis, "?")
320
+ @ellipsis = opts.fetch(:ellipsis, '?')
178
321
  @format = opts.fetch(:format, nil)
322
+ @header = TermUtils::Tab::Header.new(title: @id.to_s, align: @align)
179
323
  end
324
+
180
325
  # Validates the column represented by this one.
181
326
  # @return [nil]
327
+ # @raise [TermUtils::Tab::TableError]
182
328
  def validate
183
- raise "missing column id (nil)" if @id.nil?
184
- raise "missing column index (nil)" if @index.nil?
185
- raise "wrong column index (not integer)" unless @index.is_a? Integer
186
- raise "wrong column index (not >= 0)" if @index < 0
187
- raise "missing column width (nil)" if @width.nil?
188
- raise "wrong column width (not integer)" unless @width.is_a? Integer
189
- raise "wrong column width (not > 0)" if @width <= 0
190
- raise "wrong column align (not :left or :right)" unless %i{left right}.index @align
191
- end
192
- # Aligns and cuts a given string.
193
- # @param str [String]
194
- # @return [String]
195
- def align_cut(str)
196
- if @align == :left
197
- # Align left
198
- if @fixed and (str.length > @width)
199
- str = "#{str[0..(@width - (@ellipsis.length + 1))]}#{@ellipsis}"
200
- else
201
- str = "%-*s" % [@width, str]
202
- end
203
- else
204
- # Align right
205
- if @fixed and (str.length > @width)
206
- str = "#{@ellipsis}#{str[(str.length - @width + @ellipsis.length)..(str.length - 1)]}"
207
- else
208
- str = "%*s" % [@width, str]
209
- end
210
- end
211
- str
329
+ raise TermUtils::Tab::TableError, 'missing column id (nil)' if @id.nil?
330
+ raise TermUtils::Tab::TableError, 'missing column index (nil)' if @index.nil?
331
+ raise TermUtils::Tab::TableError, 'wrong column index (not integer)' unless @index.is_a? Integer
332
+ raise TermUtils::Tab::TableError, 'wrong column index (not >= 0)' if @index.negative?
333
+ raise TermUtils::Tab::TableError, 'missing column width (nil)' if @width.nil?
334
+ raise TermUtils::Tab::TableError, 'wrong column width (not integer)' unless @width.is_a? Integer
335
+ raise TermUtils::Tab::TableError, 'wrong column width (not > 0)' if @width <= 0
336
+ raise TermUtils::Tab::TableError, 'wrong column align (not :left or :right)' unless %i[left right].index(@align)
337
+
338
+ @header.validate
212
339
  end
340
+
213
341
  # Renders a given header.
214
- # @param v [Object]
342
+ # @param val [Object]
215
343
  # return [String]
216
- def render_header(v)
217
- str = v
218
- str = str.to_s unless str.is_a? String
219
- align_cut str
344
+ def render_header(val)
345
+ src = val.is_a?(String) ? val : val.to_s
346
+ TermUtils::Tab.align_cut(src, @header.align, @fixed, @width, @ellipsis)
220
347
  end
348
+
221
349
  # Renders a given value.
222
- # @param v [Object]
350
+ # @param val [Object]
223
351
  # return [String]
224
- def render_data(v)
225
- str = v
226
- if v
352
+ def render_data(val)
353
+ src = val
354
+ if val
227
355
  if @format.is_a? Proc
228
- str = @format.call(v)
356
+ src = @format.call(val)
229
357
  elsif @format.is_a? String
230
- str = @format % v
358
+ src = @format % val
231
359
  end
232
360
  end
233
- str = str.to_s unless str.is_a? String
234
- align_cut str
361
+ src = src.is_a?(String) ? src : src.to_s
362
+ TermUtils::Tab.align_cut(src, @align, @fixed, @width, @ellipsis)
363
+ end
364
+ end
365
+
366
+ # Represents a column header.
367
+ class Header
368
+ # @return [String]
369
+ attr_accessor :title
370
+ # @return [Symbol] `:left`, `:right`.
371
+ attr_accessor :align
372
+
373
+ # Constructs a new Header.
374
+ # @param opts [Hash]
375
+ # @option opts [String] :title
376
+ # @option opts [Symbol] :align
377
+ def initialize(opts = {})
378
+ @title = opts.fetch(:title)
379
+ @align = opts.fetch(:align, :left)
380
+ end
381
+
382
+ # Validates the column represented by this one.
383
+ # @return [nil]
384
+ # @raise [TermUtils::Tab::TableError]
385
+ def validate
386
+ raise TermUtils::Tab::TableError, 'missing header title (nil)' if @title.nil?
387
+ raise TermUtils::Tab::TableError, 'wrong header align (not :left or :right)' unless %i[left right].index(@align)
235
388
  end
236
389
  end
237
390
  # Represents a table printer.
@@ -242,6 +395,7 @@ module TermUtils
242
395
  attr_accessor :io
243
396
  # @return [Hash]
244
397
  attr_accessor :options
398
+
245
399
  # @param table [Tab::Table]
246
400
  # @param io [IO]
247
401
  # @param options [Hash]
@@ -250,56 +404,117 @@ module TermUtils
250
404
  @io = io
251
405
  @options = options
252
406
  end
407
+
408
+ # Prints an empty line.
253
409
  def line
254
- @io.puts ""
410
+ @io.puts
255
411
  end
256
- def header(values = nil, opts = {})
257
- @table.print_header(@io, values, @options.merge(opts))
412
+
413
+ # Prints a header row.
414
+ # @param values [Array<Object>, Hash<Symbol, Object>]
415
+ # @param opts [Hash]
416
+ # @option opts [Integer] :offset
417
+ # @option opts [Integer] :column_separator_width
418
+ # @return [nil]
419
+ def header(values = nil, opts = nil)
420
+ @table.print_header(@io, values, opts ? @options.merge(opts) : @options)
258
421
  end
259
- def data(values, opts = {})
260
- @table.print_data(@io, values, @options.merge(opts))
422
+
423
+ # Prints a data row.
424
+ # @param values [Array<Object>, Hash<Symbol, Object>]
425
+ # @param opts [Hash]
426
+ # @option opts [Integer] :offset
427
+ # @option opts [Integer] :column_separator_width
428
+ # @return [nil]
429
+ def data(values, opts = nil)
430
+ @table.print_data(@io, values, opts ? @options.merge(opts) : @options)
261
431
  end
432
+
262
433
  # Prints a separator.
263
434
  # @param opts [Hash]
264
435
  # @option opts [Integer] :offset
265
436
  # @option opts [Integer] :column_separator_width
266
437
  # @return [nil]
267
- def separator(opts = {})
268
- @table.print_separator(@io, @options.merge(opts))
438
+ def separator(opts = nil)
439
+ @table.print_separator(@io, opts ? @options.merge(opts) : @options)
269
440
  end
270
441
  end
271
- # Represents a holder of tables.
442
+ # Represents a Holder of Table(s).
272
443
  class Holder
444
+ # @return [Hash] `:offset`, `:column_separator_width`.
445
+ attr_accessor :table_defaults
446
+ # @return [Hash] `:width`, `:align`, `:fixed`, `:ellipsis`, `:format`.
447
+ attr_accessor :column_defaults
273
448
  # @return [Hash<Symbol, Tab::Table>]
274
449
  attr_accessor :tables
275
- def initialize(opts = {})
450
+
451
+ # Creates a new Holder.
452
+ def initialize
453
+ @table_defaults = TermUtils::Tab.init_table_props
454
+ @column_defaults = TermUtils::Tab.init_column_props
276
455
  @tables = {}
277
456
  end
278
- # Defines a table.
457
+
458
+ # Sets table default properties.
459
+ # @param opts [Hash]
460
+ # @option opts [Integer] :offset
461
+ # @option opts [Symbol] :column_separator_width
462
+ def set_table_defaults(opts = {})
463
+ TermUtils::Tab.assign_table_props(@table_defaults, opts)
464
+ end
465
+
466
+ # Sets column default properties.
467
+ # @param opts [Hash]
468
+ # @option opts [Integer] :width
469
+ # @option opts [Symbol] :align
470
+ # @option opts [Boolean] :fixed
471
+ # @option opts [String] :ellipsis
472
+ # @option opts [Proc, String, nil] :format
473
+ def set_column_defaults(opts = {})
474
+ TermUtils::Tab.assign_column_props(@column_defaults, opts)
475
+ end
476
+
477
+ # Creates a new table, using default properties, without registering it.
478
+ # @param opts [Hash]
479
+ # @return [Tab::Table]
480
+ def create_table(opts = {}, &block)
481
+ opts[:offset] = @table_defaults.fetch(:offset)
482
+ opts[:column_separator_width] = @table_defaults.fetch(:column_separator_width)
483
+ opts[:column_defaults] = @column_defaults.dup
484
+ new_tab = Table.new(opts)
485
+ block&.call(new_tab)
486
+ new_tab
487
+ end
488
+
489
+ # Defines a table, using default properties.
279
490
  # @param id [Symbol]
280
491
  # @param opts [Hash]
281
492
  # @return [Tab::Table]
282
493
  def define_table(id, opts = {}, &block)
283
- if @tables.has_key? id
284
- block.call(@tables[id]) if block
494
+ if @tables.key? id
495
+ block&.call(@tables[id])
285
496
  else
286
497
  opts[:id] = id
498
+ opts[:offset] = @table_defaults.fetch(:offset)
499
+ opts[:column_separator_width] = @table_defaults.fetch(:column_separator_width)
500
+ opts[:column_defaults] = @column_defaults.dup
287
501
  new_tab = Table.new(opts)
288
- block.call(new_tab) if block
502
+ block&.call(new_tab)
289
503
  @tables[id] = new_tab
290
504
  end
291
505
  @tables[id]
292
506
  end
507
+
293
508
  # Finds a table.
294
509
  # @param id [Symbol]
295
510
  # @return [Tab::Table, nil]
296
511
  def find_table(id)
297
512
  @tables[id]
298
513
  end
514
+
299
515
  # Creates a new table printer.
300
516
  # @param id [Symbol]
301
517
  # @param io [IO]
302
- # @param values [Array<Object>, Hash<Symbol, Object>]
303
518
  # @param opts [Hash]
304
519
  # @option opts [Integer] :offset
305
520
  # @option opts [Integer] :column_separator_width
@@ -308,18 +523,53 @@ module TermUtils
308
523
  find_table(id).printer(io, opts, &block)
309
524
  end
310
525
  end
311
- @@default_holder = Holder.new
312
- # Defines a table.
526
+
527
+ @@default_holder = Holder.new # rubocop:disable Style/ClassVars
528
+
529
+ # Sets table default properties.
530
+ # @param opts [Hash]
531
+ # @option opts [Integer] :offset
532
+ # @option opts [Symbol] :column_separator_width
533
+ def self.set_table_defaults(opts = {})
534
+ @@default_holder.set_table_defaults(opts)
535
+ end
536
+
537
+ # Sets column default properties.
538
+ # @param opts [Hash]
539
+ # @option opts [Integer] :width
540
+ # @option opts [Symbol] :align
541
+ # @option opts [Boolean] :fixed
542
+ # @option opts [String] :ellipsis
543
+ # @option opts [Proc, String, nil] :format
544
+ def self.set_column_defaults(opts = {})
545
+ @@default_holder.set_column_defaults(opts)
546
+ end
547
+
548
+ # Creates a new Table, using default properties, without registering it.
549
+ # @param opts [Hash]
550
+ # @return [Tab::Table]
551
+ def self.create_table(opts = {}, &block)
552
+ @@default_holder.create_table(opts, &block)
553
+ end
554
+
555
+ # Defines a new Table, using default properties, and registers it.
313
556
  # @param id [Symbol]
314
557
  # @param opts [Hash]
315
558
  # @return [Tab::Table]
316
559
  def self.define_table(id, opts = {}, &block)
317
- @@default_holder.define_table(id, opts = {}, &block)
560
+ @@default_holder.define_table(id, opts, &block)
561
+ end
562
+
563
+ # Finds a registered table.
564
+ # @param id [Symbol]
565
+ # @return [Tab::Table, nil]
566
+ def self.find_table(id)
567
+ @@default_holder.find_table(id)
318
568
  end
319
- # Creates a new table printer.
569
+
570
+ # Creates a new Printer for a registered Table.
320
571
  # @param id [Symbol]
321
572
  # @param io [IO]
322
- # @param values [Array<Object>, Hash<Symbol, Object>]
323
573
  # @param opts [Hash]
324
574
  # @option opts [Integer] :offset
325
575
  # @option opts [Integer] :column_separator_width