tty-table 0.1.0 → 0.2.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/CHANGELOG.md +24 -0
- data/README.md +458 -142
- data/lib/tty-table.rb +6 -6
- data/lib/tty/table.rb +34 -34
- data/lib/tty/table/alignment_set.rb +73 -0
- data/lib/tty/table/border.rb +54 -36
- data/lib/tty/table/border/null.rb +4 -4
- data/lib/tty/table/{columns.rb → column_constraint.rb} +30 -32
- data/lib/tty/table/column_set.rb +18 -17
- data/lib/tty/table/field.rb +50 -25
- data/lib/tty/table/header.rb +6 -2
- data/lib/tty/table/indentation.rb +7 -12
- data/lib/tty/table/operation/alignment.rb +59 -0
- data/lib/tty/table/operation/escape.rb +1 -1
- data/lib/tty/table/operation/filter.rb +1 -1
- data/lib/tty/table/operation/padding.rb +12 -61
- data/lib/tty/table/operation/truncation.rb +2 -2
- data/lib/tty/table/operation/wrapped.rb +2 -5
- data/lib/tty/table/operations.rb +35 -17
- data/lib/tty/table/orientation/vertical.rb +4 -4
- data/lib/tty/table/renderer.rb +1 -7
- data/lib/tty/table/renderer/basic.rb +69 -63
- data/lib/tty/table/version.rb +1 -1
- data/spec/spec_helper.rb +3 -4
- data/spec/unit/access_spec.rb +8 -8
- data/spec/unit/{operation/alignment_set → alignment_set}/each_spec.rb +1 -1
- data/spec/unit/{operation/alignment_set → alignment_set}/new_spec.rb +4 -4
- data/spec/unit/{operation/alignment_set → alignment_set}/to_ary_spec.rb +1 -1
- data/spec/unit/alignment_spec.rb +71 -0
- data/spec/unit/border/ascii/rendering_spec.rb +12 -12
- data/spec/unit/border/new_spec.rb +2 -2
- data/spec/unit/border/null/rendering_spec.rb +2 -2
- data/spec/unit/border/unicode/rendering_spec.rb +10 -10
- data/spec/unit/{columns → column_constraint}/enforce_spec.rb +15 -12
- data/spec/unit/{columns → column_constraint}/widths_spec.rb +6 -6
- data/spec/unit/column_set/extract_widths_spec.rb +39 -6
- data/spec/unit/data_spec.rb +4 -6
- data/spec/unit/each_spec.rb +8 -23
- data/spec/unit/each_with_index_spec.rb +27 -33
- data/spec/unit/field/length_spec.rb +23 -9
- data/spec/unit/field/width_spec.rb +1 -1
- data/spec/unit/filter_spec.rb +7 -8
- data/spec/unit/header/new_spec.rb +6 -15
- data/spec/unit/indentation/indent_spec.rb +21 -0
- data/spec/unit/new_spec.rb +73 -0
- data/spec/unit/operation/{alignment_set → alignment}/call_spec.rb +1 -1
- data/spec/unit/operation/escape/call_spec.rb +2 -3
- data/spec/unit/operation/filter/call_spec.rb +2 -3
- data/spec/unit/operation/truncation/call_spec.rb +6 -8
- data/spec/unit/operation/wrapped/call_spec.rb +15 -8
- data/spec/unit/operations/new_spec.rb +1 -1
- data/spec/unit/orientation_spec.rb +6 -6
- data/spec/unit/padding_spec.rb +29 -32
- data/spec/unit/properties_spec.rb +4 -4
- data/spec/unit/render_repeat_spec.rb +42 -0
- data/spec/unit/render_spec.rb +1 -1
- data/spec/unit/render_with_spec.rb +3 -3
- data/spec/unit/renderer/ascii/coloring_spec.rb +70 -0
- data/spec/unit/renderer/ascii/multiline_spec.rb +101 -0
- data/spec/unit/renderer/ascii/padding_spec.rb +37 -10
- data/spec/unit/renderer/ascii/render_spec.rb +4 -4
- data/spec/unit/renderer/ascii/resizing_spec.rb +22 -22
- data/spec/unit/renderer/ascii/separator_spec.rb +1 -1
- data/spec/unit/renderer/basic/alignment_spec.rb +20 -20
- data/spec/unit/renderer/basic/coloring_spec.rb +43 -28
- data/spec/unit/renderer/basic/filter_spec.rb +3 -3
- data/spec/unit/renderer/basic/multiline_spec.rb +74 -0
- data/spec/unit/renderer/basic/options_spec.rb +9 -9
- data/spec/unit/renderer/basic/padding_spec.rb +26 -2
- data/spec/unit/renderer/basic/render_spec.rb +4 -4
- data/spec/unit/renderer/basic/resizing_spec.rb +18 -18
- data/spec/unit/renderer/basic/separator_spec.rb +1 -1
- data/spec/unit/renderer/basic/truncation_spec.rb +6 -6
- data/spec/unit/renderer/basic/wrapping_spec.rb +3 -3
- data/spec/unit/renderer/border_spec.rb +4 -4
- data/spec/unit/renderer/unicode/coloring_spec.rb +70 -0
- data/spec/unit/renderer/unicode/indentation_spec.rb +1 -1
- data/spec/unit/renderer/unicode/padding_spec.rb +26 -26
- data/spec/unit/renderer/unicode/render_spec.rb +4 -4
- data/spec/unit/renderer/unicode/separator_spec.rb +1 -1
- data/spec/unit/to_s_spec.rb +4 -11
- data/spec/unit/utf_spec.rb +33 -0
- data/tty-table.gemspec +2 -1
- metadata +52 -32
- data/lib/tty/table/operation/alignment_set.rb +0 -103
- data/lib/tty/table/padder.rb +0 -180
- data/lib/tty/table/renderer/color.rb +0 -12
- data/spec/unit/indentation/insert_indent_spec.rb +0 -27
- data/spec/unit/initialize_spec.rb +0 -88
- data/spec/unit/padder/parse_spec.rb +0 -45
- data/spec/unit/padder/to_s_spec.rb +0 -14
- data/spec/unit/renderer/basic/multiline_content_spec.rb +0 -135
- data/spec/unit/renderer/style_spec.rb +0 -72
data/lib/tty-table.rb
CHANGED
@@ -6,6 +6,7 @@ require 'necromancer'
|
|
6
6
|
require 'verse'
|
7
7
|
require 'tty-screen'
|
8
8
|
require 'pastel'
|
9
|
+
require 'unicode_utils'
|
9
10
|
|
10
11
|
require 'tty/table/header'
|
11
12
|
require 'tty/table/row'
|
@@ -22,23 +23,22 @@ require 'tty/table/border/ascii'
|
|
22
23
|
require 'tty/table/border/null'
|
23
24
|
require 'tty/table/border/row_line'
|
24
25
|
|
25
|
-
require 'tty/table/renderer'
|
26
|
-
require 'tty/table/renderer/ascii'
|
27
26
|
require 'tty/table/renderer/basic'
|
28
|
-
require 'tty/table/renderer/
|
27
|
+
require 'tty/table/renderer/ascii'
|
29
28
|
require 'tty/table/renderer/unicode'
|
29
|
+
require 'tty/table/renderer'
|
30
30
|
|
31
|
+
require 'tty/table/alignment_set'
|
31
32
|
require 'tty/table/column_set'
|
32
|
-
require 'tty/table/
|
33
|
+
require 'tty/table/column_constraint'
|
33
34
|
require 'tty/table/orientation'
|
34
35
|
require 'tty/table/orientation/horizontal'
|
35
36
|
require 'tty/table/orientation/vertical'
|
36
37
|
require 'tty/table/transformation'
|
37
38
|
require 'tty/table/indentation'
|
38
|
-
require 'tty/table/padder'
|
39
39
|
|
40
40
|
require 'tty/table/operations'
|
41
|
-
require 'tty/table/operation/
|
41
|
+
require 'tty/table/operation/alignment'
|
42
42
|
require 'tty/table/operation/truncation'
|
43
43
|
require 'tty/table/operation/wrapped'
|
44
44
|
require 'tty/table/operation/filter'
|
data/lib/tty/table.rb
CHANGED
@@ -61,19 +61,18 @@ module TTY
|
|
61
61
|
# Instantiate a new Table
|
62
62
|
#
|
63
63
|
# @example of no header
|
64
|
-
#
|
65
|
-
# table = Table.new rows
|
64
|
+
# table = Table.new [['a1', 'a2'], ['b1', 'b2']]
|
66
65
|
#
|
67
66
|
# @example of direct parameters
|
68
|
-
# rows = [
|
67
|
+
# rows = [['a1', 'a2'], ['b1', 'b2']]
|
69
68
|
# table = Table.new ['Header 1', 'Header 2'], rows
|
70
69
|
#
|
71
70
|
# @example of parameters passed as options
|
72
|
-
# rows = [
|
71
|
+
# rows = [['a1', 'a2'], ['b1', 'b2']]
|
73
72
|
# table = Table.new header: ['Header 1', 'Header 2'], rows: rows
|
74
73
|
#
|
75
74
|
# @example of parameters passed as hash
|
76
|
-
# Table.new [
|
75
|
+
# Table.new [{'Header1' => ['a1','a2'], 'Header2' => ['b1', 'b2'] }]}
|
77
76
|
#
|
78
77
|
# @param [Array[Symbol], Hash] *args
|
79
78
|
#
|
@@ -156,8 +155,8 @@ module TTY
|
|
156
155
|
#
|
157
156
|
# @api private
|
158
157
|
def rotate_vertical
|
159
|
-
@original_columns =
|
160
|
-
@original_rows =
|
158
|
+
@original_columns = columns_size
|
159
|
+
@original_rows = rows_size
|
161
160
|
@rows = orientation.slice(self)
|
162
161
|
@header = [] if header
|
163
162
|
@rotated = true
|
@@ -179,6 +178,15 @@ module TTY
|
|
179
178
|
|
180
179
|
# Lookup element of the table given a row(i) and column(j)
|
181
180
|
#
|
181
|
+
# @param [Integer] row_index
|
182
|
+
# @param [Integer] column_index
|
183
|
+
#
|
184
|
+
# @example
|
185
|
+
# table = TTY::Table.new [['a1','a2'], ['b1','b2']]
|
186
|
+
# table[0] # => ['a1','a2']
|
187
|
+
# table[0,0] # => 'a1'
|
188
|
+
# table[-1] # => ['b1','b2']
|
189
|
+
#
|
182
190
|
# @api public
|
183
191
|
def [](row_index, column_index = false)
|
184
192
|
return row(row_index) unless column_index
|
@@ -188,9 +196,9 @@ module TTY
|
|
188
196
|
fail TTY::Table::TupleMissing.new(row_index, column_index)
|
189
197
|
end
|
190
198
|
end
|
191
|
-
|
192
|
-
|
193
|
-
|
199
|
+
alias_method :at, :[]
|
200
|
+
alias_method :element, :[]
|
201
|
+
alias_method :component, :[]
|
194
202
|
|
195
203
|
# Set table value at row(i) and column(j)
|
196
204
|
#
|
@@ -204,9 +212,9 @@ module TTY
|
|
204
212
|
# When a block is given, the elements of that Array are iterated over.
|
205
213
|
#
|
206
214
|
# @example
|
207
|
-
# rows = [
|
208
|
-
# table = TTY::Table.new :
|
209
|
-
# table.row(1) { |
|
215
|
+
# rows = [['a1', 'a2'], ['b1', 'b2']]
|
216
|
+
# table = TTY::Table.new rows: rows
|
217
|
+
# table.row(1) { |row| ... }
|
210
218
|
#
|
211
219
|
# @param [Integer] index
|
212
220
|
#
|
@@ -247,7 +255,7 @@ module TTY
|
|
247
255
|
#
|
248
256
|
# @api public
|
249
257
|
def column(index)
|
250
|
-
index_unknown = index.is_a?(Integer) && (index >=
|
258
|
+
index_unknown = index.is_a?(Integer) && (index >= columns_size || index < 0)
|
251
259
|
if block_given?
|
252
260
|
return self if index_unknown
|
253
261
|
rows.map { |row| yield row[index] }
|
@@ -288,29 +296,22 @@ module TTY
|
|
288
296
|
self
|
289
297
|
end
|
290
298
|
|
291
|
-
#
|
299
|
+
# Same as #each but passes the index of the row with the row itself
|
292
300
|
#
|
293
301
|
# @example
|
294
302
|
# table = TTY::Table.new(header, tuples)
|
295
|
-
# table.each_with_index { |
|
303
|
+
# table.each_with_index { |row, index|
|
304
|
+
# puts "#{row} at #{index}"
|
305
|
+
# }
|
296
306
|
#
|
297
307
|
# @return self
|
298
308
|
#
|
299
309
|
# @api public
|
300
310
|
def each_with_index
|
301
311
|
return to_enum unless block_given?
|
302
|
-
start_index =
|
303
|
-
|
304
|
-
|
305
|
-
yield el, 0, col_index
|
306
|
-
end
|
307
|
-
start_index = 1
|
308
|
-
end
|
309
|
-
|
310
|
-
rows.each_with_index do |row, row_index|
|
311
|
-
row.fields.each_with_index do |el, col_index|
|
312
|
-
yield el, row_index + start_index, col_index
|
313
|
-
end
|
312
|
+
start_index = -1
|
313
|
+
data.each do |row|
|
314
|
+
yield row.to_a, start_index += 1
|
314
315
|
end
|
315
316
|
self
|
316
317
|
end
|
@@ -318,13 +319,12 @@ module TTY
|
|
318
319
|
# Return the number of columns
|
319
320
|
#
|
320
321
|
# @example
|
321
|
-
# table.
|
322
|
+
# table.columns_size # => 5
|
322
323
|
#
|
323
324
|
# @return [Integer]
|
324
325
|
#
|
325
326
|
# @api public
|
326
|
-
|
327
|
-
def column_size
|
327
|
+
def columns_size
|
328
328
|
rows.size > 0 ? rows[0].size : 0
|
329
329
|
end
|
330
330
|
|
@@ -336,7 +336,7 @@ module TTY
|
|
336
336
|
# @return [Integer]
|
337
337
|
#
|
338
338
|
# @api public
|
339
|
-
def
|
339
|
+
def rows_size
|
340
340
|
rows.size
|
341
341
|
end
|
342
342
|
|
@@ -349,7 +349,7 @@ module TTY
|
|
349
349
|
#
|
350
350
|
# @api public
|
351
351
|
def size
|
352
|
-
[
|
352
|
+
[rows_size, columns_size]
|
353
353
|
end
|
354
354
|
|
355
355
|
# Check table width
|
@@ -368,7 +368,7 @@ module TTY
|
|
368
368
|
#
|
369
369
|
# @api public
|
370
370
|
def empty?
|
371
|
-
|
371
|
+
columns_size == 0 || rows_size == 0
|
372
372
|
end
|
373
373
|
|
374
374
|
# Return string representation of table using basic renderer.
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Table
|
5
|
+
# A class responsible for column alignments
|
6
|
+
#
|
7
|
+
# Used internally by {TTY::Table::Operation::Alignment}
|
8
|
+
class AlignmentSet
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
DEFAULT = :left
|
12
|
+
|
13
|
+
# Initialize an AlignmentSet
|
14
|
+
#
|
15
|
+
# @param [AlignmentSet, Array] alignments
|
16
|
+
# the alignments for the renderer
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
def initialize(alignments)
|
20
|
+
@converter = Necromancer.new
|
21
|
+
@alignments = @converter.convert(alignments).to(:array).map(&:to_sym)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Iterate over each element in the alignment set
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# alignment = AlignmentSet.new [1,2,3]
|
28
|
+
# alignment.each { |element| ... }
|
29
|
+
#
|
30
|
+
# @return [self]
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def each
|
34
|
+
return to_enum unless block_given?
|
35
|
+
to_ary.each { |element| yield element }
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
# Lookup an alignment by index
|
40
|
+
#
|
41
|
+
# @param [Integer]
|
42
|
+
#
|
43
|
+
# @return [Symbol] alignment
|
44
|
+
#
|
45
|
+
# @api public
|
46
|
+
def [](index)
|
47
|
+
alignments.fetch(index, DEFAULT)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Convert to array
|
51
|
+
#
|
52
|
+
# @return [Array]
|
53
|
+
#
|
54
|
+
# @api public
|
55
|
+
def to_ary
|
56
|
+
alignments.to_a
|
57
|
+
end
|
58
|
+
|
59
|
+
# String representation of aligments
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
#
|
63
|
+
# @api public
|
64
|
+
def to_s
|
65
|
+
to_ary
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
attr_reader :alignments
|
71
|
+
end # AlignmentSet
|
72
|
+
end # Table
|
73
|
+
end # TTY
|
data/lib/tty/table/border.rb
CHANGED
@@ -13,17 +13,6 @@ module TTY
|
|
13
13
|
# Represent a separtor on each row
|
14
14
|
EACH_ROW = :each_row
|
15
15
|
|
16
|
-
# The row field widths
|
17
|
-
#
|
18
|
-
# @api private
|
19
|
-
attr_reader :widths
|
20
|
-
private :widths
|
21
|
-
|
22
|
-
# The table custom border characters
|
23
|
-
attr_reader :border
|
24
|
-
|
25
|
-
# The table
|
26
|
-
|
27
16
|
class << self
|
28
17
|
# Store characters for border
|
29
18
|
#
|
@@ -41,12 +30,13 @@ module TTY
|
|
41
30
|
# @return [Object]
|
42
31
|
#
|
43
32
|
# @api private
|
44
|
-
def initialize(column_widths, options = nil)
|
33
|
+
def initialize(column_widths, padding, options = nil)
|
45
34
|
if self.class == Border
|
46
35
|
fail NotImplementedError, "#{self} is an abstract class"
|
47
36
|
else
|
48
37
|
@widths = column_widths
|
49
|
-
@
|
38
|
+
@padding = Verse::Padder.parse(padding)
|
39
|
+
@border_options = TTY::Table::BorderOptions.from options
|
50
40
|
@color = Pastel.new
|
51
41
|
end
|
52
42
|
end
|
@@ -66,7 +56,7 @@ module TTY
|
|
66
56
|
self.characters = dsl.characters
|
67
57
|
end
|
68
58
|
|
69
|
-
# Retrive
|
59
|
+
# Retrive individual character by type
|
70
60
|
#
|
71
61
|
# @param [String] type
|
72
62
|
# the character type
|
@@ -76,7 +66,11 @@ module TTY
|
|
76
66
|
# @api private
|
77
67
|
def [](type)
|
78
68
|
characters = self.class.characters
|
79
|
-
chars =
|
69
|
+
chars = if border_options.nil?
|
70
|
+
characters
|
71
|
+
else
|
72
|
+
characters.merge(border_options.characters)
|
73
|
+
end
|
80
74
|
chars[type] || EMPTY_CHAR
|
81
75
|
end
|
82
76
|
|
@@ -86,20 +80,7 @@ module TTY
|
|
86
80
|
#
|
87
81
|
# @api public
|
88
82
|
def color?
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
# Set color on characters
|
93
|
-
#
|
94
|
-
# @param [Symbol] color
|
95
|
-
#
|
96
|
-
# @param [Array[String]] array of strings
|
97
|
-
#
|
98
|
-
# @return [Array[String]]
|
99
|
-
#
|
100
|
-
# @api public
|
101
|
-
def set_color(color, *strings)
|
102
|
-
strings.map { |string| @color.decorate(string, color) }
|
83
|
+
border_options && border_options.style
|
103
84
|
end
|
104
85
|
|
105
86
|
# A line spanning all columns marking top of a table.
|
@@ -139,14 +120,48 @@ module TTY
|
|
139
120
|
# @api public
|
140
121
|
def row_line(row)
|
141
122
|
line = RowLine.new(self['left'], self['center'], self['right'])
|
142
|
-
line.colorize(self,
|
123
|
+
line.colorize(self, border_options.style) if color?
|
143
124
|
|
144
125
|
result = row_heights(row, line)
|
145
126
|
result.empty? ? EMPTY_CHAR : result
|
146
127
|
end
|
147
128
|
|
129
|
+
# Set color on characters
|
130
|
+
#
|
131
|
+
# @param [Symbol] color
|
132
|
+
#
|
133
|
+
# @param [Array[String]] array of strings
|
134
|
+
#
|
135
|
+
# @return [Array[String]]
|
136
|
+
#
|
137
|
+
# @api public
|
138
|
+
def set_color(color, *strings)
|
139
|
+
strings.map do |string|
|
140
|
+
if string.gsub(/\s+/, '').empty?
|
141
|
+
string
|
142
|
+
else
|
143
|
+
@color.decorate(string, color)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
148
|
protected
|
149
149
|
|
150
|
+
# The row field widths
|
151
|
+
#
|
152
|
+
# @api private
|
153
|
+
attr_reader :widths
|
154
|
+
|
155
|
+
# The table custom border options including styling
|
156
|
+
#
|
157
|
+
# @api private
|
158
|
+
attr_reader :border_options
|
159
|
+
|
160
|
+
# The padding to apply to each field
|
161
|
+
#
|
162
|
+
# @api private
|
163
|
+
attr_reader :padding
|
164
|
+
|
150
165
|
# Separate multiline string into individual rows with border.
|
151
166
|
#
|
152
167
|
# @param [TTY::Table::Row] row
|
@@ -180,7 +195,9 @@ module TTY
|
|
180
195
|
# @api private
|
181
196
|
def row_height_line(row, line_index, line)
|
182
197
|
line.left + row.fields.each_with_index.map do |field, index|
|
183
|
-
|
198
|
+
direction = field.alignment || :left
|
199
|
+
field_content = field.lines[line_index] || SPACE_CHAR * field.length
|
200
|
+
Verse.align(field_content, widths[index], direction)
|
184
201
|
end.join(line.center) + line.right
|
185
202
|
end
|
186
203
|
|
@@ -198,21 +215,22 @@ module TTY
|
|
198
215
|
self["#{type}_right"] || border_char,
|
199
216
|
self["#{type}_mid"])
|
200
217
|
|
201
|
-
|
202
|
-
|
203
|
-
end
|
204
|
-
line
|
218
|
+
return line unless color?
|
219
|
+
set_color(border_options.style, line).join
|
205
220
|
end
|
206
221
|
|
207
222
|
# Generate a border string
|
208
223
|
#
|
209
224
|
# @param [String] line
|
225
|
+
# the line character
|
210
226
|
#
|
211
227
|
# @return [String]
|
212
228
|
#
|
213
229
|
# @api private
|
214
230
|
def render_line(line, left, right, intersection)
|
215
|
-
left + widths.map
|
231
|
+
left + widths.map do |width|
|
232
|
+
line * (padding.left + width + padding.right)
|
233
|
+
end.join(intersection) + right
|
216
234
|
end
|
217
235
|
end # Border
|
218
236
|
end # Table
|
@@ -14,22 +14,22 @@ module TTY
|
|
14
14
|
#
|
15
15
|
# @api private
|
16
16
|
def top_line
|
17
|
-
|
17
|
+
border_options ? super : nil
|
18
18
|
end
|
19
19
|
|
20
20
|
# A stub separator line
|
21
21
|
#
|
22
22
|
# @api private
|
23
23
|
def separator
|
24
|
-
return [] if
|
25
|
-
|
24
|
+
return [] if border_options.separator == EACH_ROW
|
25
|
+
border_options ? super : nil
|
26
26
|
end
|
27
27
|
|
28
28
|
# A stub bottom line
|
29
29
|
#
|
30
30
|
# @api private
|
31
31
|
def bottom_line
|
32
|
-
|
32
|
+
border_options ? super : nil
|
33
33
|
end
|
34
34
|
end # Null
|
35
35
|
end # Border
|