tabular 0.2.7 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|