console_table 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -14
- data/console_table.gemspec +2 -1
- data/lib/console_table.rb +209 -195
- data/test/test_console_table.rb +119 -102
- data/todo.txt +2 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1105b617581e5b593f42b5227546ec90e7ceb6f
|
4
|
+
data.tar.gz: 9b720ddaeef699a8d57c00bd8bfecd69b8b5ee2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf00120d77b9255bf7b2f9cd87ec5362ec6d88942034068a60c110d9d3f59f4bf5222b4e7155dc660327f87fa6a934091067de62adc32d9e6464699b3cadcacd
|
7
|
+
data.tar.gz: 996efe76eb5e2c28c5f78faa34e45ed596ae14d633800570bb87a2b3a6e344050b7922787db8a8597a779c052daa725df346d28abf9f3f29e2ef8fc939ff55b8
|
data/README.md
CHANGED
@@ -60,12 +60,12 @@ Once we have our table, we must print to it. Printing a line of data means supp
|
|
60
60
|
|
61
61
|
```ruby
|
62
62
|
ConsoleTable.define(table_config) do |table|
|
63
|
-
table
|
63
|
+
table << {
|
64
64
|
:name=>"Rod",
|
65
65
|
:birthday=>"04-14-80",
|
66
66
|
:nickname=>"Chainsaw",
|
67
67
|
:motto=>"It works on my machine"
|
68
|
-
}
|
68
|
+
}
|
69
69
|
end
|
70
70
|
```
|
71
71
|
|
@@ -90,12 +90,12 @@ table_config = [
|
|
90
90
|
]
|
91
91
|
|
92
92
|
ConsoleTable.define(table_config) do |table|
|
93
|
-
table
|
93
|
+
table << {
|
94
94
|
:name=>"Rod",
|
95
95
|
:birthday=>"04-14-80",
|
96
96
|
:nickname=>{:text=>"Chainsaw", :justify=>:left},
|
97
97
|
:motto=>"It works on my machine"
|
98
|
-
}
|
98
|
+
}
|
99
99
|
end
|
100
100
|
```
|
101
101
|
|
@@ -118,16 +118,16 @@ table_config = [
|
|
118
118
|
{:key=>:name, :size=>15, :title=>"Name"},
|
119
119
|
{:key=>:birthday, :size=>8, :title=>"DOB"},
|
120
120
|
{:key=>:nickname, :size=>0.3, :title=>"Nickname(s)", :justify=>:center},
|
121
|
-
{:key=>:motto, :size=>"*", :title=>"Motto", :justify=>:right}
|
121
|
+
{:key=>:motto, :size=>"*", :title=>"Motto", :justify=>:right}
|
122
122
|
]
|
123
123
|
|
124
124
|
ConsoleTable.define(table_config) do |table|
|
125
|
-
table
|
125
|
+
table << {
|
126
126
|
:name=>{:text=>"Rod", :highlight=>{:regex=>/[A-Z]/, :color=>:red},
|
127
127
|
:birthday=>{text: "04-14-80", :color=>:blue},
|
128
128
|
:nickname=>{:text=>"Chainsaw", :justify=>:left},
|
129
129
|
:motto=>{:text=>"This is a very long motto, I don't mind if it gets cut off but I'd like it to indicate as such with ellipses", :ellipsize=>true}
|
130
|
-
}
|
130
|
+
}
|
131
131
|
end
|
132
132
|
```
|
133
133
|
|
@@ -156,19 +156,19 @@ table_config = [
|
|
156
156
|
]
|
157
157
|
|
158
158
|
ConsoleTable.define(table_config, :left_margin=>5, :right_margin=>10, :title=>"Movie Killers") do |table|
|
159
|
-
table
|
159
|
+
table << {
|
160
160
|
:title=>{:text=>"Friday the 13th", :highlight=>{:regex=>/[A-Z]/, :color=>:red}},
|
161
161
|
:name=>{:text=>"Jason's Mom", :justify=>:left},
|
162
162
|
:release_date=>{text: "05-09-80", :color=>:blue},
|
163
163
|
:tagline=>{:text=>"They were warned...They are doomed...And on Friday the 13th, nothing will save them.", :ellipsize=>true}
|
164
|
-
}
|
164
|
+
}
|
165
165
|
|
166
|
-
table
|
166
|
+
table << {
|
167
167
|
:title=>{:text=>"Halloween", :highlight=>{:regex=>/[A-Z]/, :color=>:red}, :background=>:orange},
|
168
168
|
:name=>{:text=>"Michael Meyers", :justify=>:left},
|
169
169
|
:release_date=>{text: "10-25-80", :color=>:blue},
|
170
170
|
:tagline=>{:text=>"Everyone is entitled to one good scare", :ellipsize=>true}
|
171
|
-
}
|
171
|
+
}
|
172
172
|
|
173
173
|
table << {
|
174
174
|
:title=>{:text=>"Nightmare on Elm St.", :highlight=>{:regex=>/[A-Z]/, :color=>:red}, :background=>:orange},
|
@@ -179,8 +179,8 @@ ConsoleTable.define(table_config, :left_margin=>5, :right_margin=>10, :title=>"M
|
|
179
179
|
|
180
180
|
table << ["Hellraiser", "Pinhead", "9-18-87", "Demon to some. Angel to others."]
|
181
181
|
|
182
|
-
table.
|
183
|
-
table.
|
182
|
+
table.footer << "This is just a line of footer text"
|
183
|
+
table.footer << "This is a second footer with \nlots of \nlinebreaks in it."
|
184
184
|
end
|
185
185
|
```
|
186
186
|
|
@@ -202,7 +202,7 @@ end
|
|
202
202
|
=================================================================
|
203
203
|
```
|
204
204
|
|
205
|
-
Note the alternative method of calling
|
205
|
+
Note the alternative method of calling `<<` where you can supply an Array instead of a hash, and ConsoleTable will infer from the array order which value goes in what column
|
206
206
|
|
207
207
|
## Contributing
|
208
208
|
|
data/console_table.gemspec
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'console_table'
|
4
5
|
|
5
6
|
Gem::Specification.new do |spec|
|
6
7
|
spec.name = "console_table"
|
7
|
-
spec.version =
|
8
|
+
spec.version = ConsoleTable::VERSION
|
8
9
|
spec.authors = ["Rod Hilton"]
|
9
10
|
spec.email = ["consoletable@rodhilton.com"]
|
10
11
|
spec.summary = %q{Simplifies printing tables of information to commandline consoles}
|
data/lib/console_table.rb
CHANGED
@@ -1,262 +1,276 @@
|
|
1
1
|
require 'colorize'
|
2
2
|
require 'terminfo'
|
3
3
|
|
4
|
-
|
4
|
+
module ConsoleTable
|
5
|
+
VERSION = "0.1.0"
|
5
6
|
|
6
7
|
def self.define(layout, options={}, &block)
|
7
|
-
table =
|
8
|
-
table.print_header
|
8
|
+
table = ConsoleTableClass.new(layout, options)
|
9
|
+
table.send(:print_header)
|
9
10
|
block.call(table)
|
10
|
-
table.print_footer
|
11
|
+
table.send(:print_footer)
|
11
12
|
end
|
12
13
|
|
13
|
-
|
14
|
-
@original_column_layout = column_layout
|
15
|
-
@left_margin = options[:left_margin] || 0
|
16
|
-
@right_margin = options[:right_margin] || 0
|
17
|
-
@out = options[:output] || $stdout
|
18
|
-
@title = options[:title]
|
19
|
-
@set_width = options[:width]
|
14
|
+
class ConsoleTableClass
|
20
15
|
|
21
|
-
|
16
|
+
attr_reader :footer
|
22
17
|
|
23
|
-
|
24
|
-
|
18
|
+
def <<(options)
|
19
|
+
print(options)
|
20
|
+
end
|
25
21
|
|
26
|
-
|
27
|
-
Signal.trap('SIGWINCH', proc { calc_column_widths })
|
28
|
-
end
|
22
|
+
protected
|
29
23
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
24
|
+
def initialize(column_layout, options={})
|
25
|
+
@original_column_layout = column_layout
|
26
|
+
@left_margin = options[:left_margin] || 0
|
27
|
+
@right_margin = options[:right_margin] || 0
|
28
|
+
@out = options[:output] || $stdout
|
29
|
+
@title = options[:title]
|
30
|
+
@set_width = options[:width]
|
34
31
|
|
35
|
-
|
36
|
-
@out.print " "*@left_margin
|
37
|
-
left_side = (@working_width - @title.uncolorize.length)/2
|
38
|
-
right_side = (@working_width - @title.uncolorize.length) - left_side
|
39
|
-
@out.print " "*left_side
|
40
|
-
@out.print @title
|
41
|
-
@out.print " "*right_side
|
42
|
-
@out.print "\n"
|
43
|
-
end
|
44
|
-
end
|
32
|
+
@footer = []
|
45
33
|
|
46
|
-
|
47
|
-
|
48
|
-
@out.print " "*@left_margin
|
34
|
+
@headings_printed = false
|
35
|
+
@count = 0
|
49
36
|
|
50
|
-
|
51
|
-
|
52
|
-
title = (column[:title] || column[:key].to_s.capitalize).strip
|
53
|
-
@out.print format(column[:size], title, false, justify)
|
54
|
-
@out.print " " if i < @column_widths.size-1
|
37
|
+
calc_column_widths
|
38
|
+
Signal.trap('SIGWINCH', proc { calc_column_widths })
|
55
39
|
end
|
56
|
-
@out.print "\n"
|
57
40
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
41
|
+
def print_header()
|
42
|
+
@out.print " " * @left_margin
|
43
|
+
@out.print "=" * @working_width
|
44
|
+
@out.print "\n"
|
62
45
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
46
|
+
if not @title.nil? and @title.length <= @working_width
|
47
|
+
@out.print " "*@left_margin
|
48
|
+
left_side = (@working_width - @title.uncolorize.length)/2
|
49
|
+
right_side = (@working_width - @title.uncolorize.length) - left_side
|
50
|
+
@out.print " "*left_side
|
51
|
+
@out.print @title
|
52
|
+
@out.print " "*right_side
|
53
|
+
@out.print "\n"
|
54
|
+
end
|
67
55
|
end
|
68
|
-
end
|
69
56
|
|
70
|
-
|
71
|
-
|
57
|
+
def print_headings()
|
58
|
+
@headings_printed = true
|
59
|
+
@out.print " "*@left_margin
|
60
|
+
|
61
|
+
@column_widths.each_with_index do |column, i|
|
62
|
+
justify = column[:justify] || :left
|
63
|
+
title = (column[:title] || column[:key].to_s.capitalize).strip
|
64
|
+
@out.print format(column[:size], title, false, justify)
|
65
|
+
@out.print " " if i < @column_widths.size-1
|
66
|
+
end
|
67
|
+
@out.print "\n"
|
72
68
|
|
73
|
-
if should_print_footer
|
74
69
|
@out.print " " * @left_margin
|
75
70
|
@out.print "-" * @working_width
|
76
71
|
@out.print "\n"
|
77
72
|
end
|
78
73
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
74
|
+
def print_footer()
|
75
|
+
footer_lines = []
|
76
|
+
@footer.each do |line|
|
77
|
+
lines = line.split("\n")
|
78
|
+
lines.each do |l|
|
79
|
+
footer_lines << l.strip unless l.nil? or l.uncolorize.strip == ""
|
80
|
+
end
|
85
81
|
end
|
86
|
-
end
|
87
82
|
|
88
|
-
|
89
|
-
@out.print "=" * @working_width
|
90
|
-
@out.print "\n"
|
91
|
-
end
|
83
|
+
should_print_footer = footer_lines.length > 0 && footer_lines.any? { |l| l.uncolorize.length <= @working_width }
|
92
84
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
@out.print format(@working_width, normalize(to_print))
|
98
|
-
elsif to_print.is_a? Hash
|
99
|
-
color = to_print[:color] || :default
|
100
|
-
background = to_print[:background] || :default
|
101
|
-
text = normalize(to_print[:text]) || ""
|
102
|
-
ellipsize = to_print[:ellipsize] || false
|
103
|
-
justify = to_print[:justify] || :left
|
104
|
-
mode = to_print[:mode] || :default
|
105
|
-
|
106
|
-
formatted=format(@working_width, text, ellipsize, justify)
|
107
|
-
if text != :default or background != :default or mode != :default
|
108
|
-
formatted = formatted.colorize(:color => color, :background => background, :mode => mode)
|
85
|
+
if should_print_footer
|
86
|
+
@out.print " " * @left_margin
|
87
|
+
@out.print "-" * @working_width
|
88
|
+
@out.print "\n"
|
109
89
|
end
|
110
|
-
@out.print formatted
|
111
|
-
end
|
112
|
-
|
113
|
-
@out.print "\n"
|
114
|
-
end
|
115
|
-
|
116
|
-
def <<(options)
|
117
|
-
print(options)
|
118
|
-
end
|
119
90
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
91
|
+
footer_lines.each do |line|
|
92
|
+
if line.uncolorize.length <= @working_width
|
93
|
+
@out.print " " * @left_margin
|
94
|
+
@out.print " " * (@working_width - line.uncolorize.length)
|
95
|
+
@out.print line
|
96
|
+
@out.print "\n"
|
97
|
+
end
|
127
98
|
end
|
128
99
|
|
129
|
-
|
100
|
+
@out.print " " * @left_margin
|
101
|
+
@out.print "=" * @working_width
|
102
|
+
@out.print "\n"
|
130
103
|
end
|
131
104
|
|
132
|
-
|
133
|
-
#column order is set, so go through each column and look up values in the incoming options
|
134
|
-
@column_widths.each_with_index do |column, i|
|
135
|
-
to_print = options[column[:key]] || ""
|
136
|
-
justify = column[:justify] || :left
|
137
|
-
if to_print.is_a? String
|
138
|
-
@out.print format(column[:size], normalize(to_print), false, justify)
|
139
|
-
elsif to_print.is_a? Hash
|
140
|
-
color = to_print[:color] || :default
|
141
|
-
background = to_print[:background] || :default
|
142
|
-
text = normalize(to_print[:text]) || ""
|
143
|
-
ellipsize = to_print[:ellipsize] || false
|
144
|
-
highlight = to_print[:highlight]
|
145
|
-
justify = to_print[:justify] || justify #can override
|
146
|
-
mode = to_print[:mode] || :default
|
105
|
+
def print(options)
|
147
106
|
|
148
|
-
|
107
|
+
if (options.is_a? String)
|
108
|
+
print_plain(options)
|
109
|
+
return
|
110
|
+
end
|
149
111
|
|
150
|
-
|
151
|
-
formatted = formatted.colorize(color)
|
152
|
-
end
|
112
|
+
print_headings unless @headings_printed
|
153
113
|
|
154
|
-
|
155
|
-
|
114
|
+
if options.is_a? Array #If an array or something is supplied, infer the order from the heading order
|
115
|
+
munged_options = {}
|
116
|
+
options.each_with_index do |element, i|
|
117
|
+
munged_options[@original_column_layout[i][:key]] = element
|
156
118
|
end
|
157
119
|
|
158
|
-
|
159
|
-
|
120
|
+
options = munged_options
|
121
|
+
end
|
122
|
+
|
123
|
+
@out.print " "*@left_margin
|
124
|
+
#column order is set, so go through each column and look up values in the incoming options
|
125
|
+
@column_widths.each_with_index do |column, i|
|
126
|
+
to_print = options[column[:key]] || ""
|
127
|
+
justify = column[:justify] || :left
|
128
|
+
if to_print.is_a? String
|
129
|
+
@out.print format(column[:size], normalize(to_print), false, justify)
|
130
|
+
elsif to_print.is_a? Hash
|
131
|
+
color = to_print[:color] || :default
|
132
|
+
background = to_print[:background] || :default
|
133
|
+
text = normalize(to_print[:text]) || ""
|
134
|
+
ellipsize = to_print[:ellipsize] || false
|
135
|
+
highlight = to_print[:highlight]
|
136
|
+
justify = to_print[:justify] || justify #can override
|
137
|
+
mode = to_print[:mode] || :default
|
138
|
+
|
139
|
+
formatted=format(column[:size], text, ellipsize, justify)
|
140
|
+
|
141
|
+
if color != :default
|
142
|
+
formatted = formatted.colorize(color)
|
143
|
+
end
|
144
|
+
|
145
|
+
if background != :default
|
146
|
+
formatted = formatted.colorize(:background => background)
|
147
|
+
end
|
148
|
+
|
149
|
+
if mode != :default
|
150
|
+
formatted = formatted.colorize(:mode => mode)
|
151
|
+
end
|
152
|
+
|
153
|
+
unless highlight.nil?
|
154
|
+
highlight_regex = to_print[:highlight][:regex] || /wontbefoundbecauseit'sgobbledygookblahblahblahbah/
|
155
|
+
highlight_color = to_print[:highlight][:color] || :blue
|
156
|
+
highlight_background = to_print[:highlight][:background] || :default
|
157
|
+
|
158
|
+
formatted = formatted.gsub(highlight_regex, '\0'.colorize(:color => highlight_color, :background => highlight_background))
|
159
|
+
end
|
160
|
+
|
161
|
+
@out.print formatted
|
162
|
+
else
|
163
|
+
@out.print format(column[:size], normalize(to_print.to_s))
|
160
164
|
end
|
161
165
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
highlight_background = to_print[:highlight][:background] || :default
|
166
|
+
@out.print " " if i < @column_widths.size-1
|
167
|
+
end
|
168
|
+
@out.print "\n"
|
166
169
|
|
167
|
-
|
168
|
-
|
170
|
+
@count = @count + 1
|
171
|
+
end
|
169
172
|
|
170
|
-
|
173
|
+
def normalize(string)
|
174
|
+
if string.nil?
|
175
|
+
nil
|
171
176
|
else
|
172
|
-
|
177
|
+
string.to_s.gsub(/\s+/, " ").strip #Primarily to remove any tabs or newlines
|
173
178
|
end
|
174
|
-
|
175
|
-
@out.print " " if i < @column_widths.size-1
|
176
179
|
end
|
177
|
-
@out.print "\n"
|
178
180
|
|
179
|
-
|
180
|
-
|
181
|
+
def calc_column_widths()
|
182
|
+
@column_widths = []
|
181
183
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
end
|
189
|
-
end
|
184
|
+
total_width = @set_width
|
185
|
+
begin
|
186
|
+
total_width = TermInfo.screen_columns
|
187
|
+
rescue => ex
|
188
|
+
total_width = ENV["COLUMNS"].to_i || 79
|
189
|
+
end if total_width.nil?
|
190
190
|
|
191
|
-
|
192
|
-
|
191
|
+
keys = @original_column_layout.reject { |d| d[:key].nil? }.collect { |d| d[:key] }.uniq
|
192
|
+
if keys.length < @original_column_layout.length
|
193
|
+
raise("ConsoleTable configuration invalid, same key defined more than once")
|
194
|
+
end
|
193
195
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
total_width = ENV["COLUMNS"].to_i || 79
|
199
|
-
end if total_width.nil?
|
196
|
+
num_spacers = @original_column_layout.length - 1
|
197
|
+
set_sizes = @original_column_layout.collect { |x| x[:size] }.find_all { |x| x.is_a? Integer }
|
198
|
+
used_up = set_sizes.inject(:+) || 0
|
199
|
+
available = total_width - used_up - @left_margin - @right_margin - num_spacers
|
200
200
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
end
|
201
|
+
if available <= 0
|
202
|
+
raise("ConsoleTable configuration invalid, current window is too small to display required sizes")
|
203
|
+
end
|
205
204
|
|
206
|
-
|
207
|
-
|
208
|
-
used_up = set_sizes.inject(:+) || 0
|
209
|
-
available = total_width - used_up - @left_margin - @right_margin - num_spacers
|
205
|
+
percentages = @original_column_layout.collect { |x| x[:size] }.find_all { |x| x.is_a? Float }
|
206
|
+
percent_used = percentages.inject(:+) || 0
|
210
207
|
|
211
|
-
|
212
|
-
|
213
|
-
|
208
|
+
if percent_used > 1.0
|
209
|
+
raise("ConsoleTable configuration invalid, percentages total value greater than 100%")
|
210
|
+
end
|
214
211
|
|
215
|
-
|
216
|
-
|
212
|
+
percent_available = 1 - percent_used
|
213
|
+
stars = @original_column_layout.collect { |x| x[:size] or x[:size].nil? }.find_all { |x| x.is_a? String }
|
214
|
+
num_stars = [stars.length, 1].max
|
215
|
+
percent_for_stars = percent_available.to_f / num_stars
|
216
|
+
|
217
|
+
@original_column_layout.each do |column_config|
|
218
|
+
if column_config[:size].is_a? Integer
|
219
|
+
@column_widths << column_config #As-is when integer
|
220
|
+
elsif column_config[:size].is_a? Float
|
221
|
+
@column_widths << column_config.merge({:size => (column_config[:size]*available).floor})
|
222
|
+
elsif column_config[:size].nil? or column_config[:size].is_a?(String) && column_config[:size] == "*"
|
223
|
+
@column_widths << column_config.merge({:size => (percent_for_stars*available).floor})
|
224
|
+
else
|
225
|
+
raise("ConsoleTable configuration invalid, '#{column_config[:size]}' is not a valid size")
|
226
|
+
end
|
227
|
+
end
|
217
228
|
|
218
|
-
|
219
|
-
raise("ConsoleTable configuration invalid, percentages total value greater than 100%")
|
229
|
+
@working_width = (@column_widths.inject(0) { |res, c| res+c[:size] }) + @column_widths.length - 1
|
220
230
|
end
|
221
231
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
@column_widths << column_config #As-is when integer
|
230
|
-
elsif column_config[:size].is_a? Float
|
231
|
-
@column_widths << column_config.merge({:size => (column_config[:size]*available).floor})
|
232
|
-
elsif column_config[:size].nil? or column_config[:size].is_a?(String) && column_config[:size] == "*"
|
233
|
-
@column_widths << column_config.merge({:size => (percent_for_stars*available).floor})
|
232
|
+
def format(length, text, ellipsize=false, justify=:left)
|
233
|
+
if text.length > length
|
234
|
+
if ellipsize
|
235
|
+
text[0, length-3] + '...'
|
236
|
+
else
|
237
|
+
text[0, length]
|
238
|
+
end
|
234
239
|
else
|
235
|
-
|
240
|
+
if justify == :right
|
241
|
+
(" "*(length-text.length)) + text
|
242
|
+
elsif justify == :center
|
243
|
+
space = length-text.length
|
244
|
+
left_side = space/2
|
245
|
+
right_side = space - left_side
|
246
|
+
(" " * left_side) + text + (" "*right_side)
|
247
|
+
else #assume left
|
248
|
+
text + (" "*(length-text.length))
|
249
|
+
end
|
236
250
|
end
|
237
251
|
end
|
238
252
|
|
239
|
-
|
240
|
-
|
253
|
+
def print_plain(to_print)
|
254
|
+
@out.print " "*@left_margin
|
241
255
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
text[
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
else #assume left
|
258
|
-
text + (" "*(length-text.length))
|
256
|
+
if to_print.is_a? String
|
257
|
+
@out.print format(@working_width, normalize(to_print))
|
258
|
+
elsif to_print.is_a? Hash
|
259
|
+
color = to_print[:color] || :default
|
260
|
+
background = to_print[:background] || :default
|
261
|
+
text = normalize(to_print[:text]) || ""
|
262
|
+
ellipsize = to_print[:ellipsize] || false
|
263
|
+
justify = to_print[:justify] || :left
|
264
|
+
mode = to_print[:mode] || :default
|
265
|
+
|
266
|
+
formatted=format(@working_width, text, ellipsize, justify)
|
267
|
+
if text != :default or background != :default or mode != :default
|
268
|
+
formatted = formatted.colorize(:color => color, :background => background, :mode => mode)
|
269
|
+
end
|
270
|
+
@out.print formatted
|
259
271
|
end
|
272
|
+
|
273
|
+
@out.print "\n"
|
260
274
|
end
|
261
275
|
end
|
262
276
|
end
|
data/test/test_console_table.rb
CHANGED
@@ -18,15 +18,15 @@ class ConsoleTableTest < Minitest::Test
|
|
18
18
|
]
|
19
19
|
|
20
20
|
ConsoleTable.define(table_config, :width=> 100, :output=>@mock_out) do |table|
|
21
|
-
table
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
table << {
|
22
|
+
:col1 => "Row 1, Column 1",
|
23
|
+
:col2 => "Row 1, Column 2"
|
24
|
+
}
|
25
25
|
|
26
|
-
table
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
table << {
|
27
|
+
:col1 => "Row 2, Column 1",
|
28
|
+
:col2 => "Row 2, Column 1"
|
29
|
+
}
|
30
30
|
end
|
31
31
|
|
32
32
|
#2345678901234567890##2345678901234567890
|
@@ -109,15 +109,12 @@ Row 1, Column 1 Row 1, Column 2
|
|
109
109
|
]
|
110
110
|
|
111
111
|
ConsoleTable.define(table_config, :width=> 100, :output=>@mock_out) do |table|
|
112
|
-
table
|
113
|
-
|
114
|
-
|
115
|
-
|
112
|
+
table << {
|
113
|
+
:col1 => "Row 1, Column 1",
|
114
|
+
:col2 => "Row 1, Column 2"
|
115
|
+
}
|
116
116
|
|
117
|
-
table
|
118
|
-
:col1 => "Row 2, Column 1",
|
119
|
-
:col2 => "Row 2, Column 1"
|
120
|
-
})
|
117
|
+
table << ["Row 2, Column 1", "Row 2, Column 1"]
|
121
118
|
end
|
122
119
|
|
123
120
|
expected=<<-END
|
@@ -139,15 +136,15 @@ Row 2, Column 1 Row 2, Column 1
|
|
139
136
|
]
|
140
137
|
|
141
138
|
ConsoleTable.define(table_config, :width=> 100, :output=>@mock_out) do |table|
|
142
|
-
table
|
143
|
-
|
144
|
-
|
145
|
-
|
139
|
+
table << {
|
140
|
+
:col1 => "Row 1, Column 1",
|
141
|
+
:col2 => "Row 1, Column 2"
|
142
|
+
}
|
146
143
|
|
147
|
-
table
|
148
|
-
|
149
|
-
|
150
|
-
|
144
|
+
table << {
|
145
|
+
:col1 => "Row 2, Column 1",
|
146
|
+
:col2 => "Row 2, Column 1"
|
147
|
+
}
|
151
148
|
end
|
152
149
|
|
153
150
|
expected=<<-END
|
@@ -170,17 +167,17 @@ Row 2, Column 1 Row 2, Column 1
|
|
170
167
|
]
|
171
168
|
|
172
169
|
ConsoleTable.define(table_config, :width=> 100, :output=>@mock_out) do |table|
|
173
|
-
table
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
170
|
+
table << {
|
171
|
+
:col1 => "Row 1, Column 1",
|
172
|
+
:col2 => "Row 1, Column 2",
|
173
|
+
:col3 => "Row 1, Column 3"
|
174
|
+
}
|
178
175
|
|
179
|
-
table
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
176
|
+
table << {
|
177
|
+
:col1 => "Row 2, Column 1",
|
178
|
+
:col2 => "Row 2, Column 1",
|
179
|
+
:col3 => "Row 2, Column 3"
|
180
|
+
}
|
184
181
|
end
|
185
182
|
|
186
183
|
expected=<<-END
|
@@ -202,10 +199,10 @@ Row 2, Column 1 Row 2, Column 1 Row 2, Column 3
|
|
202
199
|
]
|
203
200
|
|
204
201
|
ConsoleTable.define(table_config, :width=> 40, :output=>@mock_out) do |table|
|
205
|
-
table
|
206
|
-
|
207
|
-
|
208
|
-
|
202
|
+
table << {
|
203
|
+
:col1 => "Row 1, Column 1",
|
204
|
+
:col2 => "Row 1, Column 2",
|
205
|
+
}
|
209
206
|
|
210
207
|
end
|
211
208
|
|
@@ -227,10 +224,10 @@ Row 1, Column 1 Row 1, Column 2
|
|
227
224
|
]
|
228
225
|
|
229
226
|
ConsoleTable.define(table_config, :width=> 40, :output=>@mock_out) do |table|
|
230
|
-
table
|
231
|
-
|
232
|
-
|
233
|
-
|
227
|
+
table << {
|
228
|
+
:col1 => "Row 1, Column 1",
|
229
|
+
:col2 => "Row 1, Column 2",
|
230
|
+
}
|
234
231
|
|
235
232
|
end
|
236
233
|
|
@@ -257,25 +254,25 @@ Row 1, Column 1 Row 1, Column 2
|
|
257
254
|
]
|
258
255
|
|
259
256
|
ConsoleTable.define(table_config, :width=> 160, :output=>@mock_out) do |table|
|
260
|
-
table
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
table
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
257
|
+
table << {
|
258
|
+
:col1 => "Row 1, Column 1",
|
259
|
+
:col2 => "Row 1, Column 2",
|
260
|
+
:col3 => "Row 1, Column 3",
|
261
|
+
:col4 => "Row 1, Column 4",
|
262
|
+
:col5 => "Row 1, Column 5",
|
263
|
+
:col6 => "Row 1, Column 6",
|
264
|
+
:col7 => "Row 1, Column 7",
|
265
|
+
}
|
266
|
+
|
267
|
+
table << {
|
268
|
+
:col1 => "Row 2, Column 1",
|
269
|
+
:col2 => "Row 2, Column 2",
|
270
|
+
:col3 => "Row 2, Column 3",
|
271
|
+
:col4 => "Row 2, Column 4",
|
272
|
+
:col5 => "Row 2, Column 5",
|
273
|
+
:col6 => "Row 2, Column 6",
|
274
|
+
:col7 => "Row 2, Column 7",
|
275
|
+
}
|
279
276
|
end
|
280
277
|
|
281
278
|
expected=<<-END
|
@@ -341,17 +338,14 @@ Row 2, Column 1 Row 2, Column 2 Row Row 2, Column 4
|
|
341
338
|
]
|
342
339
|
|
343
340
|
ConsoleTable.define(table_config, :width=> 100, :output=>@mock_out) do |table|
|
344
|
-
table
|
345
|
-
:col1 => "This is short"
|
346
|
-
})
|
341
|
+
table << ["This is short"]
|
347
342
|
|
348
|
-
table
|
349
|
-
|
350
|
-
|
343
|
+
table << {:col1=>"This is way too long and it needs to get cut off"}
|
344
|
+
|
345
|
+
table << [
|
346
|
+
{:text=>"This is way too long and it needs to get cut off", :ellipsize=>true}
|
347
|
+
]
|
351
348
|
|
352
|
-
table.print({
|
353
|
-
:col1 => {:text=>"This is way too long and it needs to get cut off", :ellipsize=>true}
|
354
|
-
})
|
355
349
|
end
|
356
350
|
|
357
351
|
expected=<<-END
|
@@ -375,23 +369,23 @@ This is way too l...
|
|
375
369
|
]
|
376
370
|
|
377
371
|
ConsoleTable.define(table_config, :width=> 100, :output=>@mock_out) do |table|
|
378
|
-
table
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
table
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
table
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
372
|
+
table << {
|
373
|
+
:col1 => "Short1",
|
374
|
+
:col2 => "Short2",
|
375
|
+
:col3 => "Short3"
|
376
|
+
}
|
377
|
+
|
378
|
+
table << {
|
379
|
+
:col1 => {text: "Short1"},
|
380
|
+
:col2 => {text: "Short2"},
|
381
|
+
:col3 => {text: "Short3"}
|
382
|
+
}
|
383
|
+
|
384
|
+
table << {
|
385
|
+
:col1 => {text: "Short1", :justify=>:center},
|
386
|
+
:col2 => {text: "Short2", :justify=>:right},
|
387
|
+
:col3 => {text: "Short3", :justify=>:left}
|
388
|
+
}
|
395
389
|
end
|
396
390
|
|
397
391
|
expected=<<-END
|
@@ -417,19 +411,19 @@ Short1 Short2 Short3
|
|
417
411
|
]
|
418
412
|
|
419
413
|
ConsoleTable.define(table_config, :left_margin=>5, :right_margin=>10, :width=>80, :title=>"Movie Killers", :output=>@mock_out) do |table|
|
420
|
-
table
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
table
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
414
|
+
table << {
|
415
|
+
:title=>{:text=>"Friday the 13th"},
|
416
|
+
:name=>{:text=>"Jason's Mom", :justify=>:left},
|
417
|
+
:release_date=>{text: "05-09-80"},
|
418
|
+
:tagline=>{:text=>"They were warned...They are doomed...And on Friday the 13th, nothing will save them.", :ellipsize=>true}
|
419
|
+
}
|
420
|
+
|
421
|
+
table << {
|
422
|
+
:title=>{:text=>"Halloween"},
|
423
|
+
:name=>{:text=>"Michael Meyers", :justify=>:left},
|
424
|
+
:release_date=>{text: "10-25-80"},
|
425
|
+
:tagline=>{:text=>"Everyone is entitled to one good scare", :ellipsize=>true}
|
426
|
+
}
|
433
427
|
|
434
428
|
table << {
|
435
429
|
:title=>{:text=>"Nightmare on Elm St."},
|
@@ -440,8 +434,8 @@ Short1 Short2 Short3
|
|
440
434
|
|
441
435
|
table << ["Hellraiser", "Pinhead", "9-18-87", "Demon to some. Angel to others."]
|
442
436
|
|
443
|
-
table.
|
444
|
-
table.
|
437
|
+
table.footer << "This is just a line of footer text"
|
438
|
+
table.footer << "This is a second footer with \nlots of \nlinebreaks in it."
|
445
439
|
end
|
446
440
|
|
447
441
|
expected=<<-END
|
@@ -464,6 +458,29 @@ Short1 Short2 Short3
|
|
464
458
|
assert_output_equal expected, @mock_out.string
|
465
459
|
end
|
466
460
|
|
461
|
+
def test_printing_a_single_string_does_full_line
|
462
|
+
table_config = [
|
463
|
+
{:key=>:col1, :size=>20, :title=>"Column 1"},
|
464
|
+
{:key=>:col2, :size=>20, :title=>"Column 2"},
|
465
|
+
]
|
466
|
+
|
467
|
+
ConsoleTable.define(table_config, :width=> 100, :output=>@mock_out) do |table|
|
468
|
+
table << "This is just a string, it should ignore columns"
|
469
|
+
end
|
470
|
+
|
471
|
+
expected=<<-END
|
472
|
+
=========================================
|
473
|
+
Column 1 Column 2
|
474
|
+
-----------------------------------------
|
475
|
+
This is just a string, it should ignore c
|
476
|
+
=========================================
|
477
|
+
END
|
478
|
+
|
479
|
+
puts @mock_out.string
|
480
|
+
|
481
|
+
assert_output_equal expected, @mock_out.string
|
482
|
+
end
|
483
|
+
|
467
484
|
private
|
468
485
|
def assert_output_equal(expected, actual)
|
469
486
|
expected_lines = expected.split("\n")
|
data/todo.txt
CHANGED
@@ -1,2 +1,3 @@
|
|
1
1
|
:border=>true on options, uses | instead of " " to space and adds 2 to the spacer count. prepends if true
|
2
|
-
perhaps :border=>:thin, :thick, thin does above, thick also adds a row of --'s between, or even smartly uses +'s for joins
|
2
|
+
perhaps :border=>:thin, :thick, thin does above, thick also adds a row of --'s between, or even smartly uses +'s for joins
|
3
|
+
note the dangerousness of this with the current impl - Total width available is always the screen width, so if you make a table with 2 20 char columns and set a border, where does the final | go? it should go at the end of the 40ish character, but it'd go at the end of the line I think. might not even want to bite this off
|