tty 0.0.7 → 0.0.8
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.
- data/.travis.yml +0 -1
- data/README.md +141 -23
- data/benchmarks/table.rb +5 -0
- data/lib/tty/logger.rb +71 -0
- data/lib/tty/support/equatable.rb +6 -2
- data/lib/tty/system/which.rb +41 -0
- data/lib/tty/system.rb +8 -0
- data/lib/tty/table/border/ascii.rb +15 -16
- data/lib/tty/table/border/null.rb +9 -4
- data/lib/tty/table/border/unicode.rb +15 -16
- data/lib/tty/table/border.rb +69 -9
- data/lib/tty/table/border_dsl.rb +247 -0
- data/lib/tty/table/border_options.rb +52 -0
- data/lib/tty/table/field.rb +101 -0
- data/lib/tty/table/header.rb +115 -0
- data/lib/tty/table/operation/alignment_set.rb +14 -10
- data/lib/tty/table/operation/truncation.rb +19 -13
- data/lib/tty/table/operation/wrapped.rb +20 -9
- data/lib/tty/table/operations.rb +69 -0
- data/lib/tty/table/renderer/basic.rb +35 -26
- data/lib/tty/table/renderer.rb +13 -1
- data/lib/tty/table/row.rb +174 -0
- data/lib/tty/table.rb +96 -21
- data/lib/tty/text/truncation.rb +1 -1
- data/lib/tty/vector.rb +8 -7
- data/lib/tty/version.rb +1 -1
- data/lib/tty.rb +21 -0
- data/spec/tty/logger/new_spec.rb +36 -0
- data/spec/tty/logger/valid_level_spec.rb +33 -0
- data/spec/tty/system/platform_spec.rb +8 -0
- data/spec/tty/system/which_spec.rb +41 -0
- data/spec/tty/table/access_spec.rb +12 -1
- data/spec/tty/table/add_row_spec.rb +28 -0
- data/spec/tty/table/border/new_spec.rb +9 -4
- data/spec/tty/table/border/null/rendering_spec.rb +39 -1
- data/spec/tty/table/border/options/from_spec.rb +39 -0
- data/spec/tty/table/border/options/new_spec.rb +15 -0
- data/spec/tty/table/border/style_spec.rb +70 -0
- data/spec/tty/table/border_spec.rb +107 -0
- data/spec/tty/table/each_with_index_spec.rb +30 -0
- data/spec/tty/table/field/equality_spec.rb +51 -0
- data/spec/tty/table/field/new_spec.rb +29 -0
- data/spec/tty/table/field/width_spec.rb +21 -0
- data/spec/tty/table/header/call_spec.rb +30 -0
- data/spec/tty/table/header/new_spec.rb +25 -0
- data/spec/tty/table/header/set_spec.rb +15 -0
- data/spec/tty/table/header/to_ary_spec.rb +14 -0
- data/spec/tty/table/header_spec.rb +14 -0
- data/spec/tty/table/operation/alignment_set/align_rows_spec.rb +8 -1
- data/spec/tty/table/operation/truncation/call_spec.rb +27 -0
- data/spec/tty/table/operation/wrapped/call_spec.rb +27 -0
- data/spec/tty/table/operations/new_spec.rb +32 -0
- data/spec/tty/table/options_spec.rb +17 -9
- data/spec/tty/table/renderer/basic/alignment_spec.rb +76 -29
- data/spec/tty/table/renderer/basic/separator_spec.rb +99 -0
- data/spec/tty/table/renderer_spec.rb +7 -1
- data/spec/tty/table/renders_with_spec.rb +35 -28
- data/spec/tty/table/rotate_spec.rb +1 -0
- data/spec/tty/table/row/access_spec.rb +25 -0
- data/spec/tty/table/row/call_spec.rb +41 -0
- data/spec/tty/table/row/data_spec.rb +26 -0
- data/spec/tty/table/row/equality_spec.rb +73 -0
- data/spec/tty/table/row/new_spec.rb +41 -0
- data/spec/tty/table/row/to_ary_spec.rb +14 -0
- data/spec/tty/text/truncation/truncate_spec.rb +6 -0
- metadata +72 -10
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# TTY
|
2
|
-
[][gem]
|
3
|
+
[][travis]
|
4
|
+
[][codeclimate]
|
3
5
|
|
6
|
+
[gem]: http://badge.fury.io/rb/tty
|
4
7
|
[travis]: http://travis-ci.org/peter-murach/tty
|
5
8
|
[codeclimate]: https://codeclimate.com/github/peter-murach/tty
|
6
9
|
|
@@ -10,14 +13,16 @@ Toolbox for developing CLI clients in Ruby. This library provides a fluid interf
|
|
10
13
|
|
11
14
|
Jump-start development of your command line app:
|
12
15
|
|
13
|
-
*
|
14
|
-
* Terminal output colorization.
|
15
|
-
* Terminal & System detection utilities.
|
16
|
-
* Text
|
17
|
-
* Shell user interface.
|
18
|
-
* File diffs.
|
19
|
-
* Progress bar.
|
20
|
-
* Configuration file management.
|
16
|
+
* Table rendering with an easy-to-use API [status: In Progress]
|
17
|
+
* Terminal output colorization. [status: ✔ ]
|
18
|
+
* Terminal & System detection utilities. [status: In Progress]
|
19
|
+
* Text manipulation(wrapping/truncation) [status: In Progress]
|
20
|
+
* Shell user interface. [status: In Progress]
|
21
|
+
* File diffs. [status: TODO]
|
22
|
+
* Progress bar. [status: TODO]
|
23
|
+
* Configuration file management. [status: TODO]
|
24
|
+
* Logging [status: In Progress]
|
25
|
+
* Plugin ecosystem [status: TODO]
|
21
26
|
* Fully tested with major ruby interpreters.
|
22
27
|
* No dependencies to allow for easy gem vendoring.
|
23
28
|
|
@@ -45,7 +50,6 @@ To instantiate table pass 2-dimensional array:
|
|
45
50
|
table = TTY::Table[['a1', 'a2'], ['b1', 'b2']]
|
46
51
|
table = TTY::Table.new [['a1', 'a2'], ['b1', 'b2']]
|
47
52
|
table = TTY::Table.new rows: [['a1', 'a2'], ['b1', 'b2']]
|
48
|
-
|
49
53
|
table = TTY::Table.new ['h1', 'h2'], [['a1', 'a2'], ['b1', 'b2']]
|
50
54
|
table = TTY::Table.new header: ['h1', 'h2'], rows: [['a1', 'a2'], ['b1', 'b2']]
|
51
55
|
```
|
@@ -63,6 +67,8 @@ Apart from `rows` and `header`, you can provide other customization options such
|
|
63
67
|
column_aligns # array of cell alignments out of :left, :center and :right
|
64
68
|
renderer # enforce display type out of :basic, :color, :unicode, :ascii
|
65
69
|
orientation # either :horizontal or :vertical
|
70
|
+
border # hash of border properties out of :characters, :style, :separator keys
|
71
|
+
width # constrain the table total width, otherwise dynamically calculated based on content and terminal size
|
66
72
|
```
|
67
73
|
|
68
74
|
Table behaves like an Array so `<<`, `each` and familiar methods can be used
|
@@ -73,12 +79,15 @@ Table behaves like an Array so `<<`, `each` and familiar methods can be used
|
|
73
79
|
table << ['a1', 'a2'] << ['b1', 'b2'] # chain rows assignment
|
74
80
|
|
75
81
|
table.each { |row| ... } # iterate over rows
|
82
|
+
table.each_with_index # iterate over each element with row and column index
|
76
83
|
table[i, j] # return element at row(i) and column(j)
|
77
84
|
table.row(i) { ... } # return array for row(i)
|
78
85
|
table.column(j) { ... } # return array for column(j)
|
86
|
+
table.column(name) # return array for column(name), name of header
|
79
87
|
table.row_size # return row size
|
80
88
|
table.column_size # return column size
|
81
89
|
table.size # return an array of [row_size, column_size]
|
90
|
+
table.border # specify border properties
|
82
91
|
```
|
83
92
|
|
84
93
|
or pass your rows in a block
|
@@ -99,7 +108,9 @@ And then to print do
|
|
99
108
|
b1 b2 b3
|
100
109
|
```
|
101
110
|
|
102
|
-
|
111
|
+
#### Border
|
112
|
+
|
113
|
+
To print border around data table you need to specify `renderer` type out of `basic`, `ascii`, `unicode`. By default `basic` is used. For instance, to output unicode border:
|
103
114
|
|
104
115
|
```
|
105
116
|
table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2'], renderer: 'unicode'
|
@@ -113,26 +124,132 @@ To print border around data table you need to specify `renderer` type out of `ba
|
|
113
124
|
└───────┴───────┘
|
114
125
|
```
|
115
126
|
|
116
|
-
You can also create your own custom border by subclassing `TTY::Table::Border`
|
127
|
+
You can also create your own custom border by subclassing `TTY::Table::Border` and implementing the `def_border` method using internal DSL methods like so:
|
117
128
|
|
118
129
|
```ruby
|
119
130
|
class MyBorder < TTY::Table::Border
|
120
131
|
def_border do
|
121
|
-
|
122
|
-
|
123
|
-
'
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
}
|
132
|
+
left '$'
|
133
|
+
center '$'
|
134
|
+
right '$'
|
135
|
+
bottom ' '
|
136
|
+
bottom_mid '*'
|
137
|
+
bottom_left '*'
|
138
|
+
bottom_right '*'
|
129
139
|
end
|
130
140
|
end
|
131
141
|
```
|
132
|
-
|
142
|
+
|
143
|
+
Next pass the border class to your instantiated table
|
133
144
|
|
134
145
|
```ruby
|
146
|
+
table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2']
|
135
147
|
table.renders_with MyBorder
|
148
|
+
table.to_s
|
149
|
+
|
150
|
+
$header1$header2$
|
151
|
+
$a1 $a2 $
|
152
|
+
* * *
|
153
|
+
```
|
154
|
+
|
155
|
+
Finally, if you want to introduce slight modifications to the predefined border types, you can use table `border` helper like so
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2']
|
159
|
+
table.border do
|
160
|
+
mid '='
|
161
|
+
mid_mid ' '
|
162
|
+
end
|
163
|
+
|
164
|
+
table.to_s
|
165
|
+
|
166
|
+
header1 header2
|
167
|
+
======= =======
|
168
|
+
a1 a2
|
169
|
+
b1 b2
|
170
|
+
```
|
171
|
+
|
172
|
+
In addition to specifying border characters you can force table to render separator line on each row like:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2']]
|
176
|
+
table.border.separator = :each_row
|
177
|
+
table.to_s
|
178
|
+
|
179
|
+
+-------+-------+
|
180
|
+
|header1|header2|
|
181
|
+
+-------+-------+
|
182
|
+
|a1 |a2 |
|
183
|
+
+-------+-------+
|
184
|
+
|b1 |b2 |
|
185
|
+
+-------+-------+
|
186
|
+
```
|
187
|
+
|
188
|
+
Also to change the display color of your border do:
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
table.border.style = :red
|
192
|
+
```
|
193
|
+
|
194
|
+
#### Alignment
|
195
|
+
|
196
|
+
All columns are left aligned by default. You can enforce per column alignment by passing `column_aligns` option like so
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
rows = [['a1', 'a2'], ['b1', 'b2']
|
200
|
+
table = TTY::Table.new rows: rows, column_aligns: [:center, :right]
|
201
|
+
```
|
202
|
+
|
203
|
+
To align a single column do
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
table.align_column(1, :right)
|
207
|
+
```
|
208
|
+
|
209
|
+
If you require a more granular alignment you can align individual fields in a row by passing `align` option
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
table = TTY::Table.new do |t|
|
213
|
+
t << ['a1', 'a2', 'a3']
|
214
|
+
t << ['b1', {:value => 'b2', :align => :right}, 'b3']
|
215
|
+
t << ['c1', 'c2', {:value => 'c3', :align => :center}]
|
216
|
+
end
|
217
|
+
```
|
218
|
+
|
219
|
+
#### Style
|
220
|
+
|
221
|
+
To format individual fields/cells do
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
table = TTY::Table.new rows: rows, width: 40
|
225
|
+
```
|
226
|
+
|
227
|
+
#### Filter
|
228
|
+
|
229
|
+
You can define filters that will modify individual table fields value before they are rendered. A filter can be a callable such as proc. Here's an example that formats
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2']
|
233
|
+
table.filter = Proc.new do |val, row_index, col_index|
|
234
|
+
if col_index == 1 and !(row_index == 0)
|
235
|
+
val.capitalize
|
236
|
+
end
|
237
|
+
end
|
238
|
+
table.to_s
|
239
|
+
|
240
|
+
+-------+-------+
|
241
|
+
|header1|header2|
|
242
|
+
+-------+-------+
|
243
|
+
|a1 |A2 |
|
244
|
+
+-------+-------+
|
245
|
+
|b1 |B2 |
|
246
|
+
+-------+-------+
|
247
|
+
|
248
|
+
```
|
249
|
+
|
250
|
+
To add background color to even fields do
|
251
|
+
|
252
|
+
```ruby
|
136
253
|
```
|
137
254
|
|
138
255
|
### Terminal
|
@@ -241,8 +358,9 @@ on the other hand, if we are interested in range answer then
|
|
241
358
|
### System
|
242
359
|
|
243
360
|
```ruby
|
244
|
-
TTY::System.unix?
|
245
|
-
TTY::System.windows?
|
361
|
+
TTY::System.unix? # => true
|
362
|
+
TTY::System.windows? # => false
|
363
|
+
TTY::System.which(cmd) # full path to executable if found, nil otherwise
|
246
364
|
```
|
247
365
|
|
248
366
|
## Contributing
|
data/benchmarks/table.rb
CHANGED
@@ -13,6 +13,7 @@ rows = (1..100).map { |n| ["row#{n}", "red"] }
|
|
13
13
|
table = TTY::Table.new(header, rows)
|
14
14
|
table_ascii = TTY::Table.new(header, rows, :renderer => :ascii)
|
15
15
|
table_unicode = TTY::Table.new(header, rows, :renderer => :unicode)
|
16
|
+
table_color = TTY::Table.new(header, rows, :renderer => :ascii, :border => { :style => :red })
|
16
17
|
|
17
18
|
Benchmark.ips do |r|
|
18
19
|
|
@@ -32,4 +33,8 @@ Benchmark.ips do |r|
|
|
32
33
|
table_unicode.to_s
|
33
34
|
end
|
34
35
|
|
36
|
+
r.report("TTY Color #to_s") do
|
37
|
+
table_color.to_s
|
38
|
+
end
|
39
|
+
|
35
40
|
end
|
data/lib/tty/logger.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
|
5
|
+
# A class providing logging system
|
6
|
+
class Logger
|
7
|
+
include TTY::Equatable
|
8
|
+
|
9
|
+
ALL = 0
|
10
|
+
INFO = 1
|
11
|
+
DEBUG = 2
|
12
|
+
WARN = 3
|
13
|
+
ERROR = 4
|
14
|
+
FATAL = 5
|
15
|
+
OFF = 6
|
16
|
+
|
17
|
+
MAX_LEVELS = 7
|
18
|
+
|
19
|
+
attr_reader :namespace
|
20
|
+
|
21
|
+
attr_reader :level
|
22
|
+
|
23
|
+
attr_reader :output
|
24
|
+
|
25
|
+
attr_reader :timestamp_format
|
26
|
+
|
27
|
+
# Initialize a Logger
|
28
|
+
#
|
29
|
+
# @param [String] name
|
30
|
+
#
|
31
|
+
# @param [Hash] options
|
32
|
+
#
|
33
|
+
# @option options [String] :output
|
34
|
+
#
|
35
|
+
# @api public
|
36
|
+
def initialize(options={})
|
37
|
+
@namespace = options.fetch(:namespace) { raise ArgumentError, "Logger must have namespace", caller }
|
38
|
+
@output = options.fetch(:output) { $stderr }
|
39
|
+
@level = options.fetch(:level) { ALL }
|
40
|
+
@timestamp_format = options.fetch(:timestamp_format) { '%Y-%m-%d %T' }
|
41
|
+
end
|
42
|
+
|
43
|
+
def level=(level)
|
44
|
+
validate_level(level)
|
45
|
+
@level = level
|
46
|
+
end
|
47
|
+
|
48
|
+
# @api public
|
49
|
+
def timestamp
|
50
|
+
Time.now.strftime(timestamp_format)
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate_level(level)
|
54
|
+
unless valid_level?(level)
|
55
|
+
raise ArgumentError, "Log level must be 0..#{MAX_LEVELS}", caller
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.valid_level?(level)
|
60
|
+
!level.nil? && level.kind_of?(Numeric) && level >= ALL && level <= OFF
|
61
|
+
end
|
62
|
+
|
63
|
+
# Print formatted log to output
|
64
|
+
#
|
65
|
+
# @api public
|
66
|
+
def log(message)
|
67
|
+
output.print timestamp + ' - ' + message
|
68
|
+
end
|
69
|
+
|
70
|
+
end # Logger
|
71
|
+
end # TTY
|
@@ -85,8 +85,9 @@ module TTY
|
|
85
85
|
# @api private
|
86
86
|
def define_compare
|
87
87
|
define_method(:compare?) do |comparator, other|
|
88
|
-
|
89
|
-
|
88
|
+
klass = self.class
|
89
|
+
attrs = klass.comparison_attrs || []
|
90
|
+
attrs.all? { |attr| send(attr).send(comparator, other.send(attr)) }
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
@@ -142,6 +143,9 @@ module TTY
|
|
142
143
|
#
|
143
144
|
# @api public
|
144
145
|
def ==(other)
|
146
|
+
print '== '
|
147
|
+
p self
|
148
|
+
p other
|
145
149
|
return false unless self.class <=> other.class
|
146
150
|
compare?(__method__, other)
|
147
151
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class System
|
5
|
+
|
6
|
+
# A class responsible for finding an executable in the PATH
|
7
|
+
class Which
|
8
|
+
|
9
|
+
# Find an executable in the PATH
|
10
|
+
#
|
11
|
+
# @param [String] command
|
12
|
+
# the command to search in the PATH
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# which("ruby") # => /usr/local/bin/ruby
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
# the full path to executable if found, `nil` otherwise
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
def which(command)
|
22
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
23
|
+
default_system_path.each do |path|
|
24
|
+
exts.each do |ext|
|
25
|
+
exec = File.join("#{path}", "#{command}#{ext}")
|
26
|
+
return exec if File.executable? exec
|
27
|
+
end
|
28
|
+
end
|
29
|
+
return nil
|
30
|
+
end
|
31
|
+
|
32
|
+
# Find default system paths
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
def default_system_path
|
36
|
+
ENV['PATH'].split(File::PATH_SEPARATOR)
|
37
|
+
end
|
38
|
+
|
39
|
+
end # Which
|
40
|
+
end # System
|
41
|
+
end # TTY
|
data/lib/tty/system.rb
CHANGED
@@ -25,6 +25,14 @@ module TTY
|
|
25
25
|
RbConfig::CONFIG['host_os'] =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
|
26
26
|
end
|
27
27
|
|
28
|
+
# Find an executable in the PATH
|
29
|
+
#
|
30
|
+
# @see TTY::System::Which
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def which(command)
|
34
|
+
Which.new(command)
|
35
|
+
end
|
28
36
|
end
|
29
37
|
|
30
38
|
end # System
|
@@ -8,22 +8,21 @@ module TTY
|
|
8
8
|
class ASCII < Border
|
9
9
|
|
10
10
|
def_border do
|
11
|
-
|
12
|
-
'
|
13
|
-
|
14
|
-
|
15
|
-
'
|
16
|
-
'
|
17
|
-
|
18
|
-
|
19
|
-
'
|
20
|
-
'
|
21
|
-
|
22
|
-
|
23
|
-
'
|
24
|
-
'
|
25
|
-
|
26
|
-
}
|
11
|
+
top '-'
|
12
|
+
top_mid '+'
|
13
|
+
top_left '+'
|
14
|
+
top_right '+'
|
15
|
+
bottom '-'
|
16
|
+
bottom_mid '+'
|
17
|
+
bottom_left '+'
|
18
|
+
bottom_right '+'
|
19
|
+
mid '-'
|
20
|
+
mid_mid '+'
|
21
|
+
mid_left '+'
|
22
|
+
mid_right '+'
|
23
|
+
left '|'
|
24
|
+
center '|'
|
25
|
+
right '|'
|
27
26
|
end
|
28
27
|
|
29
28
|
end # ASCII
|
@@ -7,18 +7,23 @@ module TTY
|
|
7
7
|
# A class that represents no border.
|
8
8
|
class Null < Border
|
9
9
|
|
10
|
+
def_border do
|
11
|
+
center SPACE_CHAR
|
12
|
+
end
|
13
|
+
|
10
14
|
# A stub top line
|
11
15
|
#
|
12
16
|
# @api private
|
13
17
|
def top_line
|
14
|
-
nil
|
18
|
+
border ? super : nil
|
15
19
|
end
|
16
20
|
|
17
21
|
# A stub separator line
|
18
22
|
#
|
19
23
|
# @api private
|
20
24
|
def separator
|
21
|
-
|
25
|
+
return [] if border.separator == EACH_ROW
|
26
|
+
border ? super : nil
|
22
27
|
end
|
23
28
|
|
24
29
|
# A line spanning all columns delemited by space character.
|
@@ -27,14 +32,14 @@ module TTY
|
|
27
32
|
#
|
28
33
|
# @api private
|
29
34
|
def row_line
|
30
|
-
row.join(
|
35
|
+
(border && !border.characters.empty?) ? super : row.join(SPACE_CHAR)
|
31
36
|
end
|
32
37
|
|
33
38
|
# A stub bottom line
|
34
39
|
#
|
35
40
|
# @api private
|
36
41
|
def bottom_line
|
37
|
-
nil
|
42
|
+
border ? super : nil
|
38
43
|
end
|
39
44
|
|
40
45
|
end # Null
|
@@ -8,22 +8,21 @@ module TTY
|
|
8
8
|
class Unicode < Border
|
9
9
|
|
10
10
|
def_border do
|
11
|
-
|
12
|
-
'
|
13
|
-
'
|
14
|
-
'
|
15
|
-
'
|
16
|
-
'
|
17
|
-
'
|
18
|
-
|
19
|
-
'
|
20
|
-
'
|
21
|
-
'
|
22
|
-
'
|
23
|
-
'
|
24
|
-
'
|
25
|
-
|
26
|
-
}
|
11
|
+
top '─'
|
12
|
+
top_mid '┬'
|
13
|
+
top_left '┌'
|
14
|
+
top_right '┐'
|
15
|
+
bottom '─'
|
16
|
+
bottom_mid '┴'
|
17
|
+
bottom_left '└'
|
18
|
+
bottom_right '┘'
|
19
|
+
mid '─'
|
20
|
+
mid_mid '┼'
|
21
|
+
mid_left '├'
|
22
|
+
mid_right '┤'
|
23
|
+
left '│'
|
24
|
+
center '│'
|
25
|
+
right '│'
|
27
26
|
end
|
28
27
|
|
29
28
|
end # Unicode
|
data/lib/tty/table/border.rb
CHANGED
@@ -6,6 +6,14 @@ module TTY
|
|
6
6
|
# Abstract base class that is responsible for building the table border.
|
7
7
|
class Border
|
8
8
|
include Unicode
|
9
|
+
include TTY::Equatable
|
10
|
+
|
11
|
+
EMPTY_CHAR = ''.freeze
|
12
|
+
|
13
|
+
SPACE_CHAR = ' '.freeze
|
14
|
+
|
15
|
+
# Represent a separtor on each row
|
16
|
+
EACH_ROW = :each_row
|
9
17
|
|
10
18
|
# The row cell widths
|
11
19
|
#
|
@@ -19,6 +27,9 @@ module TTY
|
|
19
27
|
attr_reader :row
|
20
28
|
private :row
|
21
29
|
|
30
|
+
# The table custom border characters
|
31
|
+
attr_reader :border
|
32
|
+
|
22
33
|
class << self
|
23
34
|
# Store characters for border
|
24
35
|
#
|
@@ -28,23 +39,36 @@ module TTY
|
|
28
39
|
|
29
40
|
# Instantiate a new object
|
30
41
|
#
|
42
|
+
# @param [Array] row
|
43
|
+
#
|
44
|
+
# @param [BorderOptions] options
|
45
|
+
#
|
31
46
|
# @return [Object]
|
32
47
|
#
|
33
48
|
# @api private
|
34
|
-
def initialize(row=nil)
|
49
|
+
def initialize(row, options=nil)
|
35
50
|
if self.class == Border
|
36
51
|
raise NotImplementedError, "#{self} is an abstract class"
|
37
52
|
else
|
38
53
|
@row = row
|
39
54
|
@widths = row.map { |cell| cell.chars.to_a.size }
|
55
|
+
@border = TTY::Table::BorderOptions.from options
|
40
56
|
end
|
41
57
|
end
|
42
58
|
|
43
59
|
# Define border characters
|
44
60
|
#
|
61
|
+
# @param [Hash] characters
|
62
|
+
# the border characters
|
63
|
+
#
|
64
|
+
# @return [Hash]
|
65
|
+
#
|
45
66
|
# @api public
|
46
|
-
def self.def_border(&block)
|
47
|
-
|
67
|
+
def self.def_border(characters=(not_set=true), &block)
|
68
|
+
return self.characters = characters if !not_set
|
69
|
+
|
70
|
+
dsl = TTY::Table::BorderDSL.new(&block)
|
71
|
+
self.characters = dsl.characters
|
48
72
|
end
|
49
73
|
|
50
74
|
# Retrive individula character by type
|
@@ -56,7 +80,31 @@ module TTY
|
|
56
80
|
#
|
57
81
|
# @api private
|
58
82
|
def [](type)
|
59
|
-
self.class.characters
|
83
|
+
characters = self.class.characters
|
84
|
+
chars = border.nil? ? characters : characters.merge(border.characters)
|
85
|
+
chars[type] || EMPTY_CHAR
|
86
|
+
end
|
87
|
+
|
88
|
+
# Check if border color is set
|
89
|
+
#
|
90
|
+
# @return [Boolean]
|
91
|
+
#
|
92
|
+
# @api public
|
93
|
+
def color?
|
94
|
+
border && border.style
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set color on characters
|
98
|
+
#
|
99
|
+
# @param [Symbol] color
|
100
|
+
#
|
101
|
+
# @param [Array[String]] array of strings
|
102
|
+
#
|
103
|
+
# @return [Array[String]]
|
104
|
+
#
|
105
|
+
# @api public
|
106
|
+
def self.set_color(color, *strings)
|
107
|
+
strings.map { |string| TTY.terminal.color.set(string, color) }
|
60
108
|
end
|
61
109
|
|
62
110
|
# A line spanning all columns marking top of a table.
|
@@ -83,7 +131,15 @@ module TTY
|
|
83
131
|
#
|
84
132
|
# @api private
|
85
133
|
def row_line
|
86
|
-
|
134
|
+
right_char = self['right']
|
135
|
+
left_char = self['left']
|
136
|
+
center_char = self['center']
|
137
|
+
|
138
|
+
if color?
|
139
|
+
right_char, center_char, left_char = Border.set_color(border.style, right_char, center_char, left_char)
|
140
|
+
end
|
141
|
+
|
142
|
+
result = left_char + row.join(center_char) + right_char
|
87
143
|
result.empty? ? nil : result
|
88
144
|
end
|
89
145
|
|
@@ -106,10 +162,14 @@ module TTY
|
|
106
162
|
# @api private
|
107
163
|
def render(type)
|
108
164
|
type = type.to_s
|
109
|
-
|
110
|
-
|
111
|
-
self["#{type}
|
112
|
-
self["#{type}
|
165
|
+
border_char = self[type]
|
166
|
+
line = render_line(border_char,
|
167
|
+
self["#{type}_left"] || border_char,
|
168
|
+
self["#{type}_right"] || border_char,
|
169
|
+
self["#{type}_mid"])
|
170
|
+
|
171
|
+
line = Border.set_color(border.style, line) if color?
|
172
|
+
line
|
113
173
|
end
|
114
174
|
|
115
175
|
# Generate a border string
|