tabular 0.2.7 → 0.3.0
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 +4 -4
- data/Gemfile +1 -2
- data/Gemfile.lock +14 -12
- data/README +5 -5
- data/lib/tabular.rb +2 -0
- data/lib/tabular/column.rb +11 -34
- data/lib/tabular/columns.rb +22 -23
- data/lib/tabular/row.rb +12 -2
- data/lib/tabular/table.rb +21 -85
- data/lib/tabular/version.rb +1 -1
- data/tabular.gemspec +1 -3
- metadata +6 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a72f7305b34731c1fb2e479cfbb0a13039dfd840
|
4
|
+
data.tar.gz: 11cca1a77c8687abbe9f026edee0422239ff2937
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 298c71843ce790a2f6db8ff682c6fed2665b598234e0703384805f40beb2273193dd280b90e979287635d61ce7e2c95b305fc4842ed1b9befbfc13da5ddbbc7e
|
7
|
+
data.tar.gz: c522ca24515089828157fffc266450d7b45fd5993f8439ee1df67d60e7e7706b5c51b837956652edbaddb7397313262f236456cab97a4eb7e24f83069638107e
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,25 +1,27 @@
|
|
1
1
|
GIT
|
2
|
-
remote: git://github.com/
|
3
|
-
revision:
|
2
|
+
remote: git://github.com/Empact/roo.git
|
3
|
+
revision: 4a1353de22e46880e656d9af062a1436eb5e1a9c
|
4
4
|
specs:
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
revision: e5d97bc43f3db66600a70ace5de638f41a4a700b
|
10
|
-
specs:
|
11
|
-
spreadsheet (0.6.6)
|
12
|
-
ruby-ole
|
5
|
+
roo (1.13.2)
|
6
|
+
nokogiri
|
7
|
+
rubyzip
|
8
|
+
spreadsheet (> 0.6.4)
|
13
9
|
|
14
10
|
GEM
|
15
11
|
remote: https://rubygems.org/
|
16
12
|
specs:
|
13
|
+
mini_portile (0.6.0)
|
14
|
+
nokogiri (1.6.3.1)
|
15
|
+
mini_portile (= 0.6.0)
|
17
16
|
rake (10.1.0)
|
17
|
+
ruby-ole (1.2.11.7)
|
18
|
+
rubyzip (1.1.6)
|
19
|
+
spreadsheet (1.0.0)
|
20
|
+
ruby-ole (>= 1.0)
|
18
21
|
|
19
22
|
PLATFORMS
|
20
23
|
ruby
|
21
24
|
|
22
25
|
DEPENDENCIES
|
23
26
|
rake
|
24
|
-
|
25
|
-
spreadsheet!
|
27
|
+
roo!
|
data/README
CHANGED
@@ -14,17 +14,15 @@ Install
|
|
14
14
|
-------
|
15
15
|
sudo gem install tabular
|
16
16
|
|
17
|
-
|
17
|
+
Or, Gemfile:
|
18
|
+
gem "tabular"
|
18
19
|
|
19
20
|
|
20
21
|
Dependencies
|
21
22
|
------------
|
22
23
|
For tab-delimited data: Ruby standard lib
|
23
24
|
|
24
|
-
For
|
25
|
-
sudo gem install fastercsv
|
26
|
-
|
27
|
-
For Excel: Spreadsheet gem (http://spreadsheet.rubyforge.org/)
|
25
|
+
For Excel: Roo gem (https://github.com/Empact/roo)
|
28
26
|
sudo gem install spreadsheet
|
29
27
|
|
30
28
|
|
@@ -64,6 +62,8 @@ There's basic test coverage. More comprehensive test coverage needs to be extrac
|
|
64
62
|
|
65
63
|
Changes
|
66
64
|
-------
|
65
|
+
0.3.0 Revise Table creation methods to something sensible. Use Roo to read
|
66
|
+
spreadsheets. Support for xlsx.
|
67
67
|
0.2.7 Add Table#to_space_delimited for space-padded fixed layout
|
68
68
|
0.2.6 Add :except option for delete_blank_columns!
|
69
69
|
0.2.5 Use modern gemspec with no runtime dependencies. Make spreadsheet gem optional.
|
data/lib/tabular.rb
CHANGED
@@ -6,8 +6,10 @@ require "tabular/blank"
|
|
6
6
|
require "tabular/keys"
|
7
7
|
require "tabular/zero"
|
8
8
|
|
9
|
+
require "tabular/column_mapper"
|
9
10
|
require "tabular/column"
|
10
11
|
require "tabular/columns"
|
11
12
|
require "tabular/renderer"
|
12
13
|
require "tabular/row"
|
14
|
+
require "tabular/tables/file_reading"
|
13
15
|
require "tabular/table"
|
data/lib/tabular/column.rb
CHANGED
@@ -1,33 +1,21 @@
|
|
1
1
|
module Tabular
|
2
2
|
class Column
|
3
|
-
include Tabular::Blank
|
4
|
-
|
5
3
|
attr_reader :key, :column_type
|
6
4
|
|
7
5
|
# +table+ -- parent Table
|
8
6
|
# +column+ -- parent Columns
|
9
|
-
# +key+
|
10
|
-
def initialize(table, columns, key = nil
|
7
|
+
# +key+ should be a normalized, downcase, underscored symbol
|
8
|
+
def initialize(table, columns, key = nil)
|
11
9
|
@columns = columns
|
12
10
|
@table = table
|
11
|
+
@key = self.columns.column_mapper.map(key)
|
13
12
|
|
14
|
-
key
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@column_type = :string
|
19
|
-
case map_for_key
|
20
|
-
when nil
|
21
|
-
@key = key
|
22
|
-
@column_type = :date if key == :date
|
23
|
-
when Symbol
|
24
|
-
@key = map_for_key
|
25
|
-
@column_type = :date if key == :date
|
26
|
-
when Hash
|
27
|
-
@key = key
|
28
|
-
@column_type = map_for_key[:column_type]
|
13
|
+
if @key && @key.to_s["date"]
|
14
|
+
@column_type = :date
|
15
|
+
elsif @key && @key.to_s[/\?\z/]
|
16
|
+
@column_type = :boolean
|
29
17
|
else
|
30
|
-
|
18
|
+
@column_type = :string
|
31
19
|
end
|
32
20
|
end
|
33
21
|
|
@@ -77,22 +65,11 @@ module Tabular
|
|
77
65
|
key.to_s
|
78
66
|
end
|
79
67
|
|
80
|
-
private
|
81
68
|
|
82
|
-
|
83
|
-
return nil if is_blank?(key)
|
69
|
+
protected
|
84
70
|
|
85
|
-
|
86
|
-
|
87
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
88
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
89
|
-
tr("-", "_").
|
90
|
-
gsub(/ +/, "_").
|
91
|
-
downcase.
|
92
|
-
to_sym
|
93
|
-
rescue
|
94
|
-
nil
|
95
|
-
end
|
71
|
+
def columns
|
72
|
+
@columns ||= Columns.new
|
96
73
|
end
|
97
74
|
end
|
98
75
|
end
|
data/lib/tabular/columns.rb
CHANGED
@@ -5,21 +5,35 @@ module Tabular
|
|
5
5
|
include Tabular::Blank
|
6
6
|
include Tabular::Keys
|
7
7
|
|
8
|
+
attr_accessor :column_mapper
|
8
9
|
attr_accessor :renderer
|
9
10
|
|
10
11
|
# +table+ -- Table
|
11
12
|
# +data+ -- array of header names
|
12
|
-
|
13
|
-
def
|
13
|
+
|
14
|
+
def column_mapper
|
15
|
+
@column_mapper ||= Tabular::ColumnMapper.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(table = Table.new, names = [], column_mapper = nil)
|
14
19
|
@table = table
|
15
|
-
|
16
|
-
|
20
|
+
self.column_mapper = column_mapper
|
21
|
+
|
17
22
|
@column_indexes = {}
|
18
23
|
@columns_by_key = {}
|
24
|
+
|
25
|
+
set_columns table, names
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_columns(table = Table.new, names = [])
|
19
29
|
index = 0
|
20
|
-
|
21
|
-
|
22
|
-
|
30
|
+
|
31
|
+
if names.respond_to?(:keys)
|
32
|
+
names = names.keys
|
33
|
+
end
|
34
|
+
|
35
|
+
@columns = names.map do |name|
|
36
|
+
new_column = Tabular::Column.new(table, self, name)
|
23
37
|
unless is_blank?(new_column.key)
|
24
38
|
@column_indexes[new_column.key] = index
|
25
39
|
@columns_by_key[new_column.key] = new_column
|
@@ -52,7 +66,7 @@ module Tabular
|
|
52
66
|
|
53
67
|
# Add a new Column with +key+
|
54
68
|
def <<(key)
|
55
|
-
column = Column.new(@table, self, key
|
69
|
+
column = Column.new(@table, self, key)
|
56
70
|
unless is_blank?(column.key) || has_key?(key)
|
57
71
|
@column_indexes[column.key] = @columns.size
|
58
72
|
@column_indexes[@columns.size] = column
|
@@ -89,20 +103,5 @@ module Tabular
|
|
89
103
|
def to_space_delimited
|
90
104
|
map(&:to_space_delimited).join " "
|
91
105
|
end
|
92
|
-
|
93
|
-
private
|
94
|
-
|
95
|
-
def normalize_columns_map(columns_map)
|
96
|
-
normalized_columns_map = {}
|
97
|
-
columns_map.each do |key, value|
|
98
|
-
case value
|
99
|
-
when Hash, Symbol
|
100
|
-
normalized_columns_map[key_to_sym(key)] = value
|
101
|
-
else
|
102
|
-
normalized_columns_map[key_to_sym(key)] = value.to_sym
|
103
|
-
end
|
104
|
-
end
|
105
|
-
normalized_columns_map
|
106
|
-
end
|
107
106
|
end
|
108
107
|
end
|
data/lib/tabular/row.rb
CHANGED
@@ -78,6 +78,16 @@ module Tabular
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
# Next Row
|
82
|
+
def next
|
83
|
+
@table.rows[index + 1]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Is this the last row?
|
87
|
+
def last?
|
88
|
+
index == @table.rows.size - 1
|
89
|
+
end
|
90
|
+
|
81
91
|
# Tabluar::Columns
|
82
92
|
def columns
|
83
93
|
@table.columns
|
@@ -133,7 +143,7 @@ module Tabular
|
|
133
143
|
else
|
134
144
|
begin
|
135
145
|
if @array[index]
|
136
|
-
@hash[column.key] = Date.parse(@array[index], true)
|
146
|
+
@hash[column.key] = Date.parse(@array[index].to_s, true)
|
137
147
|
else
|
138
148
|
@hash[column.key] = nil
|
139
149
|
end
|
@@ -162,7 +172,7 @@ module Tabular
|
|
162
172
|
def parse_invalid_date(value)
|
163
173
|
return unless value
|
164
174
|
|
165
|
-
parts = value.split("/")
|
175
|
+
parts = value.to_s.split("/")
|
166
176
|
return unless parts.size == 3
|
167
177
|
|
168
178
|
month = parts[0].to_i
|
data/lib/tabular/table.rb
CHANGED
@@ -4,72 +4,22 @@ module Tabular
|
|
4
4
|
class Table
|
5
5
|
include Tabular::Blank
|
6
6
|
include Tabular::Keys
|
7
|
+
include Tabular::Tables::FileReading
|
7
8
|
include Tabular::Zero
|
8
9
|
|
9
|
-
|
10
|
+
attr_accessor :column_mapper
|
10
11
|
attr_accessor :row_mapper
|
12
|
+
attr_reader :rows
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
file_path = case file
|
17
|
-
when File
|
18
|
-
file.path
|
19
|
-
else
|
20
|
-
file
|
21
|
-
end
|
22
|
-
|
23
|
-
raise "Could not find '#{file_path}'" unless File.exists?(file_path)
|
24
|
-
options = extract_options(options)
|
25
|
-
|
26
|
-
format = self.format_from(options.delete(:as), file_path)
|
27
|
-
data = read_file(file_path, format)
|
28
|
-
|
29
|
-
Table.new data, options
|
30
|
-
end
|
31
|
-
|
32
|
-
# +format+ : :csv, :txt, or :xls
|
33
|
-
# Returns Array of Arrays
|
34
|
-
def self.read_file(file_path, format)
|
35
|
-
case format
|
36
|
-
when :xls
|
37
|
-
require "spreadsheet"
|
38
|
-
# Row#to_a coerces Excel data to Strings, but we want Dates and Numbers
|
39
|
-
data = []
|
40
|
-
Spreadsheet.open(file_path).worksheets.first.each do |excel_row|
|
41
|
-
data << excel_row.inject([]) { |row, cell| row << cell; row }
|
42
|
-
end
|
43
|
-
data
|
44
|
-
when :txt
|
45
|
-
require "csv"
|
46
|
-
if RUBY_VERSION < "1.9"
|
47
|
-
::CSV.open(file_path, "r", "\t").collect { |row| row }
|
48
|
-
else
|
49
|
-
CSV.read(file_path, :col_sep => "\t")
|
50
|
-
end
|
51
|
-
when :csv
|
52
|
-
if RUBY_VERSION < "1.9"
|
53
|
-
require "fastercsv"
|
54
|
-
FasterCSV.read(file_path)
|
55
|
-
else
|
56
|
-
require "csv"
|
57
|
-
CSV.read(file_path)
|
58
|
-
end
|
59
|
-
else
|
60
|
-
raise "Cannot read '#{format}' format. Expected :xls, :xlsx, :txt, or :csv"
|
61
|
-
end
|
14
|
+
def self.read(file, options = {})
|
15
|
+
table = Table.new
|
16
|
+
table.read file, options[:as]
|
17
|
+
table
|
62
18
|
end
|
63
19
|
|
64
20
|
# Pass data in as +rows+. Expects rows to be an Enumerable of Enumerables.
|
65
21
|
# Maps rows to Hash-like Tabular::Rows.
|
66
|
-
|
67
|
-
# Options:
|
68
|
-
# :columns => { :original_name => :preferred_name, :column_name => { :column_type => :boolean } }
|
69
|
-
#
|
70
|
-
# The :columns option will likely be deprecated and options for mappers and renderers added
|
71
|
-
def initialize(rows = [], *options)
|
72
|
-
@options = Table.extract_options(options)
|
22
|
+
def initialize(rows = [])
|
73
23
|
self.rows = rows
|
74
24
|
end
|
75
25
|
|
@@ -103,9 +53,11 @@ module Tabular
|
|
103
53
|
cells = row
|
104
54
|
end
|
105
55
|
|
106
|
-
if @columns.nil?
|
107
|
-
@columns = Tabular::Columns.new(self, cells,
|
108
|
-
|
56
|
+
if @columns.nil?
|
57
|
+
@columns = Tabular::Columns.new(self, cells, column_mapper)
|
58
|
+
if !cells.respond_to?(:keys)
|
59
|
+
return columns
|
60
|
+
end
|
109
61
|
end
|
110
62
|
|
111
63
|
_row = Tabular::Row.new(self, cells, row)
|
@@ -122,7 +74,7 @@ module Tabular
|
|
122
74
|
|
123
75
|
# Instance of Tabular::Columns
|
124
76
|
def columns
|
125
|
-
@columns ||= Tabular::Columns.new(self, [])
|
77
|
+
@columns ||= Tabular::Columns.new(self, [], column_mapper)
|
126
78
|
end
|
127
79
|
|
128
80
|
# Remove all columns that only contain a blank string, zero, or nil
|
@@ -180,6 +132,13 @@ module Tabular
|
|
180
132
|
columns.renderers
|
181
133
|
end
|
182
134
|
|
135
|
+
def column_mapper=(mapper)
|
136
|
+
if rows.nil? || rows.size == 0
|
137
|
+
@columns = nil
|
138
|
+
end
|
139
|
+
@column_mapper = mapper
|
140
|
+
end
|
141
|
+
|
183
142
|
# Last-resort storage for client code data
|
184
143
|
def metadata
|
185
144
|
@metadata ||= {}
|
@@ -196,29 +155,6 @@ module Tabular
|
|
196
155
|
|
197
156
|
private
|
198
157
|
|
199
|
-
def self.extract_options(options)
|
200
|
-
if options
|
201
|
-
options.flatten.first || {}
|
202
|
-
else
|
203
|
-
{}
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
def self.format_from(as_option, file_path)
|
208
|
-
if as_option
|
209
|
-
as_option
|
210
|
-
else
|
211
|
-
case File.extname(file_path)
|
212
|
-
when ".xls", ".xlsx"
|
213
|
-
:xls
|
214
|
-
when ".txt"
|
215
|
-
:txt
|
216
|
-
when ".csv"
|
217
|
-
:csv
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
158
|
def extract_exceptions(options)
|
223
159
|
if options.first && options.first[:except]
|
224
160
|
options.first[:except]
|
data/lib/tabular/version.rb
CHANGED
data/tabular.gemspec
CHANGED
@@ -35,7 +35,5 @@ Gem::Specification.new do |s|
|
|
35
35
|
s.require_paths = ["lib"]
|
36
36
|
s.summary = "Read, write, and manipulate CSV, tab-delimited and Excel data"
|
37
37
|
|
38
|
-
s.add_development_dependency "
|
39
|
-
s.add_development_dependency "spreadsheet", "~> 0.6.6"
|
38
|
+
s.add_development_dependency "roo", "~> 1.3"
|
40
39
|
end
|
41
|
-
|
metadata
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tabular
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Willson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: roo
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: spreadsheet
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.6.6
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.6.6
|
26
|
+
version: '1.3'
|
41
27
|
description: Tabular is a Ruby library for reading, writing, and manipulating CSV,
|
42
28
|
tab-delimited and Excel data.
|
43
29
|
email: scott.willson@gmail.c0m
|
@@ -82,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
68
|
version: '0'
|
83
69
|
requirements: []
|
84
70
|
rubyforge_project:
|
85
|
-
rubygems_version: 2.
|
71
|
+
rubygems_version: 2.4.2
|
86
72
|
signing_key:
|
87
73
|
specification_version: 4
|
88
74
|
summary: Read, write, and manipulate CSV, tab-delimited and Excel data
|