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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f72bfb44646e954c27cf46a4b3b3f4d50c629b0
4
- data.tar.gz: 23402eb6500112776e41f43a988c0340552c1b65
3
+ metadata.gz: 0f4ac113386a891b3e7d95fa64d700214eba8798
4
+ data.tar.gz: 6f0979982d1a0e0996312a999b020c7f253bee8f
5
5
  SHA512:
6
- metadata.gz: 3fb568ca9cac5df83ac89909b4988f56b464345ca938600926c84f747d734799ea64967d472420d0a30cc6be66b39afa0a9040d6eb63fd08be6d4a22573526a4
7
- data.tar.gz: d2bdf4a87fe2dbf1a6f62a5a1a9bbfbf60250b28c36d96a480575e76fbe36597b71b275a60a9c700e2edff0bac2d7ff2b683b02f17a83d7cf4cfc8d24c55e5c2
6
+ metadata.gz: e0c0ccc7c271858afebdaa23bae2700d46fcf2b5f213815373685160b7ff8f50d5154bf22f0b23a33b39981d90d1462aa09574f6563308a5a8f6f7ed69c94e1b
7
+ data.tar.gz: 0d25ee5db8423d23545a950baeff579a4c68f0c57f2b33fbe1f8f1f5618ddf99c4c080dc27469d64eb313dc168ff005cf1f70ec661f7bc5597a8c77573450085
data/README.md CHANGED
@@ -1,10 +1,16 @@
1
- #NOTE: I just pulled this code out of a skunkworks project into a gem, readme and tests coming soon. Would not recommend this gem for any critical-path work at this time
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
- # ConsoleTable
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
- TODO: Write usage instructions here
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/<my-github-username>/console_table/fork )
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`)
@@ -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.4"
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.blank?
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 || 150
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")
@@ -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
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