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.
- checksums.yaml +4 -4
- data/AUTHORS +1 -0
- data/CHANGELOG.md +51 -0
- data/COPYING +674 -0
- data/README.md +99 -0
- data/Rakefile +55 -0
- data/doc/TermUtils.html +138 -0
- data/doc/TermUtils/AP.html +394 -0
- data/doc/TermUtils/AP/Article.html +993 -0
- data/doc/TermUtils/AP/ArticleResult.html +584 -0
- data/doc/TermUtils/AP/Flag.html +756 -0
- data/doc/TermUtils/AP/NoSuchValueError.html +217 -0
- data/doc/TermUtils/AP/Parameter.html +1592 -0
- data/doc/TermUtils/AP/ParameterResult.html +980 -0
- data/doc/TermUtils/AP/ParameterWalkerHooks.html +409 -0
- data/doc/TermUtils/AP/ParseError.html +217 -0
- data/doc/TermUtils/AP/Parser.html +604 -0
- data/doc/TermUtils/AP/Result.html +837 -0
- data/doc/TermUtils/AP/Syntax.html +761 -0
- data/doc/TermUtils/AP/SyntaxError.html +217 -0
- data/doc/TermUtils/AP/Walker.html +686 -0
- data/doc/TermUtils/FF.html +128 -0
- data/doc/TermUtils/FF/Config.html +774 -0
- data/doc/TermUtils/FF/Context.html +585 -0
- data/doc/TermUtils/FF/Entry.html +626 -0
- data/doc/TermUtils/FF/Query.html +1085 -0
- data/doc/TermUtils/PropertyTreeNode.html +2113 -0
- data/doc/TermUtils/Tab.html +1486 -0
- data/doc/TermUtils/Tab/Column.html +1263 -0
- data/doc/TermUtils/Tab/Header.html +536 -0
- data/doc/TermUtils/Tab/Holder.html +1210 -0
- data/doc/TermUtils/Tab/Printer.html +967 -0
- data/doc/TermUtils/Tab/Table.html +1966 -0
- data/doc/TermUtils/Tab/TableError.html +217 -0
- data/doc/_index.html +387 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +496 -0
- data/doc/file.README.html +170 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +170 -0
- data/doc/js/app.js +314 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +1539 -0
- data/doc/top-level-namespace.html +110 -0
- data/lib/term_utils.rb +11 -0
- data/lib/term_utils/ap.rb +70 -0
- data/lib/term_utils/ap/article.rb +74 -0
- data/lib/term_utils/ap/flag.rb +65 -0
- data/lib/term_utils/ap/parameter.rb +144 -0
- data/lib/term_utils/ap/parser.rb +211 -0
- data/lib/term_utils/ap/result.rb +244 -0
- data/lib/term_utils/ap/syntax.rb +96 -0
- data/lib/term_utils/ff.rb +27 -0
- data/lib/term_utils/ff/config.rb +55 -0
- data/lib/term_utils/ff/entry.rb +45 -0
- data/lib/term_utils/ff/query.rb +145 -0
- data/lib/term_utils/property_tree_node.rb +228 -0
- data/lib/term_utils/tab.rb +338 -88
- data/term_utils.gemspec +16 -0
- metadata +69 -7
data/lib/term_utils/tab.rb
CHANGED
@@ -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
|
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
|
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 [
|
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
|
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 [
|
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.
|
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
|
84
|
-
|
85
|
-
|
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 <<
|
221
|
+
sb << ' ' * offset if offset.positive?
|
88
222
|
@columns.each do |col|
|
89
|
-
sb <<
|
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 [
|
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
|
110
|
-
|
111
|
-
|
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 <<
|
250
|
+
sb << ' ' * offset if offset.positive?
|
114
251
|
@columns.each do |col|
|
115
|
-
sb <<
|
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 [
|
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
|
128
|
-
column_separator_width = opts.fetch(:column_separator_width
|
265
|
+
offset = opts.fetch(:offset)
|
266
|
+
column_separator_width = opts.fetch(:column_separator_width)
|
129
267
|
sb = StringIO.new
|
130
|
-
sb <<
|
268
|
+
sb << ' ' * offset if offset.positive?
|
131
269
|
@columns.each do |col|
|
132
|
-
sb <<
|
133
|
-
sb <<
|
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
|
184
|
-
raise
|
185
|
-
raise
|
186
|
-
raise
|
187
|
-
raise
|
188
|
-
raise
|
189
|
-
raise
|
190
|
-
raise
|
191
|
-
|
192
|
-
|
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
|
342
|
+
# @param val [Object]
|
215
343
|
# return [String]
|
216
|
-
def render_header(
|
217
|
-
|
218
|
-
|
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
|
350
|
+
# @param val [Object]
|
223
351
|
# return [String]
|
224
|
-
def render_data(
|
225
|
-
|
226
|
-
if
|
352
|
+
def render_data(val)
|
353
|
+
src = val
|
354
|
+
if val
|
227
355
|
if @format.is_a? Proc
|
228
|
-
|
356
|
+
src = @format.call(val)
|
229
357
|
elsif @format.is_a? String
|
230
|
-
|
358
|
+
src = @format % val
|
231
359
|
end
|
232
360
|
end
|
233
|
-
|
234
|
-
align_cut
|
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
|
-
|
257
|
-
|
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
|
-
|
260
|
-
|
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
|
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
|
-
|
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
|
-
|
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.
|
284
|
-
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
|
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
|
-
|
312
|
-
#
|
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
|
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
|
-
|
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
|