tty-table 0.9.0 → 0.10.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/.travis.yml +4 -3
- data/CHANGELOG.md +16 -0
- data/Gemfile +4 -4
- data/README.md +3 -3
- data/appveyor.yml +2 -0
- data/benchmarks/speed.rb +3 -5
- data/examples/alignment.rb +3 -3
- data/examples/basic.rb +2 -2
- data/examples/orientation.rb +13 -0
- data/examples/padding.rb +15 -0
- data/examples/resize.rb +15 -0
- data/lib/tty/table.rb +2 -1
- data/lib/tty/table/border.rb +4 -12
- data/lib/tty/table/column_constraint.rb +15 -7
- data/lib/tty/table/columns.rb +42 -68
- data/lib/tty/table/field.rb +3 -13
- data/lib/tty/table/indentation.rb +9 -20
- data/lib/tty/table/operation/alignment.rb +2 -2
- data/lib/tty/table/operation/padding.rb +3 -3
- data/lib/tty/table/operation/truncation.rb +3 -3
- data/lib/tty/table/operation/wrapped.rb +3 -3
- data/lib/tty/table/operations.rb +3 -14
- data/lib/tty/table/renderer.rb +28 -24
- data/lib/tty/table/renderer/ascii.rb +1 -1
- data/lib/tty/table/renderer/basic.rb +42 -41
- data/lib/tty/table/renderer/unicode.rb +1 -1
- data/lib/tty/table/version.rb +1 -3
- data/spec/unit/border/ascii/rendering_spec.rb +1 -1
- data/spec/unit/border/null/rendering_spec.rb +1 -1
- data/spec/unit/border/unicode/rendering_spec.rb +1 -1
- data/spec/unit/column_constraint/enforce_spec.rb +2 -2
- data/spec/unit/columns/extract_widths_spec.rb +7 -12
- data/spec/unit/columns/total_width_spec.rb +3 -4
- data/spec/unit/indentation/indent_spec.rb +2 -6
- data/spec/unit/operations/new_spec.rb +3 -5
- data/spec/unit/renderer/ascii/padding_spec.rb +29 -0
- data/tty-table.gemspec +3 -4
- metadata +12 -24
data/lib/tty/table/field.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'equatable'
|
4
4
|
require 'pastel'
|
5
|
-
require '
|
5
|
+
require 'strings'
|
6
6
|
|
7
7
|
module TTY
|
8
8
|
class Table
|
@@ -104,7 +104,7 @@ module TTY
|
|
104
104
|
#
|
105
105
|
# @api public
|
106
106
|
def width
|
107
|
-
@width || display_width(@content)
|
107
|
+
@width || Strings::Align.display_width(@content)
|
108
108
|
end
|
109
109
|
|
110
110
|
# Return number of lines this value spans.
|
@@ -127,7 +127,7 @@ module TTY
|
|
127
127
|
# @api public
|
128
128
|
def length
|
129
129
|
(lines.map do |line|
|
130
|
-
display_width(
|
130
|
+
Strings::Align.display_width(line)
|
131
131
|
end << 0).max
|
132
132
|
end
|
133
133
|
|
@@ -152,16 +152,6 @@ module TTY
|
|
152
152
|
def to_s
|
153
153
|
content
|
154
154
|
end
|
155
|
-
|
156
|
-
# @api public
|
157
|
-
def self.color
|
158
|
-
@color ||= Pastel.new(enabled: true)
|
159
|
-
end
|
160
|
-
|
161
|
-
# @api public
|
162
|
-
def display_width(string)
|
163
|
-
Unicode::DisplayWidth.of(string)
|
164
|
-
end
|
165
155
|
end # Field
|
166
156
|
end # Table
|
167
157
|
end # TTY
|
@@ -1,36 +1,24 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module TTY
|
4
5
|
class Table
|
5
|
-
# A
|
6
|
-
|
7
|
-
# The amount of indentation
|
8
|
-
#
|
9
|
-
# @api public
|
10
|
-
attr_accessor :indentation
|
11
|
-
|
12
|
-
# Initialize an Indentation
|
13
|
-
#
|
14
|
-
# @api public
|
15
|
-
def initialize(indentation)
|
16
|
-
@indentation = indentation
|
17
|
-
end
|
18
|
-
|
6
|
+
# A module responsible for indenting table representation
|
7
|
+
module Indentation
|
19
8
|
# Return a table part with indentation inserted
|
20
9
|
#
|
21
10
|
# @param [#map, #to_s] part
|
22
11
|
# the rendered table part
|
23
12
|
#
|
24
13
|
# @api public
|
25
|
-
def indent(part)
|
14
|
+
def indent(part, indentation)
|
26
15
|
if part.respond_to?(:to_a)
|
27
|
-
part.map { |line| insert_indentation(line) }
|
16
|
+
part.map { |line| insert_indentation(line, indentation) }
|
28
17
|
else
|
29
|
-
insert_indentation(part)
|
18
|
+
insert_indentation(part, indentation)
|
30
19
|
end
|
31
20
|
end
|
32
|
-
|
33
|
-
private
|
21
|
+
module_function :indent
|
34
22
|
|
35
23
|
# Insert indentation into a table renderd line
|
36
24
|
#
|
@@ -38,10 +26,11 @@ module TTY
|
|
38
26
|
# the rendered table line
|
39
27
|
#
|
40
28
|
# @api public
|
41
|
-
def insert_indentation(line)
|
29
|
+
def insert_indentation(line, indentation)
|
42
30
|
line = line.is_a?(Array) ? line[0] : line
|
43
31
|
line.insert(0, ' ' * indentation) if line
|
44
32
|
end
|
33
|
+
module_function :insert_indentation
|
45
34
|
end # Indentation
|
46
35
|
end # Table
|
47
36
|
end # TTY
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'strings'
|
4
4
|
|
5
5
|
module TTY
|
6
6
|
class Table
|
@@ -53,7 +53,7 @@ module TTY
|
|
53
53
|
def align_field(field, col)
|
54
54
|
column_width = widths[col]
|
55
55
|
direction = field.alignment || alignments[col] || DEFAULT
|
56
|
-
|
56
|
+
Strings.align(field.content, column_width, direction: direction)
|
57
57
|
end
|
58
58
|
end # Alignment
|
59
59
|
end # Operation
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'strings'
|
4
4
|
|
5
5
|
module TTY
|
6
6
|
class Table
|
@@ -11,7 +11,7 @@ module TTY
|
|
11
11
|
class Padding
|
12
12
|
# Initialize a Padding operation
|
13
13
|
#
|
14
|
-
# @param [
|
14
|
+
# @param [Strings::Padder] padding
|
15
15
|
#
|
16
16
|
# @param [Array[Integer]] widths
|
17
17
|
#
|
@@ -35,7 +35,7 @@ module TTY
|
|
35
35
|
#
|
36
36
|
# @api public
|
37
37
|
def call(field, *)
|
38
|
-
|
38
|
+
Strings.pad(field.content, padding)
|
39
39
|
end
|
40
40
|
|
41
41
|
protected
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'strings'
|
4
4
|
|
5
5
|
module TTY
|
6
6
|
class Table
|
@@ -34,8 +34,8 @@ module TTY
|
|
34
34
|
#
|
35
35
|
# @api public
|
36
36
|
def call(field, row, col)
|
37
|
-
|
38
|
-
|
37
|
+
column_width = widths[col] || field.width
|
38
|
+
Strings.truncate(field.content, column_width)
|
39
39
|
end
|
40
40
|
end # Truncation
|
41
41
|
end # Operation
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'strings'
|
4
4
|
|
5
5
|
module TTY
|
6
6
|
class Table
|
@@ -33,8 +33,8 @@ module TTY
|
|
33
33
|
#
|
34
34
|
# @api public
|
35
35
|
def call(field, row, col)
|
36
|
-
|
37
|
-
|
36
|
+
column_width = widths[col] || field.width
|
37
|
+
Strings.wrap(field.content, column_width)
|
38
38
|
end
|
39
39
|
end # Wrapped
|
40
40
|
end # Operation
|
data/lib/tty/table/operations.rb
CHANGED
@@ -8,14 +8,8 @@ module TTY
|
|
8
8
|
class Operations
|
9
9
|
# Initialize Operations
|
10
10
|
#
|
11
|
-
# @param [TTY::Table] table
|
12
|
-
# the table to perform operations on
|
13
|
-
#
|
14
|
-
# @return [Object]
|
15
|
-
#
|
16
11
|
# @api public
|
17
|
-
def initialize
|
18
|
-
@table = table
|
12
|
+
def initialize
|
19
13
|
@operations = Hash.new { |hash, key| hash[key] = [] }
|
20
14
|
end
|
21
15
|
|
@@ -55,14 +49,14 @@ module TTY
|
|
55
49
|
# @return [TTY::Table]
|
56
50
|
#
|
57
51
|
# @api public
|
58
|
-
def
|
52
|
+
def apply_to(table, *args)
|
59
53
|
operation_types = args
|
60
54
|
table.data.each_with_index do |row, row_i|
|
61
55
|
row.fields.each_with_index do |field, col_i|
|
62
56
|
field.reset!
|
63
57
|
operation_types.each do |type|
|
64
58
|
operations[type].each do |operation|
|
65
|
-
field.content = operation.
|
59
|
+
field.content = operation.(field, row_i, col_i)
|
66
60
|
end
|
67
61
|
end
|
68
62
|
end
|
@@ -71,11 +65,6 @@ module TTY
|
|
71
65
|
|
72
66
|
protected
|
73
67
|
|
74
|
-
# The table
|
75
|
-
#
|
76
|
-
# @api private
|
77
|
-
attr_reader :table
|
78
|
-
|
79
68
|
# Available operations
|
80
69
|
#
|
81
70
|
# @return [Hash]
|
data/lib/tty/table/renderer.rb
CHANGED
@@ -7,12 +7,12 @@ require_relative 'renderer/unicode'
|
|
7
7
|
|
8
8
|
module TTY
|
9
9
|
class Table
|
10
|
-
# A
|
10
|
+
# A module responsible for selecting tabule data renderer
|
11
11
|
#
|
12
12
|
# Used internally by {Table} to render table content out.
|
13
13
|
#
|
14
14
|
# @api private
|
15
|
-
|
15
|
+
module Renderer
|
16
16
|
RENDERER_MAPPER = {
|
17
17
|
ascii: TTY::Table::Renderer::ASCII,
|
18
18
|
basic: TTY::Table::Renderer::Basic,
|
@@ -30,9 +30,10 @@ module TTY
|
|
30
30
|
# @return [TTY::Table::Renderer]
|
31
31
|
#
|
32
32
|
# @api private
|
33
|
-
def
|
33
|
+
def select(type)
|
34
34
|
RENDERER_MAPPER[type || :basic]
|
35
35
|
end
|
36
|
+
module_function :select
|
36
37
|
|
37
38
|
# Raises an error if provided border class is of wrong type or has invalid
|
38
39
|
# implementation
|
@@ -44,7 +45,7 @@ module TTY
|
|
44
45
|
# raised when border class does not implement core methods
|
45
46
|
#
|
46
47
|
# @api public
|
47
|
-
def
|
48
|
+
def assert_border_class(border_class)
|
48
49
|
return unless border_class
|
49
50
|
unless border_class <= TTY::Table::Border
|
50
51
|
fail TypeError,
|
@@ -55,6 +56,27 @@ module TTY
|
|
55
56
|
"#{border_class} should implement def_border"
|
56
57
|
end
|
57
58
|
end
|
59
|
+
module_function :assert_border_class
|
60
|
+
|
61
|
+
# Render a given table and return the string representation.
|
62
|
+
#
|
63
|
+
# @param [TTY::Table] table
|
64
|
+
# the table to be rendered
|
65
|
+
#
|
66
|
+
# @param [Hash] options
|
67
|
+
# the options to render the table with
|
68
|
+
# @option options [String] :renderer
|
69
|
+
# used to format table output
|
70
|
+
#
|
71
|
+
# @return [String]
|
72
|
+
#
|
73
|
+
# @api public
|
74
|
+
def render(table, options = {}, &block)
|
75
|
+
renderer = select(options[:renderer]).new(table, options)
|
76
|
+
yield renderer if block_given?
|
77
|
+
renderer.render
|
78
|
+
end
|
79
|
+
module_function :render
|
58
80
|
|
59
81
|
# Add custom border for the renderer
|
60
82
|
#
|
@@ -71,30 +93,12 @@ module TTY
|
|
71
93
|
# raise if the klass does not implement def_border
|
72
94
|
#
|
73
95
|
# @api public
|
74
|
-
def
|
96
|
+
def render_with(border_class, table, options = {}, &block)
|
75
97
|
assert_border_class(border_class)
|
76
98
|
options[:border_class] = border_class if border_class
|
77
99
|
render(table, options, &block)
|
78
100
|
end
|
79
|
-
|
80
|
-
# Render a given table and return the string representation.
|
81
|
-
#
|
82
|
-
# @param [TTY::Table] table
|
83
|
-
# the table to be rendered
|
84
|
-
#
|
85
|
-
# @param [Hash] options
|
86
|
-
# the options to render the table with
|
87
|
-
# @option options [String] :renderer
|
88
|
-
# used to format table output
|
89
|
-
#
|
90
|
-
# @return [String]
|
91
|
-
#
|
92
|
-
# @api public
|
93
|
-
def self.render(table, options = {}, &block)
|
94
|
-
renderer = select(options[:renderer]).new(table, options)
|
95
|
-
yield renderer if block_given?
|
96
|
-
renderer.render
|
97
|
-
end
|
101
|
+
module_function :render_with
|
98
102
|
end # Renderer
|
99
103
|
end # Table
|
100
104
|
end # TTY
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'tty-screen'
|
4
|
-
require '
|
4
|
+
require 'strings'
|
5
5
|
|
6
6
|
require_relative '../alignment_set'
|
7
7
|
require_relative '../border_dsl'
|
@@ -22,7 +22,7 @@ require_relative '../validatable'
|
|
22
22
|
|
23
23
|
module TTY
|
24
24
|
class Table
|
25
|
-
|
25
|
+
module Renderer
|
26
26
|
# Renders table without any border styles.
|
27
27
|
#
|
28
28
|
# @api private
|
@@ -70,7 +70,7 @@ module TTY
|
|
70
70
|
# @api public
|
71
71
|
attr_reader :indent
|
72
72
|
|
73
|
-
# The table
|
73
|
+
# The table total width
|
74
74
|
#
|
75
75
|
# @return [Integer]
|
76
76
|
#
|
@@ -122,7 +122,7 @@ module TTY
|
|
122
122
|
@border_class = options.fetch(:border_class) { Border::Null }
|
123
123
|
@indent = options.fetch(:indent) { 0 }
|
124
124
|
@resize = options.fetch(:resize) { false }
|
125
|
-
@padding =
|
125
|
+
@padding = Strings::Padder.parse(options[:padding])
|
126
126
|
end
|
127
127
|
|
128
128
|
# Parses supplied column widths, if not present
|
@@ -162,7 +162,7 @@ module TTY
|
|
162
162
|
#
|
163
163
|
# @api public
|
164
164
|
def indent=(value)
|
165
|
-
@
|
165
|
+
@indent = value
|
166
166
|
end
|
167
167
|
|
168
168
|
# Sets the output padding,
|
@@ -172,7 +172,7 @@ module TTY
|
|
172
172
|
#
|
173
173
|
# @api public
|
174
174
|
def padding=(value)
|
175
|
-
@padding =
|
175
|
+
@padding = Strings::Padder.parse(value)
|
176
176
|
end
|
177
177
|
|
178
178
|
# Renders table as string with border
|
@@ -188,32 +188,48 @@ module TTY
|
|
188
188
|
def render
|
189
189
|
return if table.empty?
|
190
190
|
|
191
|
-
|
192
|
-
|
193
|
-
|
191
|
+
operations = TTY::Table::Operations.new
|
192
|
+
operations.add(:escape, Operation::Escape.new)
|
193
|
+
operations.apply_to(table, :escape) unless multiline
|
194
|
+
|
194
195
|
column_constraint = ColumnConstraint.new(table, self)
|
195
196
|
@column_widths = column_constraint.enforce
|
196
|
-
|
197
|
+
widths_without_padding = @column_widths.map do |_width|
|
198
|
+
_width - padding.left - padding.right
|
199
|
+
end
|
200
|
+
create_operations(widths_without_padding).each do |op|
|
201
|
+
operations.add(*op)
|
202
|
+
end
|
203
|
+
operations.apply_to(table, *select_operations)
|
204
|
+
|
205
|
+
render_data.compact.join("\n")
|
206
|
+
end
|
207
|
+
|
208
|
+
# Select applicable operations for this table
|
209
|
+
#
|
210
|
+
# @api private
|
211
|
+
def select_operations
|
197
212
|
ops = []
|
198
213
|
ops << :escape unless multiline
|
199
214
|
ops << :alignment
|
200
215
|
ops << (multiline ? :wrapping : :truncation)
|
201
216
|
ops << :padding
|
202
217
|
ops << :filter
|
203
|
-
@operations.run_operations(*ops)
|
204
|
-
|
205
|
-
render_data.compact.join("\n")
|
206
218
|
end
|
207
219
|
|
208
|
-
# Initialize
|
220
|
+
# Initialize operations
|
221
|
+
#
|
222
|
+
# @return [Array[String, Operation]]
|
209
223
|
#
|
210
224
|
# @api private
|
211
|
-
def
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
225
|
+
def create_operations(widths)
|
226
|
+
[
|
227
|
+
[:alignment, Operation::Alignment.new(alignments, widths)],
|
228
|
+
[:filter, Operation::Filter.new(filter)],
|
229
|
+
[:truncation, Operation::Truncation.new(widths)],
|
230
|
+
[:wrapping, Operation::Wrapped.new(widths)],
|
231
|
+
[:padding, Operation::Padding.new(padding)]
|
232
|
+
]
|
217
233
|
end
|
218
234
|
|
219
235
|
protected
|
@@ -225,33 +241,17 @@ module TTY
|
|
225
241
|
# @api public
|
226
242
|
attr_reader :table
|
227
243
|
|
228
|
-
# Initializes indentation
|
229
|
-
#
|
230
|
-
# @return [TTY::Table::Indentation]
|
231
|
-
#
|
232
|
-
# @api private
|
233
|
-
def indentation
|
234
|
-
@indentation ||= TTY::Table::Indentation.new(indent)
|
235
|
-
end
|
236
|
-
|
237
|
-
# Delegate indentation insertion
|
238
|
-
#
|
239
|
-
# @api public
|
240
|
-
def insert_indent(line)
|
241
|
-
indentation.indent(line)
|
242
|
-
end
|
243
|
-
|
244
244
|
# Render table data
|
245
245
|
#
|
246
246
|
# @api private
|
247
247
|
def render_data
|
248
248
|
first_row = table.first
|
249
|
-
data_border = border_class.new(column_widths,
|
249
|
+
data_border = border_class.new(column_widths, border)
|
250
250
|
header = render_header(first_row, data_border)
|
251
251
|
rows_with_border = render_rows(data_border)
|
252
252
|
bottom_line = data_border.bottom_line
|
253
253
|
|
254
|
-
|
254
|
+
Indentation.indent(bottom_line, @indent) if bottom_line
|
255
255
|
|
256
256
|
[header, rows_with_border, bottom_line].compact
|
257
257
|
end
|
@@ -271,7 +271,7 @@ module TTY
|
|
271
271
|
top_line = data_border.top_line
|
272
272
|
if row.is_a?(TTY::Table::Header)
|
273
273
|
header = [top_line, data_border.row_line(row), data_border.separator]
|
274
|
-
|
274
|
+
Indentation.indent(header.compact, @indent)
|
275
275
|
else
|
276
276
|
top_line
|
277
277
|
end
|
@@ -309,10 +309,11 @@ module TTY
|
|
309
309
|
row_line = data_border.row_line(row)
|
310
310
|
|
311
311
|
if (border.separator == TTY::Table::Border::EACH_ROW) && is_last_row
|
312
|
-
|
312
|
+
line = [row_line, separator]
|
313
313
|
else
|
314
|
-
|
314
|
+
line = row_line
|
315
315
|
end
|
316
|
+
Indentation.indent(line, @indent)
|
316
317
|
end
|
317
318
|
end # Basic
|
318
319
|
end # Renderer
|