tabularize 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ 0.2.1
2
+ -----
3
+ - Multi-line support
4
+ - Vertical alignment
5
+
1
6
  0.2.0
2
7
  -----
3
8
  - Tabularize::Table class for easy tabularization (doh!)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tabularize (0.2.0)
4
+ tabularize (0.2.1)
5
5
  unicode-display_width (~> 0.1.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -2,7 +2,8 @@ tabularize
2
2
  ==========
3
3
 
4
4
  Formatting tabular data with paddings.
5
- `tabularize` correctly handles CJK wide characters and ANSI codes.
5
+ [tabularize](https://github.com/junegunn/tabularize) correctly handles
6
+ CJK (Chinese, Japanese and Korean) wide characters and ANSI codes.
6
7
 
7
8
  Inspired by tabular.vim (https://github.com/godlygeek/tabular)
8
9
 
@@ -49,17 +50,19 @@ puts table
49
50
  * `:vborder` Character for vertical border
50
51
  * `:iborder` Character for intersection point
51
52
  * Alignment
52
- * `:align` Cell alignment. `:left`, `:center`, `:right`, or Array of the three options
53
+ * `:align` Horizontal alignment. `:left`, `:center`, `:right`, or Array of the three options
54
+ * `:valign` Vertical alignment. `:top`, `:middle`, `:bottom`, or Array of the three options
53
55
 
54
56
  ```ruby
55
- table = Tabularize.new :pad => '.', :pad_left => 2, :pad_right => 0,
57
+ table = Tabularize.new :pad => '.', :pad_left => 2, :pad_right => 0,
56
58
  :hborder => '~', :vborder => 'I', :iborder => '#',
57
- :align => [:left, :center, :right]
59
+ :align => [:left, :center, :right],
60
+ :valign => [:top, :bottom, :middle, :middle]
58
61
  table << %w[Name Dept Location Phone]
59
62
  table.separator!
60
- table << ['John Doe', 'Finance', 'Los Angeles CA 90089', '555-1555']
63
+ table << ['John Doe', 'Finance', 'Los Angeles CA 90089', "555-1555"]
61
64
  table << ['Average Joe', 'Engineering', 'Somewhere over the rainbow', 'N/A']
62
- table << ['홍길동', '탁상 3부', '서울역 3번 출구 김씨 옆자리', 'N/A']
65
+ table << ['홍길동', '탁상 3부', "서울역 3번 출구 김씨 옆자리\n\n맞습니다", 'N/A']
63
66
  puts table
64
67
  ```
65
68
 
@@ -69,7 +72,9 @@ I..Name.......I.....Dept....I.....................LocationI.....PhoneI
69
72
  #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
70
73
  I..John Doe...I....Finance..I.........Los Angeles CA 90089I..555-1555I
71
74
  I..Average JoeI..EngineeringI...Somewhere over the rainbowI.......N/AI
72
- I..홍길동.....I...탁상 3부..I..서울역 3번 출구 김씨 옆자리I.......N/AI
75
+ I..홍길동.....I.............I..서울역 3번 출구 김씨 옆자리I..........I
76
+ I.............I.............I.............................I.......N/AI
77
+ I.............I...탁상 3부..I.....................맞습니다I..........I
73
78
  #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
74
79
  ```
75
80
 
@@ -178,14 +183,25 @@ Hong Gildong | HR_________ | Nowhere___________________ | 555-5555
178
183
 
179
184
  ANSI codes and CJK wide characters
180
185
  ----------------------------------
181
- `tabularize` correctly calculates each cell width even in the presence of ANSI codes and CJK wide characters.
186
+ [tabularize](https://github.com/junegunn/tabularize) correctly calculates each cell width even in the presence of ANSI codes and CJK wide characters.
182
187
  If your data doesn't have any of them, unset `:unicode` and `:ansi` options
183
- so that `tabularize` can process data more efficiently.
188
+ so that [tabularize](https://github.com/junegunn/tabularize) can process data more efficiently.
184
189
 
185
190
  ```ruby
186
191
  table = Tabularize.new :unicode => false, :ansi => false
187
192
  ```
188
193
 
194
+ Related work
195
+ ------------
196
+ I wasn't aware of [terminal-table](https://github.com/visionmedia/terminal-table)
197
+ when I blindly started building [tabularize](https://github.com/junegunn/tabularize).
198
+ It has more features and clearly is more mature than [tabularize](https://github.com/junegunn/tabularize),
199
+ you should definitely check it out.
200
+
201
+ There are a couple of things, however, [tabularize](https://github.com/junegunn/tabularize) does better:
202
+ - It correctly formats cells containing CJK wide characters.
203
+ - Vertical alignment for multi-line cells
204
+
189
205
  Copyright
190
206
  ---------
191
207
 
@@ -5,6 +5,7 @@ require 'unicode/display_width'
5
5
  class Tabularize
6
6
  DEFAULT_OPTIONS = {
7
7
  :align => :left,
8
+ :valign => :top,
8
9
  :pad => ' ',
9
10
  :pad_left => 0,
10
11
  :pad_right => 0,
@@ -63,11 +64,22 @@ class Tabularize
63
64
  output = StringIO.new
64
65
  output.puts separator
65
66
  rows.each_with_index do |row, idx|
67
+ row = row.map { |val| val.lines.to_a.map(&:chomp) }
68
+ height = row[0] ? row[0].count : 1
66
69
  @seps[idx].times do
67
70
  output.puts separator
68
71
  end
69
- output.puts v + row.join(v) + v
72
+ (0...height).each do |line|
73
+ output.puts v + row.map { |lines|
74
+ lines[line] || @options[:pad] * Tabularize.cell_width(lines[0], u, a)
75
+ }.join(v) + v
76
+ end
77
+ end
78
+
79
+ @seps[rows.length].times do
80
+ output.puts separator
70
81
  end
82
+
71
83
  output.puts separator
72
84
  output.string
73
85
  end
@@ -97,7 +109,8 @@ class Tabularize
97
109
  pad = options[:pad].to_s
98
110
  padl = options[:pad_left]
99
111
  padr = options[:pad_right]
100
- align = [options[:align]].flatten
112
+ align = [*options[:align]]
113
+ valign = [*options[:valign]]
101
114
  unicode = options[:unicode]
102
115
  ansi = options[:ansi]
103
116
 
@@ -113,42 +126,69 @@ class Tabularize
113
126
  unless align.all? { |a| [:left, :right, :center].include?(a) }
114
127
  raise ArgumentError.new("Invalid alignment")
115
128
  end
129
+ unless valign.all? { |a| [:top, :bottom, :middle].include?(a) }
130
+ raise ArgumentError.new("Invalid vertical alignment")
131
+ end
116
132
 
117
- rows = []
118
- max_widths = []
119
- table_data.each do |row|
120
- rows << row = [*row].map(&:to_s).map(&:chomp)
133
+ rows = []
134
+ max_widths = []
135
+ max_heights = []
136
+ table_data.each_with_index do |row, ridx|
137
+ rows << row = [*row].map(&:to_s)
121
138
 
122
139
  row.each_with_index do |cell, idx|
123
- max_widths[idx] = [ Tabularize.cell_width(cell, unicode, ansi), max_widths[idx] || 0 ].max
140
+ nlines = 0
141
+ cell.lines do |c|
142
+ max_widths[idx] = [ Tabularize.cell_width(c.chomp, unicode, ansi), max_widths[idx] || 0 ].max
143
+ nlines += 1
144
+ end
145
+ max_heights[ridx] = [ nlines, max_heights[ridx] || 1 ].max
124
146
  end
125
147
  end
126
148
 
149
+ ridx = -1
127
150
  rows.map { |row|
151
+ ridx += 1
128
152
  idx = -1
129
- row.map { |str|
130
- alen =
131
- if ansi
132
- Tabularize.cell_width(str, false, false) -
133
- Tabularize.cell_width(str, false, true)
134
- else
153
+ max_height = max_heights[ridx]
154
+ row.map { |cell|
155
+ idx += 1
156
+ lines = cell.lines.to_a
157
+ offset =
158
+ case valign[idx] || valign.last
159
+ when :top
135
160
  0
161
+ when :bottom
162
+ max_height - lines.length
163
+ when :middle
164
+ (max_height - lines.length) / 2
136
165
  end
137
- slen = str.length - alen
138
166
 
139
- idx += 1
140
- w = max_widths[idx]
141
- w += str.length - str.display_width if unicode
142
- pad * padl +
143
- case align[idx] || align.last
144
- when :left
145
- str.ljust(w + alen, pad)
146
- when :right
147
- str.rjust(w + alen, pad)
148
- when :center
149
- str.rjust((w - slen) / 2 + slen + alen, pad).ljust(w + alen, pad)
150
- end +
151
- pad * padr
167
+ (0...max_height).map { |ln|
168
+ ln -= offset
169
+ str = (ln >= 0 && lines[ln]) ? lines[ln].chomp : (pad * max_widths[idx])
170
+ alen =
171
+ if ansi
172
+ Tabularize.cell_width(str, false, false) -
173
+ Tabularize.cell_width(str, false, true)
174
+ else
175
+ 0
176
+ end
177
+ slen = str.length - alen
178
+
179
+ w = max_widths[idx]
180
+ w += str.length - str.display_width if unicode
181
+ pad * padl +
182
+ case align[idx] || align.last
183
+ when :left
184
+ str.ljust(w + alen, pad)
185
+ when :right
186
+ str.rjust(w + alen, pad)
187
+ when :center
188
+ str.rjust((w - slen) / 2 + slen + alen, pad).ljust(w + alen, pad)
189
+ end +
190
+ pad * padr
191
+ }.join($/)
152
192
  }
153
193
  }
154
194
  end
@@ -1,3 +1,3 @@
1
1
  class Tabularize
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -8,12 +8,13 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
8
  require 'tabularize'
9
9
 
10
10
  table = Tabularize.new
11
- table = Tabularize.new :pad => '.', :pad_left => 2, :pad_right => 0,
11
+ table = Tabularize.new :pad => '.', :pad_left => 2, :pad_right => 0,
12
12
  :hborder => '~', :vborder => 'I', :iborder => '#',
13
- :align => [:left, :center, :right]
13
+ :align => [:left, :center, :right],
14
+ :valign => [:top, :bottom, :middle, :middle]
14
15
  table << %w[Name Dept Location Phone]
15
16
  table.separator!
16
17
  table << ['John Doe', 'Finance', 'Los Angeles CA 90089', '555-1555']
17
18
  table << ['Average Joe', 'Engineering', 'Somewhere over the rainbow', 'N/A']
18
- table << ['홍길동', '탁상 3부', '서울역 3번 출구 김씨 옆자리', 'N/A']
19
+ table << ['홍길동', '탁상 3부', "서울역 3번 출구 김씨 옆자리\n\n맞습니다", 'N/A']
19
20
  puts table
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'rubygems'
2
3
  require 'bundler'
3
4
  Bundler.setup(:default, :development)
@@ -131,7 +132,9 @@ class TestTabularize < Test::Unit::TestCase
131
132
  assert_raise(ArgumentError) { Tabularize.it(5) }
132
133
  assert_raise(ArgumentError) { Tabularize.it("hello") }
133
134
  assert_raise(ArgumentError) { Tabularize.it([1, 2, 3], :align => :noidea) }
135
+ assert_raise(ArgumentError) { Tabularize.it([1, 2, 3], :valign => :noidea) }
134
136
  assert_raise(ArgumentError) { Tabularize.it([1, 2, 3], :align => [:center, :top]) }
137
+ assert_raise(ArgumentError) { Tabularize.it([1, 2, 3], :valign => [:left, :right]) }
135
138
  assert_raise(ArgumentError) { Tabularize.it([1, 2, 3], :pad => 'long') }
136
139
  assert_raise(ArgumentError) { Tabularize.it([1, 2, 3], :pad => ' ', :pad_left => -1) }
137
140
  assert_raise(ArgumentError) { Tabularize.it([1, 2, 3], :pad => ' ', :pad_left => '') }
@@ -154,4 +157,39 @@ class TestTabularize < Test::Unit::TestCase
154
157
 
155
158
  puts table.to_s
156
159
  end
160
+
161
+ def test_table_complex
162
+ output = "
163
+ #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
164
+ I..Name.......I.....Dept....I.....................LocationI.....PhoneI
165
+ #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
166
+ I..John Doe...I....Finance..I.........Los Angeles CA 90089I..555-1555I
167
+ I..Average JoeI..EngineeringI...Somewhere over the rainbowI.......N/AI
168
+ I..1..........I
169
+ #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
170
+ #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
171
+ I..홍길동.....I.............I..서울역 3번 출구 김씨 옆자리I..........I
172
+ I.............I.............I.............................I.......N/AI
173
+ I.............I...탁상 3부..I.....................맞습니다I..........I
174
+ #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
175
+ #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
176
+ #~~~~~~~~~~~~~#~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~#
177
+ ".strip
178
+
179
+ table = Tabularize.new :pad => '.', :pad_left => 2, :pad_right => 0,
180
+ :hborder => '~', :vborder => 'I', :iborder => '#',
181
+ :align => [:left, :center, :right],
182
+ :valign => [:top, :bottom, :middle, :middle]
183
+ table << %w[Name Dept Location Phone]
184
+ table.separator!
185
+ table << ['John Doe', 'Finance', 'Los Angeles CA 90089', '555-1555']
186
+ table << ['Average Joe', 'Engineering', 'Somewhere over the rainbow', 'N/A']
187
+ table << [1]
188
+ table.separator!
189
+ table.separator!
190
+ table << ['홍길동', '탁상 3부', "서울역 3번 출구 김씨 옆자리\n\n맞습니다", 'N/A']
191
+ table.separator!
192
+ table.separator!
193
+ assert_equal output, table.to_s.strip
194
+ end
157
195
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tabularize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-10 00:00:00.000000000 Z
12
+ date: 2012-07-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: awesome_print