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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dff94cc74c5cfbb23e9dfb56d2c4fb7091bab946
4
- data.tar.gz: 9e0c5f281e4d5d967881692d06fac660d6b3ba00
3
+ metadata.gz: a72f7305b34731c1fb2e479cfbb0a13039dfd840
4
+ data.tar.gz: 11cca1a77c8687abbe9f026edee0422239ff2937
5
5
  SHA512:
6
- metadata.gz: 32feb486e35a7be09e36188c8e052f4345bdd00dcbc74e32aca381c4447c5a3f59eba3ca287ff0f81bd3a7e4764b8ea81400039a43a01fbb22ae07ee70e33bc5
7
- data.tar.gz: a1a5fc2bcc055a00478027c63f35c35498159139b9367591706bcdf319e0d8ad902771eb093df54238c54eaf8fe174946370899474d90db722d5ad8c0b5bdd14
6
+ metadata.gz: 298c71843ce790a2f6db8ff682c6fed2665b598234e0703384805f40beb2273193dd280b90e979287635d61ce7e2c95b305fc4842ed1b9befbfc13da5ddbbc7e
7
+ data.tar.gz: c522ca24515089828157fffc266450d7b45fd5993f8439ee1df67d60e7e7706b5c51b837956652edbaddb7397313262f236456cab97a4eb7e24f83069638107e
data/Gemfile CHANGED
@@ -1,5 +1,4 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gem "rake"
4
- gem "ruby-ole", :git => "git://github.com/scottwillson/ruby-ole.git"
5
- gem "spreadsheet", :git => "git://github.com/scottwillson/spreadsheet.git"
4
+ gem "roo", github: "Empact/roo"
data/Gemfile.lock CHANGED
@@ -1,25 +1,27 @@
1
1
  GIT
2
- remote: git://github.com/scottwillson/ruby-ole.git
3
- revision: 6b9d2530b12259ca21af75ed2dcb26ba745a6115
2
+ remote: git://github.com/Empact/roo.git
3
+ revision: 4a1353de22e46880e656d9af062a1436eb5e1a9c
4
4
  specs:
5
- ruby-ole (1.2.11.3)
6
-
7
- GIT
8
- remote: git://github.com/scottwillson/spreadsheet.git
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
- ruby-ole!
25
- spreadsheet!
27
+ roo!
data/README CHANGED
@@ -14,17 +14,15 @@ Install
14
14
  -------
15
15
  sudo gem install tabular
16
16
 
17
- (The gem is hosted on Gemcutter, not RubyForge)
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 CSV: FasterCSV (http://fastercsv.rubyforge.org/)
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"
@@ -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+ is normalized to a downcase, underscored symbol
10
- def initialize(table, columns, key = nil, columns_map = {})
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 = symbolize(key)
15
- columns_map = columns_map || {}
16
- map_for_key = columns_map[key]
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
- raise "Expected Symbol or Hash, but was #{map_for_key.class}"
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
- def symbolize(key)
83
- return nil if is_blank?(key)
69
+ protected
84
70
 
85
- begin
86
- key.to_s.strip.gsub(/::/, '/').
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
@@ -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
- # +columns_map+ -- see Table. Maps column names and type conversion.
13
- def initialize(table, names, columns_map = {})
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
- columns_map ||= {}
16
- @columns_map = normalize_columns_map(columns_map)
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
- @columns = nil
21
- @columns = names.map do |column|
22
- new_column = Tabular::Column.new(table, self, column, @columns_map)
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, @columns_map)
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
- attr_reader :options, :rows
10
+ attr_accessor :column_mapper
10
11
  attr_accessor :row_mapper
12
+ attr_reader :rows
11
13
 
12
- # +file+ : file path as String or File
13
- # Assumes .txt = tab-delimited, .csv = CSV, .xls = Excel. Assumes first row is the header.
14
- # Normalizes column names to lower-case with underscores.
15
- def self.read(file, *options)
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? && !cells.respond_to?(:keys)
107
- @columns = Tabular::Columns.new(self, cells, options[:columns])
108
- return columns
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]
@@ -1,3 +1,3 @@
1
1
  module Tabular
2
- VERSION = "0.2.7"
2
+ VERSION = "0.3.0"
3
3
  end
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 "ruby-ole", "~> 1.2.11.3"
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.2.7
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-09-30 00:00:00.000000000 Z
11
+ date: 2014-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ruby-ole
14
+ name: roo
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.2.11.3
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.2.11.3
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.2.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