console_table 0.1.5 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ad359bbbe8957d51f799ac7761138ce6298c242
4
- data.tar.gz: 33e4d6d67e2405a9915d7368b32d572e27f4575a
3
+ metadata.gz: 626c1c75fc83f5be630b35551e96d9bd318f41e5
4
+ data.tar.gz: c7b122ba03999438a6408ea10ac15c3c1dc7adc1
5
5
  SHA512:
6
- metadata.gz: ca996310196d283a334171530e68b93922bff9bf2e4ac5bf2a00870a469f597ebcd8cd3cb9273e21c32add989513808df3e913270a28e3f4398eb00e1ca77414
7
- data.tar.gz: 69d0c16af724898caa200b825b3ea4c0c2fd92fe1809b969649120002f59a662bac0c16c1857c777ebe84a34ca379902da00eda03335eda328976c41dcfae7ae
6
+ metadata.gz: a5711b3beebcd41a3e353d2a3e3b842316e2201320f52a92e69fab8ac95badda818eda8d475c0cbfd6c03e285b9d18d2f6c05cd71db12300fdb73bfc164c13b1
7
+ data.tar.gz: 1f4f0a647a7db4da4b4cbd9b691b6ef9d7d4a03cd58bec59e366fe5cf83f10a44dea6d183176da40438d818b07ff18b517550e2fd2fb995c3600b2a0f58ea64a
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ deploy:
5
+ provider: rubygems
6
+ api_key:
7
+ secure: M1I+7IFuje77sZjtQbmvamzihT+NEJpCzb6Eco8AKbJu/swim+2DvojdJHJw3qpjBt+S2u6zPWWc8KqP6ME7YZzydhJKN/rftUow4lyPbJ6ut9wNg4J9EaZgawG/BOm7LESqtj6J5KWrEd2qRn86mLMHO6ZgLsvsKBWR+oMnb+U=
8
+ gem: console_table
9
+ on:
10
+ tags: true
11
+ repo: rodhilton/console_table
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # ConsoleTable
2
2
 
3
+ [![Build Status](https://travis-ci.org/rodhilton/console_table.svg?branch=master)](https://travis-ci.org/rodhilton/console_table)
4
+
3
5
  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
6
  in commandline applications with information-dense output. It checks your terminal window size (or COLUMNS environment variable) to ensure
5
7
  your data will fit, allows you to define table column sizes, and then just supply the ConsoleTable instance with data which will be
@@ -243,10 +245,137 @@ end
243
245
 
244
246
  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
245
247
 
248
+ Here's a somewhat more practical example:
249
+
250
+ ```ruby
251
+ require 'console_table'
252
+
253
+ require 'json'
254
+ require 'net/http'
255
+ require 'open-uri'
256
+ require 'colorize'
257
+
258
+ symbols = ["YHOO", "AAPL", "GOOG", "MSFT", "C", "MMM", "KO", "WMT", "GM", "IBM", "MCD", "VZ", "HD", "DIS", "INTC"]
259
+
260
+ params = symbols.collect{|s| "\"#{s}\"" }.join(",")
261
+ url = "http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.quotes where symbol in (#{params})&env=http://datatables.org/alltables.env&format=json"
262
+ uri = URI.parse(URI::encode(url))
263
+ response = Net::HTTP.get_response(uri)
264
+ json = JSON.parse(response.body)
265
+
266
+ table_config = [
267
+ {:key=>:symbol, :title=>"Symbol", :size=>6},
268
+ {:key=>:name, :title=>"Name", :size=>17},
269
+ {:key=>:price, :title=>"Price", :size=>5, :justify=>:right},
270
+ {:key=>:change, :title=>"Change", :size=>7, :justify=>:right},
271
+ {:key=>:recommendation, :title=>"Recommendation", :size=>15, :justify=>:right}
272
+ ]
273
+
274
+ ConsoleTable.define(table_config, :title=>"Stock Prices") do |table|
275
+
276
+ json["query"]["results"]["quote"].each do |j|
277
+ change = j["ChangeRealtime"]
278
+ if change.start_with?("+")
279
+ change = change.green
280
+ else
281
+ change = change.red
282
+ end
283
+
284
+ recommendation = (rand() <= 0.5) ? "BUY!".white.on_green.bold.underline : "Sell".yellow
285
+
286
+ table << [
287
+ j["Symbol"].magenta,
288
+ j["Name"],
289
+ j["LastTradePriceOnly"],
290
+ change,
291
+ recommendation
292
+ ]
293
+
294
+ end
295
+
296
+ table.footer << "Recommendations randomly generated"
297
+
298
+ end
299
+ ```
300
+
301
+ And the output:
302
+
303
+ ```
304
+ ======================================================
305
+ Stock Prices
306
+ Symbol Name Price Change Recommendation
307
+ ------------------------------------------------------
308
+ YHOO Yahoo! Inc. 44.42 +0.495 Sell
309
+ AAPL Apple Inc. 127.0 +0.62 BUY!
310
+ GOOG Google Inc. 549.0 +6.08 BUY!
311
+ MSFT Microsoft Corpora 43.87 +0.78 Sell
312
+ C Citigroup, Inc. C 51.20 +0.31 BUY!
313
+ MMM 3M Company Common 165.9 +0.03 Sell
314
+ KO Coca-Cola Company 41.99 -0.18 BUY!
315
+ WMT Wal-Mart Stores, 85.81 -0.08 Sell
316
+ GM General Motors Co 37.62 -0.40 BUY!
317
+ IBM International Bus 160.4 +1.88 BUY!
318
+ MCD MCDONALD'S CORPOR 95.65 +0.56 BUY!
319
+ VZ Verizon Communica 49.31 -0.21 BUY!
320
+ HD Home Depot, Inc. 111.8 -0.27 BUY!
321
+ DIS Walt Disney Compa 104.1 +0.59 BUY!
322
+ INTC Intel Corporation 34.36 +0.235 Sell
323
+ ------------------------------------------------------
324
+ Recommendations randomly generated
325
+ ======================================================
326
+ ```
327
+
328
+ And yes, you can make the table super-ugly and lame if you want by adding `:borders=>true` to the define call, like so:
329
+
330
+ `ConsoleTable.define(table_config, :title=>"Stock Prices", :borders=>true) do |table|`
331
+
332
+ Which will yield this, if you're into that sort of thing:
333
+
334
+ ```
335
+ *======================================================*
336
+ | Stock Prices |
337
+ +------+-----------------+-----+-------+---------------+
338
+ |Symbol|Name |Price| Change| Recommendation|
339
+ +------+-----------------+-----+-------+---------------+
340
+ |YHOO |Yahoo! Inc. |44.42| +0.495| BUY!|
341
+ +------+-----------------+-----+-------+---------------+
342
+ |AAPL |Apple Inc. |127.0| +0.62| BUY!|
343
+ +------+-----------------+-----+-------+---------------+
344
+ |GOOG |Google Inc. |549.0| +6.08| Sell|
345
+ +------+-----------------+-----+-------+---------------+
346
+ |MSFT |Microsoft Corpora|43.87| +0.78| Sell|
347
+ +------+-----------------+-----+-------+---------------+
348
+ |C |Citigroup, Inc. C|51.20| +0.31| Sell|
349
+ +------+-----------------+-----+-------+---------------+
350
+ |MMM |3M Company Common|165.9| +0.03| BUY!|
351
+ +------+-----------------+-----+-------+---------------+
352
+ |KO |Coca-Cola Company|41.99| -0.18| Sell|
353
+ +------+-----------------+-----+-------+---------------+
354
+ |WMT |Wal-Mart Stores, |85.81| -0.08| BUY!|
355
+ +------+-----------------+-----+-------+---------------+
356
+ |GM |General Motors Co|37.62| -0.40| BUY!|
357
+ +------+-----------------+-----+-------+---------------+
358
+ |IBM |International Bus|160.4| +1.88| BUY!|
359
+ +------+-----------------+-----+-------+---------------+
360
+ |MCD |MCDONALD'S CORPOR|95.65| +0.56| Sell|
361
+ +------+-----------------+-----+-------+---------------+
362
+ |VZ |Verizon Communica|49.31| -0.21| BUY!|
363
+ +------+-----------------+-----+-------+---------------+
364
+ |HD |Home Depot, Inc. |111.8| -0.27| BUY!|
365
+ +------+-----------------+-----+-------+---------------+
366
+ |DIS |Walt Disney Compa|104.1| +0.59| BUY!|
367
+ +------+-----------------+-----+-------+---------------+
368
+ |INTC |Intel Corporation|34.36| +0.235| Sell|
369
+ +------+-----------------+-----+-------+---------------+
370
+ | Recommendations randomly generated|
371
+ *======================================================*
372
+ ```
373
+
374
+
246
375
  ## Contributing
247
376
 
248
377
  1. Fork it ( http://github.com/rodhilton/console_table/fork )
249
378
  2. Create your feature branch (`git checkout -b my-new-feature`)
250
379
  3. Commit your changes (`git commit -am 'Add some feature'`)
251
380
  4. Push to the branch (`git push origin my-new-feature`)
252
- 5. Create new Pull Request
381
+ 5. Create new Pull Request
@@ -19,7 +19,6 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_development_dependency "bundler", "~> 1.5"
21
21
  spec.add_development_dependency 'rake', '~> 0'
22
- spec.add_development_dependency 'simplecov', '~> 0.9'
23
22
  spec.add_development_dependency 'minitest', '~> 5.5'
24
23
  spec.add_development_dependency 'colorize', '~> 0.7'
25
24
 
data/lib/console_table.rb CHANGED
@@ -1,7 +1,5 @@
1
- require 'terminfo'
2
-
3
1
  module ConsoleTable
4
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
5
3
 
6
4
  def self.define(layout, options={}, &block)
7
5
  table = ConsoleTableClass.new(layout, options)
@@ -11,7 +9,6 @@ module ConsoleTable
11
9
  end
12
10
 
13
11
  class ConsoleTableClass
14
-
15
12
  attr_reader :footer
16
13
 
17
14
  def <<(options)
@@ -21,13 +18,29 @@ module ConsoleTable
21
18
  protected
22
19
 
23
20
  def initialize(column_layout, options={})
24
- @original_column_layout = column_layout
25
- @left_margin = options[:left_margin] || 0
26
- @right_margin = options[:right_margin] || 0
21
+ @original_column_layout = []
22
+ column_layout.each_with_index do |layout, i|
23
+ if layout.is_a? String
24
+ @original_column_layout << {:key => "col#{i+1}".to_sym, :title=>layout, :size=>"*"}
25
+ elsif layout[:key].nil? and layout[:title].nil?
26
+ @original_column_layout << layout.merge({:key => "col#{i+1}".to_sym, :title=>"Column #{i+1}"})
27
+ elsif layout[:title].nil?
28
+ @original_column_layout << layout.merge({:title => layout[:key].to_s.capitalize})
29
+ elsif layout[:key].nil?
30
+ @original_column_layout << layout.merge({:key => "col#{i+1}".to_sym})
31
+ else
32
+ @original_column_layout << layout
33
+ end
34
+ end
35
+
36
+ #Mostly used for mocking/testing
27
37
  @out = options[:output] || $stdout
28
- @title = options[:title]
29
38
  @set_width = options[:width]
39
+
40
+ @title = options[:title]
30
41
  @borders = options[:borders] || false #Lines between every cell, implies outline
42
+ @left_margin = options[:left_margin] || 0
43
+ @right_margin = options[:right_margin] || 0
31
44
 
32
45
  #Set outline, just the upper and lower lines
33
46
  if @borders
@@ -39,7 +52,6 @@ module ConsoleTable
39
52
  end
40
53
 
41
54
  @footer = []
42
-
43
55
  @headings_printed = false
44
56
  @count = 0
45
57
 
@@ -48,6 +60,8 @@ module ConsoleTable
48
60
  end
49
61
 
50
62
  def print_header()
63
+ #Kind of weird but basically if there's a title, there will be a space between the top border and the actual data, meaning we don't
64
+ #want special characters printed for the "joining" of the lines. If there's no title, however, we do.
51
65
  if @title.nil?
52
66
  print_line("=", "*", false)
53
67
  else
@@ -66,6 +80,7 @@ module ConsoleTable
66
80
 
67
81
  def print_headings()
68
82
  @headings_printed = true
83
+
69
84
  @out.print " "*@left_margin
70
85
  if @borders
71
86
  @out.print "|"
@@ -73,8 +88,9 @@ module ConsoleTable
73
88
 
74
89
  @column_widths.each_with_index do |column, i|
75
90
  justify = column[:justify] || :left
76
- title = (column[:title] || column[:key].to_s.capitalize).strip
77
- @out.print format(column[:size], title, false, justify)
91
+ ellipsize = column[:ellipsize] || false
92
+ title = column[:title].strip
93
+ @out.print format(column[:size], title, ellipsize, justify)
78
94
 
79
95
  if @borders
80
96
  @out.print "|"
@@ -84,7 +100,7 @@ module ConsoleTable
84
100
  end
85
101
  @out.print "\n"
86
102
 
87
- print_line unless @borders #this line will be printed when the NEXT LINE prints out if borders are on
103
+ print_line unless @borders #this line will be printed when the NEXT LINE of actual data prints out if borders are on, because that call PRE-prints the separator line
88
104
  end
89
105
 
90
106
  def print_line(char="-", join_char="+", edge_join_only=false)
@@ -107,6 +123,8 @@ module ConsoleTable
107
123
  end
108
124
  end
109
125
 
126
+ #TODO: it's a little weird how, if a footer is too long, it simply doesn't print at all. This seems like not what someone would want to have happen.
127
+ #Could we take footer lines and split them every X characters where X is the working width, then use those? Long lines effectively wrap, but not on word boundaries
110
128
  def print_footer()
111
129
  if should_print_footer
112
130
  print_line
@@ -220,9 +238,7 @@ module ConsoleTable
220
238
  if string.nil?
221
239
  nil
222
240
  else
223
- require 'pp'
224
241
  normalized = string.to_s
225
-
226
242
  normalized = normalized.sub(/^(\e\[\d[^m]*?m)(\s+)/, '\2\1') #Any leading spaces preceeded by a color code should be swapped with the color code itself, so the spaces themselves aren't colored
227
243
  normalized = normalized.sub(/(\s+)(\e\[\d[^m]*?m)$/, '\2\1')
228
244
  normalized = normalized.gsub(/\s+/, " ").strip #Primarily to remove any tabs or newlines
@@ -235,12 +251,15 @@ module ConsoleTable
235
251
 
236
252
  total_width = @set_width
237
253
  begin
254
+ require 'terminfo'
238
255
  total_width = TermInfo.screen_columns
239
256
  rescue => ex
240
257
  total_width = ENV["COLUMNS"].to_i || 79
241
258
  end if total_width.nil?
242
259
 
243
- keys = @original_column_layout.reject { |d| d[:key].nil? }.collect { |d| d[:key] }.uniq
260
+ working_column_layout = []
261
+
262
+ keys = @original_column_layout.collect { |d| d[:key] }.uniq
244
263
  if keys.length < @original_column_layout.length
245
264
  raise("ConsoleTable configuration invalid, same key defined more than once")
246
265
  end
@@ -300,7 +319,7 @@ module ConsoleTable
300
319
 
301
320
  parts = text.scan(/(\e\[\d.*?m)|(.)/) #The idea here is to break the string up into control codes and single characters
302
321
  #We're going to now count up until we hit goal length, but we're not going to ever count control codes against the count
303
- #We're also going to keep track of if the last thing was a color code, so we know to reset if a color is "active"
322
+ #We're also going to keep track of if a non-resetting control code is 'active', so we know to reset at the end if need-be
304
323
 
305
324
  #I can't think of a better way to do this, it's probably dumb
306
325
  current_length = 0
@@ -331,15 +350,15 @@ module ConsoleTable
331
350
 
332
351
  final_string_parts.join("")
333
352
  else
353
+ space = length-uncolorized.length
334
354
  if justify == :right
335
- (" "*(length-uncolorized.length)) + text
355
+ (" "*space) + text
336
356
  elsif justify == :center
337
- space = length-uncolorized.length
338
357
  left_side = space/2
339
358
  right_side = space - left_side
340
359
  (" " * left_side) + text + (" "*right_side)
341
360
  else #assume left
342
- text + (" "*(length-uncolorized.length))
361
+ text + (" "*space)
343
362
  end
344
363
  end
345
364
  end
@@ -1,13 +1,12 @@
1
+ # encoding: utf-8
1
2
  require 'minitest/autorun'
2
- require 'console_table'
3
- require 'colorize'
4
-
5
- #TODO: What happens if you have a linebreak in what you print?
6
- # - what if it occurs inside of an active color code?
7
3
  #TODO: trimming from different sides depending on justification?
8
4
 
9
5
  class ConsoleTableTest < Minitest::Test
10
6
 
7
+ require 'console_table'
8
+ require 'colorize'
9
+
11
10
  def setup
12
11
  @mock_out = StringIO.new
13
12
  end
@@ -960,6 +959,74 @@ Much mu... Normal,... Much mu...
960
959
  assert_output_equal expected, @mock_out.string
961
960
  end
962
961
 
962
+ def test_will_generate_default_column_keys_and_titles_and_sizes_if_not_provided
963
+ table_config = [
964
+ {:size=>20, :title=>"Column 1"},
965
+ {:key=>:col2, :size=>20, :title=>"Column 2"},
966
+ {:size=>20, :title=>"Column 3"},
967
+ {:key=>:col4, :size=>20},
968
+ {:size=>20},
969
+ {}
970
+ ]
971
+
972
+ ConsoleTable.define(table_config, :width=> 125, :output=>@mock_out) do |table|
973
+ table << ["A", "B", "C", "D", "E", "F"]
974
+
975
+ end
976
+
977
+ expected=<<-END
978
+ =============================================================================================================================
979
+ Column 1 Column 2 Column 3 Col4 Column 5 Column 6
980
+ -----------------------------------------------------------------------------------------------------------------------------
981
+ A B C D E F
982
+ =============================================================================================================================
983
+ END
984
+
985
+ assert_output_equal expected, @mock_out.string
986
+ end
987
+
988
+ def test_can_use_a_string_instead_of_hash_to_default_everything
989
+ table_config = [
990
+ {:size=>20, :title=>"Column 1"},
991
+ "Simple Column",
992
+ {:size=>20, :title=>"Column 3"},
993
+ ]
994
+
995
+ ConsoleTable.define(table_config, :width=> 70, :output=>@mock_out) do |table|
996
+ table << ["A", "B", "C"]
997
+ end
998
+
999
+ expected=<<-END
1000
+ ======================================================================
1001
+ Column 1 Simple Column Column 3
1002
+ ----------------------------------------------------------------------
1003
+ A B C
1004
+ ======================================================================
1005
+ END
1006
+
1007
+ assert_output_equal expected, @mock_out.string
1008
+ end
1009
+
1010
+ def test_can_use_a_config_of_nothing_but_titles_if_you_really_want
1011
+ table_config = [
1012
+ "A Column", "B Column", "C Column"
1013
+ ]
1014
+
1015
+ ConsoleTable.define(table_config, :width=> 30, :output=>@mock_out) do |table|
1016
+ table << ["A", "B", "C"]
1017
+ end
1018
+
1019
+ expected=<<-END
1020
+ =============================
1021
+ A Column B Column C Column
1022
+ -----------------------------
1023
+ A B C
1024
+ =============================
1025
+ END
1026
+
1027
+ assert_output_equal expected, @mock_out.string
1028
+ end
1029
+
963
1030
  private
964
1031
  def assert_output_equal(expected, actual)
965
1032
  expected_lines = expected.split("\n")
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.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rod Hilton
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: simplecov
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.9'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.9'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: minitest
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -104,6 +90,7 @@ extensions: []
104
90
  extra_rdoc_files: []
105
91
  files:
106
92
  - ".gitignore"
93
+ - ".travis.yml"
107
94
  - Gemfile
108
95
  - LICENSE
109
96
  - README.md