roo 1.3.11 → 1.9.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.
@@ -1,9 +1,9 @@
1
- require 'xml'
1
+ require 'rubygems'
2
2
  require 'fileutils'
3
3
  require 'zip/zipfilesystem'
4
4
  require 'date'
5
5
  require 'base64'
6
- require 'cgi'
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
- return_sheets << sheet.attributes['name']
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
- @officeversion = office.attributes['version']
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
- @doc.find("//*[local-name()='table']").each do |ws|
271
- if sheet == ws.attributes['name']
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
- skip_col = cell.attributes['number-columns-repeated']
286
- formula = cell.attributes['formula']
287
- vt = cell.attributes['value-type']
288
- v = cell.attributes['value']
289
- style_name = cell.attributes['style-name']
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!(/&apos;/,"'") # special case not supported by unescapeHTML
307
358
  str_v = CGI.unescapeHTML(str_v)
308
359
  end # == 'p'
309
- end
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
@@ -1,9 +1,9 @@
1
- module Roo #:nodoc:
2
- module VERSION #:nodoc:
3
- MAJOR = 1
4
- MINOR = 3
5
- TINY = 9
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
@@ -0,0 +1,80 @@
1
+
2
+ begin
3
+ require 'bones/smtp_tls'
4
+ rescue LoadError
5
+ require 'net/smtp'
6
+ end
7
+ require 'time'
8
+
9
+ namespace :ann do
10
+
11
+ # A prerequisites task that all other tasks depend upon
12
+ task :prereqs
13
+
14
+ file PROJ.ann.file do
15
+ ann = PROJ.ann
16
+ puts "Generating #{ann.file}"
17
+ File.open(ann.file,'w') do |fd|
18
+ fd.puts("#{PROJ.name} version #{PROJ.version}")
19
+ fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
20
+ fd.puts(" #{PROJ.url}") if PROJ.url.valid?
21
+ fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
22
+ fd.puts
23
+ fd.puts("== DESCRIPTION")
24
+ fd.puts
25
+ fd.puts(PROJ.description)
26
+ fd.puts
27
+ fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
28
+ fd.puts
29
+ ann.paragraphs.each do |p|
30
+ fd.puts "== #{p.upcase}"
31
+ fd.puts
32
+ fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
33
+ fd.puts
34
+ end
35
+ fd.puts ann.text if ann.text
36
+ end
37
+ end
38
+
39
+ desc "Create an announcement file"
40
+ task :announcement => ['ann:prereqs', PROJ.ann.file]
41
+
42
+ desc "Send an email announcement"
43
+ task :email => ['ann:prereqs', PROJ.ann.file] do
44
+ ann = PROJ.ann
45
+ from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
46
+ to = Array(ann.email[:to])
47
+
48
+ ### build a mail header for RFC 822
49
+ rfc822msg = "From: #{from}\n"
50
+ rfc822msg << "To: #{to.join(',')}\n"
51
+ rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
52
+ rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
53
+ rfc822msg << "\n"
54
+ rfc822msg << "Date: #{Time.new.rfc822}\n"
55
+ rfc822msg << "Message-Id: "
56
+ rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
57
+ rfc822msg << File.read(ann.file)
58
+
59
+ params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
60
+ ann.email[key]
61
+ end
62
+
63
+ params[3] = PROJ.email if params[3].nil?
64
+
65
+ if params[4].nil?
66
+ STDOUT.write "Please enter your e-mail password (#{params[3]}): "
67
+ params[4] = STDIN.gets.chomp
68
+ end
69
+
70
+ ### send email
71
+ Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
72
+ end
73
+ end # namespace :ann
74
+
75
+ desc 'Alias to ann:announcement'
76
+ task :ann => 'ann:announcement'
77
+
78
+ CLOBBER << PROJ.ann.file
79
+
80
+ # EOF
@@ -0,0 +1,20 @@
1
+
2
+ if HAVE_BONES
3
+
4
+ namespace :bones do
5
+
6
+ desc 'Show the PROJ open struct'
7
+ task :debug do |t|
8
+ atr = if t.application.top_level_tasks.length == 2
9
+ t.application.top_level_tasks.pop
10
+ end
11
+
12
+ if atr then Bones::Debug.show_attr(PROJ, atr)
13
+ else Bones::Debug.show PROJ end
14
+ end
15
+
16
+ end # namespace :bones
17
+
18
+ end # HAVE_BONES
19
+
20
+ # EOF
@@ -0,0 +1,201 @@
1
+
2
+ require 'find'
3
+ require 'rake/packagetask'
4
+ require 'rubygems/user_interaction'
5
+ require 'rubygems/builder'
6
+
7
+ module Bones
8
+ class GemPackageTask < Rake::PackageTask
9
+ # Ruby GEM spec containing the metadata for this package. The
10
+ # name, version and package_files are automatically determined
11
+ # from the GEM spec and don't need to be explicitly provided.
12
+ #
13
+ attr_accessor :gem_spec
14
+
15
+ # Tasks from the Bones gem directory
16
+ attr_reader :bones_files
17
+
18
+ # Create a GEM Package task library. Automatically define the gem
19
+ # if a block is given. If no block is supplied, then +define+
20
+ # needs to be called to define the task.
21
+ #
22
+ def initialize(gem_spec)
23
+ init(gem_spec)
24
+ yield self if block_given?
25
+ define if block_given?
26
+ end
27
+
28
+ # Initialization tasks without the "yield self" or define
29
+ # operations.
30
+ #
31
+ def init(gem)
32
+ super(gem.name, gem.version)
33
+ @gem_spec = gem
34
+ @package_files += gem_spec.files if gem_spec.files
35
+ @bones_files = []
36
+
37
+ local_setup = File.join(Dir.pwd, %w[tasks setup.rb])
38
+ if !test(?e, local_setup)
39
+ Dir.glob(::Bones.path(%w[lib bones tasks *])).each {|fn| bones_files << fn}
40
+ end
41
+ end
42
+
43
+ # Create the Rake tasks and actions specified by this
44
+ # GemPackageTask. (+define+ is automatically called if a block is
45
+ # given to +new+).
46
+ #
47
+ def define
48
+ super
49
+ task :prereqs
50
+ task :package => ['gem:prereqs', "#{package_dir_path}/#{gem_file}"]
51
+ file "#{package_dir_path}/#{gem_file}" => [package_dir_path] + package_files + bones_files do
52
+ when_writing("Creating GEM") {
53
+ chdir(package_dir_path) do
54
+ Gem::Builder.new(gem_spec).build
55
+ verbose(true) {
56
+ mv gem_file, "../#{gem_file}"
57
+ }
58
+ end
59
+ }
60
+ end
61
+
62
+ file package_dir_path => bones_files do
63
+ mkdir_p package_dir rescue nil
64
+
65
+ gem_spec.files = (gem_spec.files +
66
+ bones_files.map {|fn| File.join('tasks', File.basename(fn))}).sort
67
+
68
+ bones_files.each do |fn|
69
+ base_fn = File.join('tasks', File.basename(fn))
70
+ f = File.join(package_dir_path, base_fn)
71
+ fdir = File.dirname(f)
72
+ mkdir_p(fdir) if !File.exist?(fdir)
73
+ if File.directory?(fn)
74
+ mkdir_p(f)
75
+ else
76
+ raise "file name conflict for '#{base_fn}' (conflicts with '#{fn}')" if test(?e, f)
77
+ safe_ln(fn, f)
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def gem_file
84
+ if @gem_spec.platform == Gem::Platform::RUBY
85
+ "#{package_name}.gem"
86
+ else
87
+ "#{package_name}-#{@gem_spec.platform}.gem"
88
+ end
89
+ end
90
+ end # class GemPackageTask
91
+ end # module Bones
92
+
93
+ namespace :gem do
94
+
95
+ PROJ.gem._spec = Gem::Specification.new do |s|
96
+ s.name = PROJ.name
97
+ s.version = PROJ.version
98
+ s.summary = PROJ.summary
99
+ s.authors = Array(PROJ.authors)
100
+ s.email = PROJ.email
101
+ s.homepage = Array(PROJ.url).first
102
+ s.rubyforge_project = PROJ.rubyforge.name
103
+
104
+ s.description = PROJ.description
105
+
106
+ PROJ.gem.dependencies.each do |dep|
107
+ s.add_dependency(*dep)
108
+ end
109
+
110
+ PROJ.gem.development_dependencies.each do |dep|
111
+ s.add_development_dependency(*dep)
112
+ end
113
+
114
+ s.files = PROJ.gem.files
115
+ s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)}
116
+ s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/
117
+
118
+ s.bindir = 'bin'
119
+ dirs = Dir["{#{PROJ.libs.join(',')}}"]
120
+ s.require_paths = dirs unless dirs.empty?
121
+
122
+ incl = Regexp.new(PROJ.rdoc.include.join('|'))
123
+ excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
124
+ excl = Regexp.new(excl.join('|'))
125
+ rdoc_files = PROJ.gem.files.find_all do |fn|
126
+ case fn
127
+ when excl; false
128
+ when incl; true
129
+ else false end
130
+ end
131
+ s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main]
132
+ s.extra_rdoc_files = rdoc_files
133
+ s.has_rdoc = true
134
+
135
+ if test ?f, PROJ.test.file
136
+ s.test_file = PROJ.test.file
137
+ else
138
+ s.test_files = PROJ.test.files.to_a
139
+ end
140
+
141
+ # Do any extra stuff the user wants
142
+ PROJ.gem.extras.each do |msg, val|
143
+ case val
144
+ when Proc
145
+ val.call(s.send(msg))
146
+ else
147
+ s.send "#{msg}=", val
148
+ end
149
+ end
150
+ end # Gem::Specification.new
151
+
152
+ Bones::GemPackageTask.new(PROJ.gem._spec) do |pkg|
153
+ pkg.need_tar = PROJ.gem.need_tar
154
+ pkg.need_zip = PROJ.gem.need_zip
155
+ end
156
+
157
+ desc 'Show information about the gem'
158
+ task :debug => 'gem:prereqs' do
159
+ puts PROJ.gem._spec.to_ruby
160
+ end
161
+
162
+ desc 'Write the gemspec '
163
+ task :spec => 'gem:prereqs' do
164
+ File.open("#{PROJ.name}.gemspec", 'w') do |f|
165
+ f.write PROJ.gem._spec.to_ruby
166
+ end
167
+ end
168
+
169
+ desc 'Install the gem'
170
+ task :install => [:clobber, 'gem:package'] do
171
+ sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
172
+
173
+ # use this version of the command for rubygems > 1.0.0
174
+ #sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}"
175
+ end
176
+
177
+ desc 'Uninstall the gem'
178
+ task :uninstall do
179
+ installed_list = Gem.source_index.find_name(PROJ.name)
180
+ if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then
181
+ sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}"
182
+ end
183
+ end
184
+
185
+ desc 'Reinstall the gem'
186
+ task :reinstall => [:uninstall, :install]
187
+
188
+ desc 'Cleanup the gem'
189
+ task :cleanup do
190
+ sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}"
191
+ end
192
+ end # namespace :gem
193
+
194
+
195
+ desc 'Alias to gem:package'
196
+ task :gem => 'gem:package'
197
+
198
+ task :clobber => 'gem:clobber_package'
199
+ remove_desc_for_task 'gem:clobber_package'
200
+
201
+ # EOF