console_table 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +176 -6
- data/console_table.gemspec +2 -1
- data/console_table_screenshot.png +0 -0
- data/lib/console_table.rb +7 -6
- data/test/test_console_table.rb +65 -0
- metadata +16 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f4ac113386a891b3e7d95fa64d700214eba8798
|
4
|
+
data.tar.gz: 6f0979982d1a0e0996312a999b020c7f253bee8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0c0ccc7c271858afebdaa23bae2700d46fcf2b5f213815373685160b7ff8f50d5154bf22f0b23a33b39981d90d1462aa09574f6563308a5a8f6f7ed69c94e1b
|
7
|
+
data.tar.gz: 0d25ee5db8423d23545a950baeff579a4c68f0c57f2b33fbe1f8f1f5618ddf99c4c080dc27469d64eb313dc168ff005cf1f70ec661f7bc5597a8c77573450085
|
data/README.md
CHANGED
@@ -1,10 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# ConsoleTable
|
2
2
|
|
3
|
-
|
3
|
+
ConsoleTable is a helper class that allows you to print data to a console in a clean, table-like fashion. It's intended for use
|
4
|
+
in commandline applications with information-dense output. It checks your terminal window size (or COLUMNS environment variable) to ensure
|
5
|
+
your data will fit, allows you to define table column sizes, and then just supply the ConsoleTable instance with data which will be
|
6
|
+
truncated or padded as needed to fit your specifications.
|
4
7
|
|
5
|
-
|
8
|
+
It can be used to generate output similar to this screenshot:
|
9
|
+
|
10
|
+
![image](console_table_screenshot.png =700x)
|
11
|
+
|
12
|
+
You're able to specify left/right/center text justification, headers, footers, colors, and most importantly different sizes including exact character widths, screen percentages, and `*` for whatever is left. If the window resizes the class will notice and output all new lines with recalculated locations (previous lines are not re-printed).
|
6
13
|
|
7
|
-
TODO: Write a gem description
|
8
14
|
|
9
15
|
## Installation
|
10
16
|
|
@@ -22,11 +28,175 @@ Or install it yourself as:
|
|
22
28
|
|
23
29
|
## Usage
|
24
30
|
|
25
|
-
|
31
|
+
ConsoleTable needs a lot of information to get going, and it can be somewhat awkward to work with.
|
32
|
+
|
33
|
+
First, we need to define the layout of our table. This consists of the exact order of the columns we want, their identifiers, titles, and sizes. Because we want to specify order, the layout config is an array, and each element of the array is a hash of config values for the column that element of the array defines. For example:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
table_config = [
|
37
|
+
{:key=>:name, :size=>15, :title=>"Name"},
|
38
|
+
{:key=>:birthday, :size=>8, :title=>"DOB"},
|
39
|
+
{:key=>:nickname, :size=>0.3, :title=>"Nickname(s)"},
|
40
|
+
{:key=>:motto, :size=>"*", :title=>"Motto"},
|
41
|
+
]
|
42
|
+
|
43
|
+
ConsoleTable.define(table_config) do |table|
|
44
|
+
#Print data to the table here
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
Here we've defined a table with four columns, a Name, DOB, Nickname, and Motto. As we defined the details of the columns, by using an array we also defined their order.
|
49
|
+
|
50
|
+
* The Name column is exactly 15 characters wide, meaning that any data printed into that column will be right-padded with spaces to take up 15 characters, or if the name is longer than 15 characters it will be truncated.
|
51
|
+
* Next is the DOB, this is another field that's exactly 8 characters.
|
52
|
+
* After that is the Nickname, which has a size of 0.3, or 30%. This column will take 30% of the available space in the window, but will never encroach on space allocated to exact-character sizes like DOB or Name.
|
53
|
+
* Last is Motto, whose size is simply `"*"`. The `"*"` is the default size as well, so the entire `:size` could have been left out of this column definition. `"*"` means to consume whatever is left of the window. You can have multiple `"*"` entries, and the available space will be divided among them equally.
|
54
|
+
|
55
|
+
Percentages and `*` sizes have no minimums, meaning they may not appear at all if the window is too small. In this case, we have a table whose first column is 15 characters and whose second column is 8 characters. The remaining columns will only appear if there is room, and there will be spaces between all four columns, so three spaces separating. Thus, your window must be 15+8+3=26 characters wide or an exception will be thrown.
|
56
|
+
|
57
|
+
Once we have our table, we must print to it. Printing a line of data means supplying the table with a `Hash` whose keys match the values for `:key` in the column config. So for example, we might do:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
ConsoleTable.define(table_config) do |table|
|
61
|
+
table.print({
|
62
|
+
:name=>"Rod",
|
63
|
+
:birthday=>"04-14-80",
|
64
|
+
:nickname=>"Chainsaw",
|
65
|
+
:motto=>"It works on my machine"
|
66
|
+
})
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
If we run this in a console exactly 80 characters wide, the result is:
|
71
|
+
|
72
|
+
```
|
73
|
+
===============================================================================
|
74
|
+
Name DOB Nickname(s) Motto
|
75
|
+
-------------------------------------------------------------------------------
|
76
|
+
Rod 04-14-80 Chainsaw It works on my machine
|
77
|
+
===============================================================================
|
78
|
+
```
|
79
|
+
|
80
|
+
We can specify justification options for columns as well, and even overwrite them when we supply row data, simply by using `Hash`es instead of `String`s for the values. For example:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
table_config = [
|
84
|
+
{:key=>:name, :size=>15, :title=>"Name"},
|
85
|
+
{:key=>:birthday, :size=>8, :title=>"DOB"},
|
86
|
+
{:key=>:nickname, :size=>0.3, :title=>"Nickname(s)", :justify=>:center},
|
87
|
+
{:key=>:motto, :size=>"*", :title=>"Motto", :justify=>:right},
|
88
|
+
]
|
89
|
+
|
90
|
+
ConsoleTable.define(table_config) do |table|
|
91
|
+
table.print({
|
92
|
+
:name=>"Rod",
|
93
|
+
:birthday=>"04-14-80",
|
94
|
+
:nickname=>{:text=>"Chainsaw", :justify=>:left},
|
95
|
+
:motto=>"It works on my machine"
|
96
|
+
})
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
This will output:
|
101
|
+
|
102
|
+
```
|
103
|
+
===============================================================================
|
104
|
+
Name DOB Nickname(s) Motto
|
105
|
+
-------------------------------------------------------------------------------
|
106
|
+
Rod 04-14-80 Chainsaw It works on my machine
|
107
|
+
===============================================================================
|
108
|
+
```
|
109
|
+
|
110
|
+
Notice how the Nickname column specifies that the justification will be centered, but when we actually output the data we say `{:text=>"Chainsaw", :justify=>:left}` thus overriding the justification to be left. As a result, the header name is centered, but the data is left-aligned. In the case of motto, we set the justification to the right-aligned, but never override it, so both the column header and the data itself are right-aligned.
|
111
|
+
|
112
|
+
There are lots of different supported options for outputting the row data elements, here's a pretty comprehensive example and it's output
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
table_config = [
|
116
|
+
{:key=>:name, :size=>15, :title=>"Name"},
|
117
|
+
{:key=>:birthday, :size=>8, :title=>"DOB"},
|
118
|
+
{:key=>:nickname, :size=>0.3, :title=>"Nickname(s)", :justify=>:center},
|
119
|
+
{:key=>:motto, :size=>"*", :title=>"Motto", :justify=>:right},
|
120
|
+
]
|
121
|
+
|
122
|
+
ConsoleTable.define(table_config) do |table|
|
123
|
+
table.print({
|
124
|
+
:name=>{:text=>"Rod", :highlight=>{:regex=>/[A-Z]/, :color=>:red},
|
125
|
+
:birthday=>{text: "04-14-80", :color=>:blue},
|
126
|
+
:nickname=>{:text=>"Chainsaw", :justify=>:left},
|
127
|
+
: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}
|
128
|
+
})
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
will output
|
133
|
+
|
134
|
+
```
|
135
|
+
===============================================================================
|
136
|
+
Name DOB Nickname(s) Motto
|
137
|
+
-------------------------------------------------------------------------------
|
138
|
+
Rod 04-14-80 Chainsaw This is a very long motto, I don't...
|
139
|
+
```
|
140
|
+
|
141
|
+
Due to limitations of this readme format, you'll have to take my word for it that the capital letters in the Name are highlighted Red, and the DOB is blue.
|
142
|
+
|
143
|
+
You can also add a title and a footer to the table, or indent the entire table within the window using different options. Again, here's another example that should more-or-less speak for itself.
|
144
|
+
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
require 'console_table'
|
148
|
+
require 'terminfo'
|
149
|
+
|
150
|
+
puts TermInfo.screen_columns
|
151
|
+
|
152
|
+
table_config = [
|
153
|
+
{:key=>:title, :size=>15, :title=>"Movie Title"},
|
154
|
+
{:key=>:name, :size=>15, :title=>"Name"},
|
155
|
+
{:key=>:release_date, :size=>8, :title=>"Release Date Too Long"},
|
156
|
+
{:key=>:tagline, :size=>"*", :title=>"Motto", :justify=>:right},
|
157
|
+
]
|
158
|
+
|
159
|
+
ConsoleTable.define(table_config, :left_margin=>5, :right_margin=>10, :title=>"Movie Killers") do |table|
|
160
|
+
table.print({
|
161
|
+
:title=>{:text=>"Friday the 13th", :highlight=>{:regex=>/[A-Z]/, :color=>:red}},
|
162
|
+
:name=>{:text=>"Jason", :justify=>:left},
|
163
|
+
:release_date=>{text: "05-09-80", :color=>:blue},
|
164
|
+
:tagline=>{:text=>"They were warned...They are doomed...And on Friday the 13th, nothing will save them.", :ellipsize=>true}
|
165
|
+
})
|
166
|
+
|
167
|
+
table.print({
|
168
|
+
:title=>{:text=>"Halloween", :highlight=>{:regex=>/[A-Z]/, :color=>:red}, :background=>:orange},
|
169
|
+
:name=>{:text=>"Michael Meyers", :justify=>:left},
|
170
|
+
:release_date=>{text: "10-25-80", :color=>:blue},
|
171
|
+
:tagline=>{:text=>"Everyone is entitled to one good scare", :ellipsize=>true}
|
172
|
+
})
|
173
|
+
|
174
|
+
table.add_footer("This is just a line of footer text")
|
175
|
+
table.add_footer("This is a second footer with \nlots of \nlinebreaks\n in it.")
|
176
|
+
end
|
177
|
+
```
|
178
|
+
|
179
|
+
|
180
|
+
```
|
181
|
+
=================================================================
|
182
|
+
Movie Killers
|
183
|
+
Movie Title Name Release Motto
|
184
|
+
-----------------------------------------------------------------
|
185
|
+
Friday the 13th Jason 05-09-80 They were warned...Th...
|
186
|
+
Halloween Michael Meyers 10-25-80 Everyone is entitled ...
|
187
|
+
-----------------------------------------------------------------
|
188
|
+
This is just a line of footer text
|
189
|
+
This is a second footer with
|
190
|
+
lots of
|
191
|
+
linebreaks
|
192
|
+
in it.
|
193
|
+
=================================================================
|
194
|
+
```
|
195
|
+
|
26
196
|
|
27
197
|
## Contributing
|
28
198
|
|
29
|
-
1. Fork it ( http://github.com
|
199
|
+
1. Fork it ( http://github.com/rodhilton/console_table/fork )
|
30
200
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
201
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
202
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/console_table.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "console_table"
|
7
|
-
spec.version = "0.0.
|
7
|
+
spec.version = "0.0.5"
|
8
8
|
spec.authors = ["Rod Hilton"]
|
9
9
|
spec.email = ["consoletable@rodhilton.com"]
|
10
10
|
spec.summary = %q{Simplifies printing tables of information to commandline consoles}
|
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency 'minitest', '~> 5.5'
|
23
23
|
|
24
24
|
spec.add_runtime_dependency 'colorize', '~> 0.7'
|
25
|
+
spec.add_runtime_dependency 'ruby-terminfo', '~> 0.1'
|
25
26
|
end
|
Binary file
|
data/lib/console_table.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'colorize'
|
2
|
+
require 'terminfo'
|
2
3
|
|
3
4
|
class ConsoleTable
|
4
5
|
|
@@ -47,7 +48,7 @@ class ConsoleTable
|
|
47
48
|
|
48
49
|
@column_widths.each_with_index do |column, i|
|
49
50
|
justify = column[:justify] || :left
|
50
|
-
title = column[:title].strip
|
51
|
+
title = (column[:title] || column[:key].to_s.capitalize).strip
|
51
52
|
@out.print format(column[:size], title, false, justify)
|
52
53
|
@out.print " " if i < @column_widths.size-1
|
53
54
|
end
|
@@ -61,7 +62,7 @@ class ConsoleTable
|
|
61
62
|
def add_footer(line)
|
62
63
|
lines = line.split("\n")
|
63
64
|
lines.each do |l|
|
64
|
-
@footer_lines << l.strip unless l.nil? or l.uncolorize.strip
|
65
|
+
@footer_lines << l.strip unless l.nil? or l.uncolorize.strip == ""
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
@@ -171,10 +172,10 @@ class ConsoleTable
|
|
171
172
|
begin
|
172
173
|
total_width = TermInfo.screen_columns
|
173
174
|
rescue => ex
|
174
|
-
total_width = ENV["COLUMNS"].to_i ||
|
175
|
+
total_width = ENV["COLUMNS"].to_i || 79
|
175
176
|
end
|
176
177
|
|
177
|
-
keys = @original_column_layout.collect { |d| d[:key] }.uniq
|
178
|
+
keys = @original_column_layout.reject{|d| d[:key].nil?}.collect { |d| d[:key] }.uniq
|
178
179
|
if keys.length < @original_column_layout.length
|
179
180
|
raise("ConsoleTable configuration invalid, same key defined more than once")
|
180
181
|
end
|
@@ -196,7 +197,7 @@ class ConsoleTable
|
|
196
197
|
end
|
197
198
|
|
198
199
|
percent_available = 1 - percent_used
|
199
|
-
stars = @original_column_layout.collect { |x| x[:size] }.find_all { |x| x.is_a? String }
|
200
|
+
stars = @original_column_layout.collect { |x| x[:size] or x[:size].nil?}.find_all { |x| x.is_a? String }
|
200
201
|
num_stars = [stars.length, 1].max
|
201
202
|
percent_for_stars = percent_available.to_f / num_stars
|
202
203
|
|
@@ -205,7 +206,7 @@ class ConsoleTable
|
|
205
206
|
@column_widths << column_config #As-is when integer
|
206
207
|
elsif column_config[:size].is_a? Float
|
207
208
|
@column_widths << column_config.merge({:size => (column_config[:size]*available).floor})
|
208
|
-
elsif column_config[:size].is_a?(String) && column_config[:size] == "*"
|
209
|
+
elsif column_config[:size].nil? or column_config[:size].is_a?(String) && column_config[:size] == "*"
|
209
210
|
@column_widths << column_config.merge({:size => (percent_for_stars*available).floor})
|
210
211
|
else
|
211
212
|
raise("ConsoleTable configuration invalid, '#{column_config[:size]}' is not a valid size")
|
data/test/test_console_table.rb
CHANGED
@@ -144,6 +144,60 @@ Row 2, Column 1 Row 2, Column 1 Row 2, Column 3
|
|
144
144
|
assert_output_equal expected, @mock_out.string
|
145
145
|
end
|
146
146
|
|
147
|
+
def test_no_size_assumed_to_be_star
|
148
|
+
ENV["COLUMNS"] = "40"
|
149
|
+
|
150
|
+
commit_table_config = [
|
151
|
+
{:key=>:col1, :title=>"Column 1"},
|
152
|
+
{:key=>:col2, :title=>"Column 2"},
|
153
|
+
]
|
154
|
+
|
155
|
+
ConsoleTable.define(commit_table_config, :output=>@mock_out) do |table|
|
156
|
+
table.print({
|
157
|
+
:col1 => "Row 1, Column 1",
|
158
|
+
:col2 => "Row 1, Column 2",
|
159
|
+
})
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
expected=<<-END
|
164
|
+
===============================================================================
|
165
|
+
Column 1 Column 2
|
166
|
+
-------------------------------------------------------------------------------
|
167
|
+
Row 1, Column 1 Row 1, Column 2
|
168
|
+
===============================================================================
|
169
|
+
END
|
170
|
+
|
171
|
+
assert_output_equal expected, @mock_out.string
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_no_name_defaulted_to_capitalize_of_key_name
|
175
|
+
ENV["COLUMNS"] = "40"
|
176
|
+
|
177
|
+
commit_table_config = [
|
178
|
+
{:key=>:col1},
|
179
|
+
{:key=>:col2},
|
180
|
+
]
|
181
|
+
|
182
|
+
ConsoleTable.define(commit_table_config, :output=>@mock_out) do |table|
|
183
|
+
table.print({
|
184
|
+
:col1 => "Row 1, Column 1",
|
185
|
+
:col2 => "Row 1, Column 2",
|
186
|
+
})
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
expected=<<-END
|
191
|
+
===============================================================================
|
192
|
+
Col1 Col2
|
193
|
+
-------------------------------------------------------------------------------
|
194
|
+
Row 1, Column 1 Row 1, Column 2
|
195
|
+
===============================================================================
|
196
|
+
END
|
197
|
+
|
198
|
+
assert_output_equal expected, @mock_out.string
|
199
|
+
end
|
200
|
+
|
147
201
|
def test_can_combine_percentages_fixed_and_stars
|
148
202
|
ENV["COLUMNS"] = "160"
|
149
203
|
|
@@ -235,6 +289,17 @@ Row 2, Column 1 Row 2, Column 2 Row Row 2, Column 4
|
|
235
289
|
assert_raises(RuntimeError) { ConsoleTable.define(commit_table_config) }
|
236
290
|
end
|
237
291
|
|
292
|
+
def test_wont_allow_columns_with_no_key_name
|
293
|
+
ENV["COLUMNS"] = "50"
|
294
|
+
|
295
|
+
commit_table_config = [
|
296
|
+
{:key=>:col1, :size=>20, :title=>"Column 1"},
|
297
|
+
{:size=>20, :title=>"Column 2"},
|
298
|
+
]
|
299
|
+
|
300
|
+
assert_raises(RuntimeError) { ConsoleTable.define(commit_table_config) }
|
301
|
+
end
|
302
|
+
|
238
303
|
def test_can_truncate_output
|
239
304
|
ENV["COLUMNS"] = "100"
|
240
305
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: console_table
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rod Hilton
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: ruby-terminfo
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.1'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.1'
|
83
97
|
description: Allows developers to define tables with specifically-sized columns, which
|
84
98
|
can then have entries printed to them that are automatically formatted, truncated,
|
85
99
|
and padded to fit in the console window.
|
@@ -95,6 +109,7 @@ files:
|
|
95
109
|
- README.md
|
96
110
|
- Rakefile
|
97
111
|
- console_table.gemspec
|
112
|
+
- console_table_screenshot.png
|
98
113
|
- lib/console_table.rb
|
99
114
|
- test/test_console_table.rb
|
100
115
|
- todo.txt
|