texttable 1.1.2 → 1.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/texttable.rb +74 -24
  3. data/texttable.gemspec +1 -1
  4. metadata +6 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9952b36c316d6bfb8b99b98c83e6b443e8df7fab62098d48d2106bfaba910762
4
- data.tar.gz: fac19dec457d9b53adbdb11a6f24b39496af73b882ab4abd856039f10c6b07e4
3
+ metadata.gz: 7e00f8d89b3eda372e1d263c439bde89c2a49fc514733c03d9d173c27d88a21b
4
+ data.tar.gz: bd3e7c03b5baa30ad80517ed68ed2cf14937ac037119a49af90e97bc99fe9cf0
5
5
  SHA512:
6
- metadata.gz: 55ef3df123eaf0261b9c3962389b667828653ea50430ca31183c51418aedba3047f9522d5e2bb8b666a81263cd283d1bb63e0fbea75ece990b24cc654cc39562
7
- data.tar.gz: 7198b28bdf371c91976476542a5b903f393009a5d2cbadb8ca1ba89911670453d536929588ced94f6d2f84c05335cf7f0a3568a8e008db079d3ae3ae75d13220
6
+ metadata.gz: 8983dbf73e36741f53acb51f953e88bfc2a77068ddd79aef042ed74e608e17d186d6c3f245bc6d8bcf548cfdb34bb3c40774af6df9e7375d8b6255a744affa10
7
+ data.tar.gz: c85f63f6c92c17475860fac370fb64c5990e7de39ebf471fcc722e099f6c3b36329d2309f3ea919851c48f99a2515f54b4ed3319f05c63e287fb5e30b04e8a8a
data/lib/texttable.rb CHANGED
@@ -2,15 +2,41 @@ class TextTable
2
2
  attr_accessor :values, :rows
3
3
 
4
4
  class << self
5
- def csv(src, sep=',', encoding: nil)
5
+ def csv(src, sep=',', encoding: nil, **kw)
6
6
  require 'csv'
7
7
  new CSV.read(src || ARGF, {
8
8
  col_sep: sep,
9
9
  encoding: encoding ? encoding + ":UTF-8" : nil,
10
+ **kw
10
11
  }.compact)
11
12
  end
12
- def tsv(*args); csv(args.shift, "\t", *args); end
13
- def psv(*args); csv(args.shift, "|" , *args); end
13
+ def tsv(*args, **kw); csv(args.shift, "\t", *args, **kw); end
14
+ def psv(*args, **kw); csv(args.shift, "|" , *args, **kw); end
15
+
16
+ def add(*args)
17
+ new.add(*args)
18
+ end
19
+
20
+ def load(data, delim="\t", headers=true)
21
+ case data
22
+ when String
23
+ if data.include?(delim) # string
24
+ text = data
25
+ elsif File.exist?(data) # filename
26
+ text = File.read(data)
27
+ end
28
+ when File, ARGF
29
+ text = data.read
30
+ end
31
+
32
+ text or raise "unable to load #{data.inspect}"
33
+ rows = text.split(/\r?\n/).map {|line| line.split(delim).map {|part| part.strip}}
34
+ info = new
35
+ rows.shift.each_with_index {|col, i| info.index!(col || i) } if headers
36
+ info.rows = rows
37
+ info.row(0)
38
+ info
39
+ end
14
40
  end
15
41
 
16
42
  def initialize(*args)
@@ -21,9 +47,8 @@ class TextTable
21
47
  rows = [] if !rows || !rows[0].is_a?(Array) || rows[0].empty?
22
48
  @cols = Hash.new {|h,k| h[k] = h.size}
23
49
  @rows = rows
24
- @values = nil
25
- @row = 0
26
- cols.each {|col| index!(col) }
50
+ row(0)
51
+ cols.each_with_index {|col, i| index!(col || i) }
27
52
  end
28
53
 
29
54
  def index(field, auto=false)
@@ -86,6 +111,10 @@ class TextTable
86
111
  @rows.each_with_index {|_, row| yield(row(row)) }
87
112
  end
88
113
 
114
+ def each_pair
115
+ @cols.each {|col, pos| yield col, @values[pos] }
116
+ end
117
+
89
118
  def [](field, val=nil)
90
119
  index = index(field)
91
120
  value = vals[index] if index
@@ -114,13 +143,15 @@ class TextTable
114
143
  obj = [obj, *args] if args.size > 0
115
144
  @values = @rows[@row = @rows.size] = []
116
145
  case obj
117
- when Hash then obj.each {|k, v| @values[@cols[k]] = v}
146
+ when Hash then obj.each {|k, v| @values[index(k.to_s, true)] = v }
118
147
  when Array then @values.replace(obj)
119
148
  else raise "unable to add #{obj.class} objects"
120
149
  end
121
150
  self
122
151
  end
123
152
 
153
+ alias :<< :add
154
+
124
155
  def show(*)
125
156
  self
126
157
  end
@@ -128,15 +159,20 @@ class TextTable
128
159
  def show!(list=nil)
129
160
  meth = list.is_a?(Array) ? list.method(:push) : method(:puts)
130
161
  join = " | "
131
- both = [@cols.keys] + rows
132
- flip = both.transpose
133
- wide = flip.map {|row| row.map {|col| col.to_s.size }.max }
134
- pict = wide.map {|len| "%-#{len}.#{len}s" }.join(join)
162
+ size = @cols.size
163
+ full = [@cols.keys] + rows
164
+ full.each_with_index do |vals, i| # only when asymmetric
165
+ miss = size - vals.size
166
+ full[i] += [nil] * miss if miss > 0
167
+ full[i] = vals[0...size] if miss < 0
168
+ end
169
+ lens = full.map {|r| r.map {|c| c.to_s.size}}.transpose.map(&:max)
170
+ pict = lens.map {|len| "%-#{len}.#{len}s" }.join(join)
135
171
  pict = [join, pict, join].join.strip
136
- line = (pict % ([""] * @cols.size)).tr("| ", "+-")
172
+ line = (pict % ([""] * size)).tr("| ", "+-")
137
173
  seen = -1
138
174
  meth["", line]
139
- both.each do |vals|
175
+ full.each do |vals|
140
176
  meth[pict % vals]
141
177
  meth[line] if (seen += 1) == 0
142
178
  end
@@ -144,20 +180,31 @@ class TextTable
144
180
  self
145
181
  end
146
182
 
147
- def csv(sep=',', encoding: nil)
183
+ def lookup!(field)
184
+ @rows or raise "no rows defined"
185
+ index = index(field)
186
+ lookup = {}
187
+ @rows.each_with_index {|cols, i| lookup[cols[index]] = i}
188
+ lookup
189
+ end
190
+
191
+ def csv(sep=',', encoding: nil, **kw)
148
192
  require 'csv'
149
- csv = {}
150
- csv[:encoding] = encoding + ":UTF-8" if encoding
151
- csv[:col_sep ] = sep
152
- csv = CSV.new($stdout, csv)
193
+ out = kw.key?(:out) ? (kw.delete(:out) || "").dup : nil
194
+ csv = CSV.new(out || $stdout, {
195
+ col_sep: sep,
196
+ encoding: encoding ? encoding + ":UTF-8" : nil,
197
+ quote_empty: false, #!# TODO: make this an option
198
+ **kw
199
+ })
153
200
  csv << @cols.keys
154
201
  @rows.each {|vals| csv << vals}
155
- nil
202
+ out
156
203
  end
157
- def tsv; csv("\t"); end
158
- def psv; csv("|" ); end
204
+ def tsv(**kw); csv("\t", **kw); end
205
+ def psv(**kw); csv("|" , **kw); end
159
206
 
160
- def sql(table='table', quote: false, timestamps: false, verb: 'insert')
207
+ def sql(table='table', quote: false, timestamps: false, verb: 'insert', out: nil)
161
208
  q = quote ? '`' : ''
162
209
  flip = @cols.invert
163
210
  @rows.each do |vals|
@@ -167,9 +214,12 @@ class TextTable
167
214
  list
168
215
  end
169
216
  list.push('created_at=now(), updated_at=now()') if timestamps
170
- puts "#{verb} into #{q}#{table}#{q} set #{list * ', '};" if !list.empty?
217
+ if !list.empty?
218
+ line = "#{verb} into #{q}#{table}#{q} set #{list * ', '};"
219
+ out ? (out << line) : puts(line)
220
+ end
171
221
  end
172
- nil
222
+ out
173
223
  end
174
224
  end
175
225
 
data/texttable.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "texttable"
5
- s.version = "1.1.2"
5
+ s.version = "1.1.7"
6
6
  s.author = "Steve Shreeve"
7
7
  s.email = "steve.shreeve@gmail.com"
8
8
  s.summary = "An easy way to work with rows and columns as simple tables"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: texttable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Shreeve
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-02 00:00:00.000000000 Z
11
+ date: 2021-03-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This gem will auto-size based on column widths.
14
14
  email: steve.shreeve@gmail.com
@@ -26,7 +26,7 @@ homepage: https://github.com/shreeve/texttable
26
26
  licenses:
27
27
  - MIT
28
28
  metadata: {}
29
- post_install_message:
29
+ post_install_message:
30
30
  rdoc_options: []
31
31
  require_paths:
32
32
  - lib
@@ -41,8 +41,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
43
  requirements: []
44
- rubygems_version: 3.1.2
45
- signing_key:
44
+ rubygems_version: 3.1.4
45
+ signing_key:
46
46
  specification_version: 4
47
47
  summary: An easy way to work with rows and columns as simple tables
48
48
  test_files: []