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 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