tty-table 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -3
  3. data/CHANGELOG.md +16 -0
  4. data/Gemfile +4 -4
  5. data/README.md +3 -3
  6. data/appveyor.yml +2 -0
  7. data/benchmarks/speed.rb +3 -5
  8. data/examples/alignment.rb +3 -3
  9. data/examples/basic.rb +2 -2
  10. data/examples/orientation.rb +13 -0
  11. data/examples/padding.rb +15 -0
  12. data/examples/resize.rb +15 -0
  13. data/lib/tty/table.rb +2 -1
  14. data/lib/tty/table/border.rb +4 -12
  15. data/lib/tty/table/column_constraint.rb +15 -7
  16. data/lib/tty/table/columns.rb +42 -68
  17. data/lib/tty/table/field.rb +3 -13
  18. data/lib/tty/table/indentation.rb +9 -20
  19. data/lib/tty/table/operation/alignment.rb +2 -2
  20. data/lib/tty/table/operation/padding.rb +3 -3
  21. data/lib/tty/table/operation/truncation.rb +3 -3
  22. data/lib/tty/table/operation/wrapped.rb +3 -3
  23. data/lib/tty/table/operations.rb +3 -14
  24. data/lib/tty/table/renderer.rb +28 -24
  25. data/lib/tty/table/renderer/ascii.rb +1 -1
  26. data/lib/tty/table/renderer/basic.rb +42 -41
  27. data/lib/tty/table/renderer/unicode.rb +1 -1
  28. data/lib/tty/table/version.rb +1 -3
  29. data/spec/unit/border/ascii/rendering_spec.rb +1 -1
  30. data/spec/unit/border/null/rendering_spec.rb +1 -1
  31. data/spec/unit/border/unicode/rendering_spec.rb +1 -1
  32. data/spec/unit/column_constraint/enforce_spec.rb +2 -2
  33. data/spec/unit/columns/extract_widths_spec.rb +7 -12
  34. data/spec/unit/columns/total_width_spec.rb +3 -4
  35. data/spec/unit/indentation/indent_spec.rb +2 -6
  36. data/spec/unit/operations/new_spec.rb +3 -5
  37. data/spec/unit/renderer/ascii/padding_spec.rb +29 -0
  38. data/tty-table.gemspec +3 -4
  39. metadata +12 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bcfc9c4c4f7d6855d4873722744d74857e12de3
4
- data.tar.gz: 9850f499486fdb55fec0114f5b136d0237be61c6
3
+ metadata.gz: c5a7d889fe3c0a30613340ff98741bdf6fe60e59
4
+ data.tar.gz: 41477fe8e7edddf80275eb253c5505efcde49b1b
5
5
  SHA512:
6
- metadata.gz: 9d879801c732179591cba77d527c2330679d9edc029966ffd08a0afaeac65db2b5e9a5089787881132f336573b5ea8ef9a230c9a6783d8d218db9f403ec23dc7
7
- data.tar.gz: cb944ee39fa02cba0a77d885c42d7f80d1b6133a51ae96d8f368ce755d462cfce1fdcefa1ea3dcaed80d19e69318137e3bb108d4f6ee314ddc4539010506ef0c
6
+ metadata.gz: 28d1f65541cd25ba4dab63f85cdc66294a67e485ca88424ddf0386824b2a28744d2b5143c0880a7eb6d7ba51597a85d4df3c5bf824285f782961c6964d39c6fc
7
+ data.tar.gz: 30e29bacb151c98f5cb41f0b09a53ac3cb53e1cbb030493362713522d7ffc7f2fce6a8cca00edde189e940626cf6848614394365f55af3dd34c5b5b1ff88f651
@@ -8,9 +8,10 @@ script: "bundle exec rake ci"
8
8
  rvm:
9
9
  - 2.0.0
10
10
  - 2.1.10
11
- - 2.2.6
12
- - 2.3.3
13
- - 2.4.1
11
+ - 2.2.8
12
+ - 2.3.6
13
+ - 2.4.3
14
+ - 2.5.0
14
15
  - ruby-head
15
16
  - jruby-9.1.1.0
16
17
  - jruby-head
@@ -1,5 +1,20 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.10.0] - 2018-02-18
4
+
5
+ ### Changed
6
+ * Change to limit Ruby version to 2.0
7
+ * Change to use strings instead of verse
8
+ * Change Field to rely on Strings#display_width
9
+ * Change Operations to stop accepting table at initialization
10
+ * Change Operations#run_operations to #apply_to
11
+ * Change Border to remove padding configuration
12
+ * Change ColumnSet class to Columns stateless module
13
+ * Change Indentation class to stateless module
14
+
15
+ ### Fixed
16
+ * Fix :resize option to honour :padding values
17
+
3
18
  ## [v0.9.0] - 2017-11-04
4
19
 
5
20
  ### Changed
@@ -76,6 +91,7 @@
76
91
 
77
92
  * Initial implementation and release
78
93
 
94
+ [v0.10.0]: https://github.com/piotrmurach/tty-table/compare/v0.9.0...v0.10.0
79
95
  [v0.9.0]: https://github.com/piotrmurach/tty-table/compare/v0.8.0...v0.9.0
80
96
  [v0.8.0]: https://github.com/piotrmurach/tty-table/compare/v0.7.0...v0.8.0
81
97
  [v0.7.0]: https://github.com/piotrmurach/tty-table/compare/v0.6.0...v0.7.0
data/Gemfile CHANGED
@@ -3,15 +3,15 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :tools do
6
- gem 'yard', '~> 0.8.7'
6
+ gem 'yard', '~> 0.9.12'
7
7
  end
8
8
 
9
9
  group :metrics do
10
- gem 'coveralls', '~> 0.8.2'
11
- gem 'simplecov', '~> 0.10.0'
10
+ gem 'coveralls', '~> 0.8.21'
11
+ gem 'simplecov', '~> 0.14.1'
12
12
  gem 'yardstick', '~> 0.9.9'
13
13
  end
14
14
 
15
15
  group :benchmarks do
16
- gem 'benchmark_suite', '~> 1.0.0'
16
+ gem 'benchmark-ips', '~> 2.7.2'
17
17
  end
data/README.md CHANGED
@@ -432,7 +432,7 @@ table.render(:ascii)
432
432
  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:
433
433
 
434
434
  ```ruby
435
- table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2']
435
+ table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2']]
436
436
  table.render :unicode
437
437
  # =>
438
438
  # ┌───────┬───────┐
@@ -554,7 +554,7 @@ All [supported colors](https://github.com/piotrmurach/pastel#3-supported-colors)
554
554
  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
555
555
 
556
556
  ```ruby
557
- table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2']
557
+ table = TTY::Table.new ['header1', 'header2'], [['a1', 'a2'], ['b1', 'b2']]
558
558
  table.render do |renderer|
559
559
  renderer.filter = Proc.new do |val, row_index, col_index|
560
560
  if col_index == 1 and !(row_index == 0)
@@ -710,4 +710,4 @@ This project is intended to be a safe, welcoming space for collaboration, and co
710
710
 
711
711
  ## Copyright
712
712
 
713
- Copyright (c) 2015-2017 Piotr Murach. See LICENSE for further details.
713
+ Copyright (c) 2015-2018 Piotr Murach. See LICENSE for further details.
@@ -17,3 +17,5 @@ environment:
17
17
  - ruby_version: "22-x64"
18
18
  - ruby_version: "23"
19
19
  - ruby_version: "23-x64"
20
+ - ruby_version: "24"
21
+ - ruby_version: "24-x64"
@@ -1,17 +1,15 @@
1
1
  # coding: utf-8
2
2
 
3
- # Benchmark speed of table operations
4
-
5
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
6
-
7
- require 'tty-table'
8
3
  require 'benchmark'
9
4
  require 'benchmark/ips'
10
5
 
6
+ require_relative '../lib/tty-table'
7
+
11
8
  header = [:name, :color]
12
9
  rows = (1..100).map { |n| ["row#{n}", "red"] }
13
10
  table = TTY::Table.new(header, rows)
14
11
 
12
+ # Benchmark speed of table operations
15
13
  Benchmark.ips do |r|
16
14
  r.report("Ruby #to_s") do
17
15
  rows.to_s
@@ -1,8 +1,8 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-table'
3
+ require_relative '../lib/tty-table'
4
4
 
5
- table = TTY::Table.new header: ['header1', 'header2', 'header3']
5
+ table = TTY::Table.new header: ['right align', 'center align', 'left align']
6
6
  table << ['a1', 'a2', 'a3']
7
7
  table << ['b1','b2', 'b3']
8
8
  table << ['c1', 'c2', 'c3']
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-table'
3
+ require_relative '../lib/tty-table'
4
4
 
5
5
  table = TTY::Table.new ['header1','header2'], [['a1', 'a2'], ['b1', 'b2']]
6
6
  puts table.render(:basic)
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/tty-table"
4
+
5
+ table = TTY::Table.new(header: ["Column 1", "Column 2", "Column 3"]) do |t|
6
+ t << [ "r1 c1", "r1 c2", "r1 c3" ]
7
+ t << [ "r2 c1", "r2 c2", "r2 c3" ]
8
+ t << [ "r3 c1", "r3 c2", "r3 c3" ]
9
+ end
10
+
11
+ table.orientation = :vertical
12
+
13
+ puts table.render(:ascii)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pastel'
4
+ require_relative "../lib/tty-table"
5
+
6
+ pastel = Pastel.new
7
+ yellow = pastel.yellow.detach
8
+
9
+ table = TTY::Table.new(header: [ yellow.("Column 1"), yellow.("Column 2"), yellow.("Column 3")]) do |t|
10
+ t << [ "11", "12", "13" ]
11
+ t << [ "21", "22", "23" ]
12
+ t << [ "31", "32", "33" ]
13
+ end
14
+
15
+ puts table.render(:ascii, padding: [1, 2, 1, 2])
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pastel'
4
+ require_relative "../lib/tty-table"
5
+
6
+ pastel = Pastel.new
7
+ yellow = pastel.yellow.detach
8
+
9
+ table = TTY::Table.new(header: [ yellow.("Column 1"), yellow.("Column 2"), yellow.("Column 3")]) do |t|
10
+ t << [ "11", "12", "13" ]
11
+ t << [ "21", "22", "23" ]
12
+ t << [ "31", "32", "33" ]
13
+ end
14
+
15
+ puts table.render(:ascii, resize: true, padding: [1, 2, 1, 2])
@@ -339,6 +339,7 @@ module TTY
339
339
  def columns_size
340
340
  rows.size > 0 ? rows[0].size : 0
341
341
  end
342
+ alias columns_count columns_size
342
343
 
343
344
  # Return the number of rows
344
345
  #
@@ -370,7 +371,7 @@ module TTY
370
371
  #
371
372
  # @api public
372
373
  def width
373
- Columns.new(self).total_width
374
+ Columns.total_width(data)
374
375
  end
375
376
 
376
377
  # Return true if this is an empty table, i.e. if the number of
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'equatable'
4
4
  require 'pastel'
5
- require 'verse'
5
+ require 'strings'
6
6
 
7
7
  require_relative 'border_options'
8
8
  require_relative 'border_dsl'
@@ -39,12 +39,11 @@ module TTY
39
39
  # @return [Object]
40
40
  #
41
41
  # @api private
42
- def initialize(column_widths, padding, options = nil)
42
+ def initialize(column_widths, options = nil)
43
43
  if self.class == Border
44
44
  fail NotImplementedError, "#{self} is an abstract class"
45
45
  else
46
46
  @widths = column_widths
47
- @padding = Verse::Padder.parse(padding)
48
47
  @border_options = TTY::Table::BorderOptions.from options
49
48
  @color = Pastel.new
50
49
  end
@@ -166,11 +165,6 @@ module TTY
166
165
  # @api private
167
166
  attr_reader :border_options
168
167
 
169
- # The padding to apply to each field
170
- #
171
- # @api private
172
- attr_reader :padding
173
-
174
168
  # Separate multiline string into individual rows with border.
175
169
  #
176
170
  # @param [TTY::Table::Row] row
@@ -206,7 +200,7 @@ module TTY
206
200
  line.left + row.fields.each_with_index.map do |field, index|
207
201
  direction = field.alignment || :left
208
202
  field_content = field.lines[line_index] || SPACE_CHAR * field.length
209
- Verse.align(field_content, widths[index], direction)
203
+ Strings.align(field_content, widths[index], direction: direction)
210
204
  end.join(line.center) + line.right
211
205
  end
212
206
 
@@ -237,9 +231,7 @@ module TTY
237
231
  #
238
232
  # @api private
239
233
  def render_line(line, left, right, intersection)
240
- left + widths.map do |width|
241
- line * (padding.left + width + padding.right)
242
- end.join(intersection) + right
234
+ left + widths.map { |width| line * width }.join(intersection) + right
243
235
  end
244
236
  end # Border
245
237
  end # Table
@@ -57,7 +57,7 @@ module TTY
57
57
  # @api public
58
58
  def padding_size
59
59
  padding = renderer.padding
60
- (padding.left + padding.right) * (table.columns_size - 1)
60
+ (padding.left + padding.right) * table.columns_count
61
61
  end
62
62
 
63
63
  # Estimate minimum table width to be able to display content
@@ -86,9 +86,16 @@ module TTY
86
86
  # @api public
87
87
  def enforce
88
88
  assert_minimum_width
89
+ padding = renderer.padding
89
90
 
90
91
  if natural_width <= renderer.width
91
- renderer.resize ? expand : renderer.column_widths
92
+ if renderer.resize
93
+ expand_column_widths
94
+ else
95
+ renderer.column_widths.map do |width|
96
+ padding.left + width + padding.right
97
+ end
98
+ end
92
99
  else
93
100
  if renderer.resize
94
101
  shrink
@@ -115,12 +122,13 @@ module TTY
115
122
  # Expand column widths to match the requested width
116
123
  #
117
124
  # @api private
118
- def expand
119
- column_size = table.columns_size
120
- ratio = ((renderer.width - natural_width) / column_size.to_f).floor
125
+ def expand_column_widths
126
+ columns_count = table.columns_count
127
+ max_width = renderer.width
128
+ extra_column_width = ((max_width - natural_width) / columns_count.to_f).floor
121
129
 
122
- widths = (0...column_size).reduce([]) do |lengths, col|
123
- lengths + [renderer.column_widths[col] + ratio]
130
+ widths = (0...columns_count).reduce([]) do |lengths, col|
131
+ lengths << renderer.column_widths[col] + extra_column_width
124
132
  end
125
133
  distribute_extra_width(widths)
126
134
  end
@@ -1,66 +1,55 @@
1
1
  # encoding: utf-8
2
-
3
- require 'equatable'
2
+ # frozen_string_literal: true
4
3
 
5
4
  require_relative 'error'
6
5
 
7
6
  module TTY
8
7
  class Table
9
- # A class that represents table column properties.
8
+ # A module for calculating table data column widths
10
9
  #
11
10
  # Used by {Table} to manage column sizing.
12
11
  #
13
12
  # @api private
14
- class Columns
15
- include Equatable
16
-
17
- # Initialize Columns
18
- #
19
- # @param [Array[Array[Object]]] data
20
- #
21
- # @api public
22
- def initialize(table)
23
- @data = table.data
24
- end
25
-
13
+ module Columns
26
14
  # Calculate total table width
27
15
  #
28
16
  # @return [Integer]
29
17
  #
30
18
  # @api public
31
- def total_width
32
- extract_widths.reduce(:+)
19
+ def total_width(data)
20
+ extract_widths(data).reduce(:+)
33
21
  end
22
+ module_function :total_width
34
23
 
35
24
  # Calcualte maximum column widths
36
25
  #
37
26
  # @return [Array] column widths
38
27
  #
39
28
  # @api private
40
- def extract_widths
29
+ def extract_widths(data)
41
30
  colcount = data.max { |row_a, row_b| row_a.size <=> row_b.size }.size
42
- find_maximas(colcount)
31
+ (0...colcount).reduce([]) do |maximas, col_index|
32
+ maximas << find_maximum(data, col_index)
33
+ maximas
34
+ end
43
35
  end
36
+ module_function :extract_widths
44
37
 
45
- # Assert data integrity for column widths
46
- #
47
- # @param [Array] column_widths
38
+ # Find a maximum column width. The calculation takes into account
39
+ # wether the content is escaped or not.
48
40
  #
49
- # @param [Integer] table_widths
41
+ # @param [Integer] index
42
+ # the column index
50
43
  #
51
- # @raise [TTY::InvalidArgument]
44
+ # @return [Integer]
52
45
  #
53
- # @api public
54
- def self.assert_widths(column_widths, table_widths)
55
- if column_widths.empty?
56
- fail InvalidArgument, 'Value for :column_widths must be ' \
57
- 'a non-empty array'
58
- end
59
- if column_widths.size != table_widths
60
- fail InvalidArgument, 'Value for :column_widths must match ' \
61
- 'table column count'
62
- end
46
+ # @api private
47
+ def find_maximum(data, index)
48
+ data.map do |row|
49
+ (field = row.call(index)) ? field.length : 0
50
+ end.max
63
51
  end
52
+ module_function :find_maximum
64
53
 
65
54
  # Converts column widths to array format or infers default widths
66
55
  #
@@ -71,7 +60,7 @@ module TTY
71
60
  # @return [Array[Integer]]
72
61
  #
73
62
  # @api public
74
- def self.widths_from(table, column_widths = nil)
63
+ def widths_from(table, column_widths = nil)
75
64
  case column_widths
76
65
  when Array
77
66
  assert_widths(column_widths, table.columns_size)
@@ -79,48 +68,33 @@ module TTY
79
68
  when Numeric
80
69
  Array.new(table.columns_size, column_widths)
81
70
  when NilClass
82
- new(table).extract_widths
71
+ extract_widths(table.data)
83
72
  else
84
73
  fail TypeError, 'Invalid type for column widths'
85
74
  end
86
75
  end
76
+ module_function :widths_from
87
77
 
88
- private
89
-
90
- attr_reader :data
91
-
92
- # Find maximum widths for each row and header if present.
93
- #
94
- # @param [Integer] colcount
95
- # number of columns
96
- #
97
- # @return [Array[Integer]]
78
+ # Assert data integrity for column widths
98
79
  #
99
- # @api private
100
- def find_maximas(colcount)
101
- maximas = []
102
- start = 0
103
-
104
- start.upto(colcount - 1) do |col_index|
105
- maximas << find_maximum(col_index)
106
- end
107
- maximas
108
- end
109
-
110
- # Find a maximum column width. The calculation takes into account
111
- # wether the content is escaped or not.
80
+ # @param [Array] column_widths
112
81
  #
113
- # @param [Integer] index
114
- # the column index
82
+ # @param [Integer] table_widths
115
83
  #
116
- # @return [Integer]
84
+ # @raise [TTY::InvalidArgument]
117
85
  #
118
- # @api private
119
- def find_maximum(index)
120
- data.map do |row|
121
- (field = row.call(index)) ? field.length : 0
122
- end.max
86
+ # @api public
87
+ def assert_widths(column_widths, table_widths)
88
+ if column_widths.empty?
89
+ fail InvalidArgument, 'Value for :column_widths must be ' \
90
+ 'a non-empty array'
91
+ end
92
+ if column_widths.size != table_widths
93
+ fail InvalidArgument, 'Value for :column_widths must match ' \
94
+ 'table column count'
95
+ end
123
96
  end
124
- end # ColumnSet
97
+ module_function :assert_widths
98
+ end # Columns
125
99
  end # Table
126
100
  end # TTY