donibuchanan-roo 1.3.12 → 1.9.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +26 -6
- data/lib/roo/excel.rb +83 -45
- data/lib/roo/excelx.rb +241 -69
- data/lib/roo/generic_spreadsheet.rb +34 -8
- data/lib/roo/google.rb +63 -117
- data/lib/roo/openoffice.rb +79 -27
- data/lib/roo/version.rb +9 -9
- data/lib/roo.rb +56 -13
- data/test/1900_base.xls +0 -0
- data/test/1904_base.xls +0 -0
- data/test/Bibelbund.csv +0 -0
- data/test/bode-v1.ods.zip +0 -0
- data/test/bode-v1.xls.zip +0 -0
- data/test/boolean.xls +0 -0
- data/test/datetime.xls +0 -0
- data/test/numbers1.csv +0 -0
- data/test/test_helper.rb +1 -1
- data/test/test_roo.rb +381 -269
- data/test/whitespace.xls +0 -0
- metadata +2 -1
data/lib/roo/google.rb
CHANGED
@@ -1,100 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
require
|
1
|
+
#require 'xml'
|
2
|
+
require "google_spreadsheet"
|
3
3
|
|
4
4
|
class GoogleHTTPError < RuntimeError; end
|
5
5
|
class GoogleReadError < RuntimeError; end
|
6
6
|
class GoogleWriteError < RuntimeError; end
|
7
7
|
|
8
|
-
# overwrite some methods from the gdata-gem:
|
9
|
-
module GData
|
10
|
-
class Spreadsheet < GData::Base
|
11
|
-
|
12
|
-
def visibility
|
13
|
-
@headers ? "private" : "public"
|
14
|
-
end
|
15
|
-
|
16
|
-
def projection
|
17
|
-
@headers ? "full" : "values"
|
18
|
-
end
|
19
|
-
|
20
|
-
#-- modified
|
21
|
-
def evaluate_cell(cell, sheet_no=1)
|
22
|
-
raise ArgumentError, "invalid cell: #{cell}" unless cell
|
23
|
-
raise ArgumentError, "invalid sheet_no: #{sheet_no}" unless sheet_no >0 and sheet_no.class == Fixnum
|
24
|
-
path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{visibility}/#{projection}/#{cell}"
|
25
|
-
doc = Hpricot(request(path))
|
26
|
-
result = (doc/"content").inner_html
|
27
|
-
end
|
28
|
-
|
29
|
-
#-- new
|
30
|
-
def sheetlist
|
31
|
-
path = "/feeds/worksheets/#{@spreadsheet_id}/#{visibility}/#{projection}"
|
32
|
-
doc = Hpricot(request(path))
|
33
|
-
result = []
|
34
|
-
(doc/"content").each { |elem|
|
35
|
-
result << elem.inner_html
|
36
|
-
}
|
37
|
-
if result.size == 0
|
38
|
-
if (doc/"h2").inner_html =~ /Error/
|
39
|
-
raise GoogleHTTPError, "#{(doc/'h2').inner_html}: #{(doc/'title').inner_html} [key '#{@spreadsheet_id}']"
|
40
|
-
else
|
41
|
-
raise GoogleReadError, "#{doc} [key '#{@spreadsheet_id}']"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
result
|
45
|
-
end
|
46
|
-
|
47
|
-
#-- new
|
48
|
-
#@@ added sheet_no to definition
|
49
|
-
def save_entry_roo(entry, sheet_no)
|
50
|
-
raise GoogleWriteError, "unable to write to public spreadsheets" if visibility == 'public'
|
51
|
-
path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{visibility}/#{projection}"
|
52
|
-
post(path, entry)
|
53
|
-
end
|
54
|
-
|
55
|
-
#-- new
|
56
|
-
def entry_roo(formula, row=1, col=1)
|
57
|
-
<<-XML
|
58
|
-
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'>
|
59
|
-
<gs:cell row='#{row}' col='#{col}' inputValue='#{formula}' />
|
60
|
-
</entry>
|
61
|
-
XML
|
62
|
-
end
|
63
|
-
|
64
|
-
#-- new
|
65
|
-
#@@ added sheet_no to definition
|
66
|
-
def add_to_cell_roo(row,col,value, sheet_no=1)
|
67
|
-
save_entry_roo(entry_roo(value,row,col), sheet_no)
|
68
|
-
end
|
69
|
-
|
70
|
-
#-- new
|
71
|
-
def get_one_sheet
|
72
|
-
path = "/feeds/cells/#{@spreadsheet_id}/1/#{visibility}/#{projection}"
|
73
|
-
doc = Hpricot(request(path))
|
74
|
-
end
|
75
|
-
|
76
|
-
#new
|
77
|
-
def oben_unten_links_rechts(sheet_no)
|
78
|
-
path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{visibility}/#{projection}"
|
79
|
-
doc = Hpricot(request(path))
|
80
|
-
rows = []
|
81
|
-
cols = []
|
82
|
-
(doc/"gs:cell").each {|item|
|
83
|
-
rows.push item['row'].to_i
|
84
|
-
cols.push item['col'].to_i
|
85
|
-
}
|
86
|
-
return rows.min, rows.max, cols.min, cols.max
|
87
|
-
end
|
88
|
-
|
89
|
-
def fulldoc(sheet_no)
|
90
|
-
path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{visibility}/#{projection}"
|
91
|
-
doc = Hpricot(request(path))
|
92
|
-
return doc
|
93
|
-
end
|
94
|
-
|
95
|
-
end # class
|
96
|
-
end # module
|
97
|
-
|
98
8
|
class Google < GenericSpreadsheet
|
99
9
|
attr_accessor :date_format, :datetime_format
|
100
10
|
|
@@ -122,10 +32,13 @@ class Google < GenericSpreadsheet
|
|
122
32
|
@date_format = '%d/%m/%Y'
|
123
33
|
@datetime_format = '%d/%m/%Y %H:%M:%S'
|
124
34
|
@time_format = '%H:%M:%S'
|
125
|
-
|
126
|
-
@
|
127
|
-
@
|
35
|
+
session = GoogleSpreadsheet.login(user, password)
|
36
|
+
@sheetlist = []
|
37
|
+
session.spreadsheet_by_key(@spreadsheetkey).worksheets.each { |sheet|
|
38
|
+
@sheetlist << sheet.title
|
39
|
+
}
|
128
40
|
@default_sheet = self.sheets.first
|
41
|
+
@worksheets = session.spreadsheet_by_key(@spreadsheetkey).worksheets
|
129
42
|
end
|
130
43
|
|
131
44
|
# returns an array of sheet names in the spreadsheet
|
@@ -276,7 +189,7 @@ class Google < GenericSpreadsheet
|
|
276
189
|
raise RangeError, "invalid sheet '"+sheet.to_s+"'"
|
277
190
|
end
|
278
191
|
row,col = normalize(row,col)
|
279
|
-
|
192
|
+
add_to_cell_roo(row,col,value,sheet_no)
|
280
193
|
# re-read the portion of the document that has changed
|
281
194
|
if @cells_read[sheet]
|
282
195
|
key = "#{row},#{col}"
|
@@ -291,7 +204,8 @@ class Google < GenericSpreadsheet
|
|
291
204
|
sheet = @default_sheet unless sheet
|
292
205
|
unless @first_row[sheet]
|
293
206
|
sheet_no = sheets.index(sheet) + 1
|
294
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
207
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
208
|
+
oben_unten_links_rechts(sheet_no)
|
295
209
|
end
|
296
210
|
return @first_row[sheet]
|
297
211
|
end
|
@@ -301,7 +215,8 @@ class Google < GenericSpreadsheet
|
|
301
215
|
sheet = @default_sheet unless sheet
|
302
216
|
unless @last_row[sheet]
|
303
217
|
sheet_no = sheets.index(sheet) + 1
|
304
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
218
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
219
|
+
oben_unten_links_rechts(sheet_no)
|
305
220
|
end
|
306
221
|
return @last_row[sheet]
|
307
222
|
end
|
@@ -311,7 +226,8 @@ class Google < GenericSpreadsheet
|
|
311
226
|
sheet = @default_sheet unless sheet
|
312
227
|
unless @first_column[sheet]
|
313
228
|
sheet_no = sheets.index(sheet) + 1
|
314
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
229
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
230
|
+
oben_unten_links_rechts(sheet_no)
|
315
231
|
end
|
316
232
|
return @first_column[sheet]
|
317
233
|
end
|
@@ -321,7 +237,8 @@ class Google < GenericSpreadsheet
|
|
321
237
|
sheet = @default_sheet unless sheet
|
322
238
|
unless @last_column[sheet]
|
323
239
|
sheet_no = sheets.index(sheet) + 1
|
324
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
240
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
241
|
+
oben_unten_links_rechts(sheet_no)
|
325
242
|
end
|
326
243
|
return @last_column[sheet]
|
327
244
|
end
|
@@ -332,25 +249,31 @@ class Google < GenericSpreadsheet
|
|
332
249
|
def read_cells(sheet=nil)
|
333
250
|
sheet = @default_sheet unless sheet
|
334
251
|
raise RangeError, "illegal sheet <#{sheet}>" unless sheets.index(sheet)
|
335
|
-
sheet_no = sheets.index(sheet)
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
252
|
+
sheet_no = sheets.index(sheet)
|
253
|
+
ws = @worksheets[sheet_no]
|
254
|
+
for row in 1..ws.num_rows
|
255
|
+
for col in 1..ws.num_cols
|
256
|
+
key = "#{row},#{col}"
|
257
|
+
string_value = ws.input_value(row,col) # item['inputvalue'] || item['inputValue']
|
258
|
+
numeric_value = ws[row,col] #item['numericvalue'] || item['numericValue']
|
259
|
+
(value, value_type) = determine_datatype(string_value, numeric_value)
|
260
|
+
@cell[sheet][key] = value unless value == "" or value == nil
|
261
|
+
@cell_type[sheet][key] = value_type
|
262
|
+
@formula[sheet] = {} unless @formula[sheet]
|
263
|
+
@formula[sheet][key] = string_value if value_type == :formula
|
264
|
+
############
|
265
|
+
#$log.debug("key: #{key}")
|
266
|
+
#$log.debug "#{ws[row,col].inspect}"
|
267
|
+
#@cell[sheet][key] = ws[row,col]
|
268
|
+
#$log.debug "@cell[sheet][key]: #{@cell[sheet][key]}"
|
269
|
+
############
|
270
|
+
end
|
349
271
|
end
|
350
272
|
@cells_read[sheet] = true
|
351
273
|
end
|
352
274
|
|
353
275
|
def determine_datatype(val, numval=nil)
|
276
|
+
# $log.debug "val: #{val} numval: #{numval}"
|
354
277
|
if val.nil? || val[0,1] == '='
|
355
278
|
ty = :formula
|
356
279
|
if numeric?(numval)
|
@@ -372,8 +295,31 @@ class Google < GenericSpreadsheet
|
|
372
295
|
else
|
373
296
|
ty = :string
|
374
297
|
end
|
375
|
-
end
|
298
|
+
end
|
299
|
+
#$log.debug "val: #{val} ty: #{ty}" if ty == :date
|
376
300
|
return val, ty
|
377
301
|
end
|
378
|
-
|
379
|
-
|
302
|
+
|
303
|
+
def add_to_cell_roo(row,col,value, sheet_no=1)
|
304
|
+
sheet_no -= 1
|
305
|
+
@worksheets[sheet_no][row,col] = value
|
306
|
+
@worksheets[sheet_no].save
|
307
|
+
end
|
308
|
+
def entry_roo(value,row,col)
|
309
|
+
return value,row,col
|
310
|
+
end
|
311
|
+
|
312
|
+
def oben_unten_links_rechts(sheet_no)
|
313
|
+
ws = @worksheets[sheet_no-1]
|
314
|
+
rows = []
|
315
|
+
cols = []
|
316
|
+
for row in 1..ws.num_rows
|
317
|
+
for col in 1..ws.num_cols
|
318
|
+
rows << row if ws[row,col] and ws[row,col] != '' #TODO: besser?
|
319
|
+
cols << col if ws[row,col] and ws[row,col] != '' #TODO: besser?
|
320
|
+
end
|
321
|
+
end
|
322
|
+
return rows.min, rows.max, cols.min, cols.max
|
323
|
+
end
|
324
|
+
|
325
|
+
end # class
|
data/lib/roo/openoffice.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'rubygems'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'zip/zipfilesystem'
|
4
4
|
require 'date'
|
5
5
|
require 'base64'
|
6
|
-
require '
|
6
|
+
require 'nokogiri'
|
7
7
|
|
8
8
|
class Openoffice < GenericSpreadsheet
|
9
9
|
|
@@ -36,7 +36,8 @@ class Openoffice < GenericSpreadsheet
|
|
36
36
|
@file_nr = @@nr
|
37
37
|
extract_content
|
38
38
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_content.xml"))
|
39
|
-
@doc = XML::Parser.io(file).parse
|
39
|
+
#TODO: @doc = XML::Parser.io(file).parse
|
40
|
+
@doc = Nokogiri::XML(file)
|
40
41
|
file.close
|
41
42
|
ensure
|
42
43
|
#if ENV["roo_local"] != "thomas-p"
|
@@ -55,6 +56,7 @@ class Openoffice < GenericSpreadsheet
|
|
55
56
|
@style_defaults = Hash.new { |h,k| h[k] = [] }
|
56
57
|
@style_definitions = Hash.new
|
57
58
|
@header_line = 1
|
59
|
+
@labels = {}
|
58
60
|
end
|
59
61
|
|
60
62
|
# creates a new empty openoffice-spreadsheet file
|
@@ -78,7 +80,8 @@ class Openoffice < GenericSpreadsheet
|
|
78
80
|
read_cells(sheet) unless @cells_read[sheet]
|
79
81
|
row,col = normalize(row,col)
|
80
82
|
if celltype(row,col,sheet) == :date
|
81
|
-
yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
|
83
|
+
#TODO: yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
|
84
|
+
yyyy,mm,dd = @cell[sheet][[row,col]].to_s.split('-')
|
82
85
|
return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
|
83
86
|
end
|
84
87
|
@cell[sheet][[row,col]]
|
@@ -170,8 +173,10 @@ class Openoffice < GenericSpreadsheet
|
|
170
173
|
|
171
174
|
def sheets
|
172
175
|
return_sheets = []
|
173
|
-
@doc.find("//*[local-name()='table']").each do |sheet|
|
174
|
-
|
176
|
+
#TODO: @doc.find("//*[local-name()='table']").each do |sheet|
|
177
|
+
@doc.xpath("//*[local-name()='table']").each do |sheet|
|
178
|
+
#TODO: return_sheets << sheet.attributes['name']
|
179
|
+
return_sheets << sheet['name']
|
175
180
|
end
|
176
181
|
return_sheets
|
177
182
|
end
|
@@ -213,12 +218,29 @@ class Openoffice < GenericSpreadsheet
|
|
213
218
|
theformulas
|
214
219
|
end
|
215
220
|
|
221
|
+
# returns the row,col values of the labelled cell
|
222
|
+
# (nil,nil) if label is not defined
|
223
|
+
# sheet parameter is not really needed because label names are global
|
224
|
+
# to the whole spreadsheet
|
225
|
+
def label(labelname,sheet=nil)
|
226
|
+
sheet = @default_sheet unless sheet
|
227
|
+
read_cells(sheet) unless @cells_read[sheet]
|
228
|
+
if @labels.has_key? labelname
|
229
|
+
return @labels[labelname][1].to_i,
|
230
|
+
GenericSpreadsheet.letter_to_number(@labels[labelname][2]),
|
231
|
+
@labels[labelname][0]
|
232
|
+
else
|
233
|
+
return nil,nil,nil
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
216
237
|
private
|
217
238
|
|
218
239
|
# read the version of the OO-Version
|
219
240
|
def oo_version
|
220
|
-
@doc.find("//*[local-name()='document-content']").each do |office|
|
221
|
-
|
241
|
+
#TODO: @doc.find("//*[local-name()='document-content']").each do |office|
|
242
|
+
@doc.xpath("//*[local-name()='document-content']").each do |office|
|
243
|
+
@officeversion = office.attributes['version'].to_s
|
222
244
|
end
|
223
245
|
end
|
224
246
|
|
@@ -238,10 +260,11 @@ class Openoffice < GenericSpreadsheet
|
|
238
260
|
when :string
|
239
261
|
@cell[sheet][key] = str_v
|
240
262
|
when :date
|
241
|
-
if table_cell.attributes['date-value'].size != "XXXX-XX-XX".size
|
263
|
+
#TODO: if table_cell.attributes['date-value'].size != "XXXX-XX-XX".size
|
264
|
+
if table_cell.attributes['date-value'].to_s.size != "XXXX-XX-XX".size
|
242
265
|
#-- dann ist noch eine Uhrzeit vorhanden
|
243
266
|
#-- "1961-11-21T12:17:18"
|
244
|
-
@cell[sheet][key] = DateTime.parse(table_cell.attributes['date-value'])
|
267
|
+
@cell[sheet][key] = DateTime.parse(table_cell.attributes['date-value'].to_s)
|
245
268
|
@cell_type[sheet][key] = :datetime
|
246
269
|
else
|
247
270
|
@cell[sheet][key] = table_cell.attributes['date-value']
|
@@ -267,31 +290,59 @@ class Openoffice < GenericSpreadsheet
|
|
267
290
|
raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
|
268
291
|
raise RangeError unless self.sheets.include? sheet
|
269
292
|
|
270
|
-
|
271
|
-
|
293
|
+
#-
|
294
|
+
# Labels
|
295
|
+
# should be factored out in separate method because labels are global
|
296
|
+
# to the whole spreadsheet file (and not to specific sheet)
|
297
|
+
#+
|
298
|
+
@doc.xpath("//table:named-range").each do |ne|
|
299
|
+
#-
|
300
|
+
# $Sheet1.$C$5
|
301
|
+
#+
|
302
|
+
name = ne.attribute('name').to_s
|
303
|
+
sheetname,coords = ne.attribute('cell-range-address').to_s.split('.')
|
304
|
+
col = coords.split('$')[1]
|
305
|
+
row = coords.split('$')[2]
|
306
|
+
sheetname = sheetname[1..-1] if sheetname[0,1] == '$'
|
307
|
+
@labels[name] = [sheetname,row,col]
|
308
|
+
end
|
309
|
+
|
310
|
+
#TODO: @doc.find("//*[local-name()='table']").each do |ws|
|
311
|
+
@doc.xpath("//*[local-name()='table']").each do |ws|
|
312
|
+
#TODO: if sheet == ws.attributes['name']
|
313
|
+
if sheet == ws['name']
|
272
314
|
sheet_found = true
|
273
315
|
col = 1
|
274
316
|
row = 1
|
275
|
-
ws.each_element do |table_element|
|
317
|
+
#TODO: ws.each_element do |table_element|
|
318
|
+
ws.children.each do |table_element|
|
276
319
|
case table_element.name
|
277
320
|
when 'table-column'
|
278
321
|
@style_defaults[sheet] << table_element.attributes['default-cell-style-name']
|
279
322
|
when 'table-row'
|
280
323
|
if table_element.attributes['number-rows-repeated']
|
281
|
-
skip_row = table_element.attributes['number-rows-repeated'].to_i
|
324
|
+
#TODO: skip_row = table_element.attributes['number-rows-repeated'].to_i
|
325
|
+
skip_row = table_element.attributes['number-rows-repeated'].to_s.to_i
|
282
326
|
row = row + skip_row - 1
|
283
327
|
end
|
284
|
-
table_element.each_element do |cell|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
328
|
+
#TODO: table_element.each_element do |cell|
|
329
|
+
table_element.children.each do |cell|
|
330
|
+
#TODO: skip_col = cell.attributes['number-columns-repeated']
|
331
|
+
skip_col = cell['number-columns-repeated']
|
332
|
+
#TODO: formula = cell.attributes['formula']
|
333
|
+
formula = cell['formula']
|
334
|
+
#TODO: vt = cell.attributes['value-type']
|
335
|
+
vt = cell['value-type']
|
336
|
+
#TODO: v = cell.attributes['value']
|
337
|
+
v = cell['value']
|
338
|
+
#TODO: style_name = cell.attributes['style-name']
|
339
|
+
style_name = cell['style-name']
|
290
340
|
if vt == 'string'
|
291
341
|
str_v = ''
|
292
342
|
# insert \n if there is more than one paragraph
|
293
343
|
para_count = 0
|
294
|
-
cell.each_element do |str|
|
344
|
+
#TODO: cell.each_element do |str|
|
345
|
+
cell.children.each do |str|
|
295
346
|
if str.name == 'p'
|
296
347
|
v = str.content
|
297
348
|
str_v += "\n" if para_count > 0
|
@@ -306,9 +357,10 @@ class Openoffice < GenericSpreadsheet
|
|
306
357
|
str_v.gsub!(/'/,"'") # special case not supported by unescapeHTML
|
307
358
|
str_v = CGI.unescapeHTML(str_v)
|
308
359
|
end # == 'p'
|
309
|
-
|
360
|
+
end
|
310
361
|
elsif vt == 'time'
|
311
|
-
cell.each_element do |str|
|
362
|
+
#TODO: cell.each_element do |str|
|
363
|
+
cell.children.each do |str|
|
312
364
|
if str.name == 'p'
|
313
365
|
v = str.content
|
314
366
|
end
|
@@ -322,8 +374,7 @@ class Openoffice < GenericSpreadsheet
|
|
322
374
|
elsif vt == 'float'
|
323
375
|
#
|
324
376
|
elsif vt == 'boolean'
|
325
|
-
v = cell.attributes['boolean-value']
|
326
|
-
#
|
377
|
+
v = cell.attributes['boolean-value'].to_s
|
327
378
|
else
|
328
379
|
# raise "unknown type #{vt}"
|
329
380
|
end
|
@@ -345,7 +396,8 @@ class Openoffice < GenericSpreadsheet
|
|
345
396
|
end
|
346
397
|
end
|
347
398
|
|
348
|
-
@doc.find("//*[local-name()='automatic-styles']").each do |style|
|
399
|
+
#TODO: @doc.find("//*[local-name()='automatic-styles']").each do |style|
|
400
|
+
@doc.xpath("//*[local-name()='automatic-styles']").each do |style|
|
349
401
|
read_styles(style)
|
350
402
|
end
|
351
403
|
if !sheet_found
|
@@ -434,7 +486,7 @@ class Openoffice < GenericSpreadsheet
|
|
434
486
|
result = result + child.content
|
435
487
|
else
|
436
488
|
if child.name == 's'
|
437
|
-
compressed_spaces = child.attributes['c'].to_i
|
489
|
+
compressed_spaces = child.attributes['c'].to_s.to_i
|
438
490
|
# no explicit number means a count of 1:
|
439
491
|
if compressed_spaces == 0
|
440
492
|
compressed_spaces = 1
|
data/lib/roo/version.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
module Roo #:nodoc:
|
2
|
-
module VERSION #:nodoc:
|
3
|
-
MAJOR = 1
|
4
|
-
MINOR = 3
|
5
|
-
TINY =
|
6
|
-
|
7
|
-
STRING = [MAJOR, MINOR, TINY].join('.')
|
8
|
-
end
|
9
|
-
end
|
1
|
+
#module Roo #:nodoc:
|
2
|
+
# module VERSION #:nodoc:
|
3
|
+
# MAJOR = 1
|
4
|
+
# MINOR = 3
|
5
|
+
# TINY = 6
|
6
|
+
#
|
7
|
+
# STRING = [MAJOR, MINOR, TINY].join('.')
|
8
|
+
# end
|
9
|
+
#end
|
data/lib/roo.rb
CHANGED
@@ -1,4 +1,48 @@
|
|
1
|
+
|
1
2
|
module Roo
|
3
|
+
|
4
|
+
# :stopdoc:
|
5
|
+
VERSION = '1.9.2'
|
6
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
7
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
8
|
+
# :startdoc:
|
9
|
+
|
10
|
+
# Returns the version string for the library.
|
11
|
+
#
|
12
|
+
def self.version
|
13
|
+
VERSION
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the library path for the module. If any arguments are given,
|
17
|
+
# they will be joined to the end of the libray path using
|
18
|
+
# <tt>File.join</tt>.
|
19
|
+
#
|
20
|
+
def self.libpath( *args )
|
21
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the lpath for the module. If any arguments are given,
|
25
|
+
# they will be joined to the end of the path using
|
26
|
+
# <tt>File.join</tt>.
|
27
|
+
#
|
28
|
+
def self.path( *args )
|
29
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Utility method used to require all files ending in .rb that lie in the
|
33
|
+
# directory below this file that has the same name as the filename passed
|
34
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
35
|
+
# the _filename_ does not have to be equivalent to the directory.
|
36
|
+
#
|
37
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
38
|
+
dir ||= ::File.basename(fname, '.*')
|
39
|
+
search_me = ::File.expand_path(
|
40
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
41
|
+
Dir.glob(search_me).sort.each {|rb|
|
42
|
+
puts "DEBUG: require #{rb}"
|
43
|
+
require rb}
|
44
|
+
end
|
45
|
+
|
2
46
|
class Spreadsheet
|
3
47
|
class << self
|
4
48
|
def open(file)
|
@@ -9,24 +53,23 @@ module Roo
|
|
9
53
|
Excelx.new(file)
|
10
54
|
when '.ods'
|
11
55
|
Openoffice.new(file)
|
12
|
-
|
13
|
-
Excel2003XML.new(file)
|
14
|
-
when ''
|
15
|
-
Google.new(file)
|
56
|
+
# when ''
|
16
57
|
else
|
17
|
-
|
18
|
-
|
58
|
+
Google.new(file)
|
59
|
+
# else
|
60
|
+
# raise ArgumentError, "Don't know how to open file #{file}"
|
61
|
+
end
|
19
62
|
end
|
20
63
|
end
|
21
64
|
end
|
22
|
-
end
|
65
|
+
end # module Roo
|
23
66
|
|
24
|
-
require 'roo/
|
25
|
-
# require 'roo/spreadsheetparser' TODO:
|
26
|
-
require 'roo/generic_spreadsheet'
|
67
|
+
require 'roo/generic_spreadsheet'
|
27
68
|
require 'roo/openoffice'
|
28
69
|
require 'roo/excel'
|
29
70
|
require 'roo/excelx'
|
30
|
-
require 'roo/google'
|
31
|
-
|
32
|
-
|
71
|
+
#require 'roo/google'
|
72
|
+
|
73
|
+
#Roo.require_all_libs_relative_to(__FILE__)
|
74
|
+
|
75
|
+
# EOF
|
data/test/1900_base.xls
CHANGED
File without changes
|
data/test/1904_base.xls
CHANGED
File without changes
|
data/test/Bibelbund.csv
CHANGED
File without changes
|
data/test/bode-v1.ods.zip
CHANGED
File without changes
|
data/test/bode-v1.xls.zip
CHANGED
File without changes
|
data/test/boolean.xls
CHANGED
File without changes
|
data/test/datetime.xls
CHANGED
Binary file
|
data/test/numbers1.csv
CHANGED
File without changes
|
data/test/test_helper.rb
CHANGED