rspreadsheet 0.2.14 → 0.2.15

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: d2f168c71e8ec1b014d48658b230c03780c6fb40
4
- data.tar.gz: 11aaf6ed2a306be9eb3a2f3dcfa89dffed291f88
3
+ metadata.gz: 8c4d7239e35070d3406af3f5c7aadb872d5c0038
4
+ data.tar.gz: e06d7243078d7531984714f29ed403ce62fcc9df
5
5
  SHA512:
6
- metadata.gz: fa517af98e5a410bd50f9bb62a878b8752bed69bc77eb1cff3d50dcb05839c4a81956417a64a8b3f32b55376c1906d3c983c3260e426ccdc69145768063e6639
7
- data.tar.gz: 95e37cd4a06b66f107b612c8467ca91f2524bf61477208129e159dc0a479a476bc9be5e965eefd1b573c70919b2fd8cb28ce33d0eb5c299064cbef044bbe5a56
6
+ metadata.gz: dfe7532c19164f3f96611793df3eb75e2c5d67c9c3763cfaee72e88f1e060ec54d9c0978c3e59183520ddc05f0ab5a88d09f8e5e03d15fc4397de5a78740c81f
7
+ data.tar.gz: f84bbe8045dfe515ac18e50df5a7482e7e6ba0282b57ba2f1ffa50991d3aec3b45a60c7080d7183a867a3839bd7f639a801b0b7e90b9d7aec9a1a59ab1a5fa34
@@ -7,6 +7,8 @@ rvm:
7
7
  - 2.0.0
8
8
  - 1.9.3
9
9
  script: 'bundle exec rake'
10
+ before_install:
11
+ - gem update bundler
10
12
  notifications:
11
13
  email:
12
14
  recipients:
@@ -1,105 +1,49 @@
1
- if RUBY_VERSION > '2.1'
2
-
3
- module ClassExtensions
4
-
5
- refine Array do
6
- def sum(identity = 0, &block)
7
- if block_given?
8
- map(&block).sum(identity)
9
- else
10
- inject(0){ |sum, element| sum.to_f + element.to_f } || identity
11
- end
12
- end
13
- end
14
-
15
- refine LibXML::XML::Node do
16
- def ==(node2)
17
- self.simplification_of?(node2) and node2.simplification_of?(self)
18
- end
19
- # if node2 contains at least all that I do
20
- def simplification_of?(node2)
21
- first_diff(node2).nil?
22
- end
23
- # return first difference where self has something more than node2 does
24
- def first_diff(node2)
25
- where = self.path.split('/').last
26
-
27
- return "#{where}> Equivalent node does not exist: #{self.name} != NOTHING" if node2.nil?
28
- return "#{where}> Names are different: #{self.name} != #{node2.name}" if (self.name != node2.name)
29
- self.attributes.each do |attr|
30
- return "#{where}> Attribute #{attr} have diffent values: #{attr.value} != #{node2.attributes[attr.name]}" unless node2.attributes[attr.name] == attr.value
31
- end
32
-
33
- elems1 = self.elements
34
- elems2 = node2.elements
35
- # return "#{where}> elements have different number of subelements #{elems1.length} != #{elems2.length}" if (elems1.length != elems2.length)
36
- elems1.length.times do |i|
37
- if (elems1[i].node_type_name == 'text') && ((elems1[i].to_s != elems2[i].to_s) )
38
- return "#{where}> #{i+1}th text subelements are different: #{elems1[i].to_s} != #{elems2[i].to_s}"
39
- elsif (elems1[i].node_type_name == 'element') && (!elems1[i].simplification_of?(elems2[i]))
40
- return "#{where}/[#{i+1}]#{elems1[i].first_diff(elems2[i])}"
41
- end
42
- end
43
-
44
- return nil
45
- end
46
- def elements
47
- result = []
48
- each_element { |e| result << e }
49
- return result
50
- end
1
+ # @private
51
2
 
3
+ class LibXML::XML::Node
4
+ def elements
5
+ result = []
6
+ each_element { |e| result << e }
7
+ return result
8
+ end
9
+ # if node2 contains at least all that I do
10
+ def simplification_of?(node2)
11
+ first_diff(node2).nil?
12
+ end
13
+ # return first difference where self has something more than node2 does
14
+ def first_diff(node2)
15
+ where = self.path.split('/').last
16
+
17
+ return "#{where}> Equivalent node does not exist: #{self.name} != NOTHING" if node2.nil?
18
+ return "#{where}> Names are different: #{self.name} != #{node2.name}" if (self.name != node2.name)
19
+ self.attributes.each do |attr|
20
+ return "#{where}> Attribute #{attr} have diffent values: #{attr.value} != #{node2.attributes[attr.name]}" unless node2.attributes[attr.name] == attr.value
52
21
  end
53
22
 
54
- end # module ClassExtensions
55
-
56
- else # Monkeypatching
57
- class Array
58
- def sum(identity = 0, &block)
59
- if block_given?
60
- map(&block).sum(identity)
61
- else
62
- inject(0){ |sum, element| sum.to_f + element.to_f } || identity
23
+ elems1 = self.elements
24
+ elems2 = node2.elements
25
+ # return "#{where}> elements have different number of subelements #{elems1.length} != #{elems2.length}" if (elems1.length != elems2.length)
26
+ elems1.length.times do |i|
27
+ if (elems1[i].node_type_name == 'text') && ((elems1[i].to_s != elems2[i].to_s) )
28
+ return "#{where}> #{i+1}th text subelements are different: #{elems1[i].to_s} != #{elems2[i].to_s}"
29
+ elsif (elems1[i].node_type_name == 'element') && (!elems1[i].simplification_of?(elems2[i]))
30
+ return "#{where}/[#{i+1}]#{elems1[i].first_diff(elems2[i])}"
63
31
  end
64
32
  end
33
+
34
+ return nil
65
35
  end
36
+ def equals?(node2) #TODO redefine == with this
37
+ self.simplification_of?(node2) and node2.simplification_of?(self)
38
+ end
39
+ end
66
40
 
67
- class LibXML::XML::Node
68
- def ==(node2)
69
- self.simplification_of?(node2) and node2.simplification_of?(self)
70
- end
71
- # if node2 contains at least all that I do
72
- def simplification_of?(node2)
73
- first_diff(node2).nil?
41
+ class Array
42
+ def sum(identity = 0, &block)
43
+ if block_given?
44
+ map(&block).sum(identity)
45
+ else
46
+ inject(0){ |sum, element| sum.to_f + element.to_f } || identity
74
47
  end
75
- # return first difference where self has something more than node2 does
76
- def first_diff(node2)
77
- where = self.path.split('/').last
78
-
79
- return "#{where}> Equivalent node does not exist: #{self.name} != NOTHING" if node2.nil?
80
- return "#{where}> Names are different: #{self.name} != #{node2.name}" if (self.name != node2.name)
81
- self.attributes.each do |attr|
82
- return "#{where}> Attribute #{attr} have diffent values: #{attr.value} != #{node2.attributes[attr.name]}" unless node2.attributes[attr.name] == attr.value
83
- end
84
-
85
- elems1 = self.elements
86
- elems2 = node2.elements
87
- # return "#{where}> elements have different number of subelements #{elems1.length} != #{elems2.length}" if (elems1.length != elems2.length)
88
- elems1.length.times do |i|
89
- if (elems1[i].node_type_name == 'text') && ((elems1[i].to_s != elems2[i].to_s) )
90
- return "#{where}> #{i+1}th text subelements are different: #{elems1[i].to_s} != #{elems2[i].to_s}"
91
- elsif (elems1[i].node_type_name == 'element') && (!elems1[i].simplification_of?(elems2[i]))
92
- return "#{where}/[#{i+1}]#{elems1[i].first_diff(elems2[i])}"
93
- end
94
- end
95
-
96
- return nil
97
- end
98
- def elements
99
- result = []
100
- each_element { |e| result << e }
101
- return result
102
- end
103
-
104
48
  end
105
49
  end
@@ -7,10 +7,8 @@ require 'rspreadsheet/xml_tied'
7
7
  require 'date'
8
8
  require 'bigdecimal'
9
9
  require 'bigdecimal/util' # for to_d method
10
- require 'helpers/class_extensions'
11
10
 
12
11
  module Rspreadsheet
13
- using ClassExtensions if RUBY_VERSION > '2.1'
14
12
 
15
13
  ###
16
14
  # Represents a cell in spreadsheet which has coordinates, contains value, formula and can be formated.
@@ -42,7 +40,7 @@ class Cell < XMLTiedItem
42
40
  def coordinates; [rowi,coli] end
43
41
  def to_s; value.to_s end
44
42
  def valuexml; self.valuexmlnode.andand.inner_xml end
45
- def valuexmlnode; self.xmlnode.elements.first end
43
+ def valuexmlnode; self.xmlnode.children.first end
46
44
  # use this to find node in cell xml. ex. xmlfind('.//text:a') finds all link nodes
47
45
  def valuexmlfindall(path)
48
46
  valuexmlnode.nil? ? [] : valuexmlnode.find(path)
@@ -152,10 +150,10 @@ class Cell < XMLTiedItem
152
150
  when 'N/A' then :unassigned
153
151
  when 'currency' then :currency
154
152
  else
155
- if xmlnode.elements.size == 0
153
+ if xmlnode.children.size == 0
156
154
  nil
157
155
  else
158
- raise "Unknown type at #{coordinates.to_s} from #{xmlnode.to_s} / elements size=#{xmlnode.elements.size.to_s} / type=#{xmlnode.attributes['value-type'].to_s}"
156
+ raise "Unknown type at #{coordinates.to_s} from #{xmlnode.to_s} / children size=#{xmlnode.children.size.to_s} / type=#{xmlnode.attributes['value-type'].to_s}"
159
157
  end
160
158
  end
161
159
 
@@ -120,4 +120,353 @@ class Row < XMLTiedItem
120
120
  def set_index(value); @rowi=value end
121
121
  end
122
122
 
123
+ # class Row
124
+ # def initialize
125
+ # @readonly = :unknown
126
+ # @cells = {}
127
+ # end
128
+ # def worksheet; @parent_array.worksheet end
129
+ # def parent_array; @parent_array end # for debug only
130
+ # def used_col_range; 1..first_unused_column_index-1 end
131
+ # def used_range; used_col_range end
132
+ # def first_unused_column_index; raise 'this should be redefined in subclasses' end
133
+ # end
134
+
135
+
136
+ # --------------------------
137
+
138
+
139
+ # # XmlTiedArrayItemGroup is internal representation of repeated items in XmlTiedArray.
140
+ # class XmlTiedArrayItemGroup
141
+ # # extend Forwardable
142
+ # # delegate [:normalize ] => :@row_group
143
+ #
144
+ # def normalize; @rowgroup.normalize end
145
+
146
+ # end
147
+
148
+ # array which synchronizes with xml structure and reflects. number-xxx-repeated attributes
149
+ # also caches returned objects for indexes.
150
+ # options must contain
151
+ # :xml_items, :xml_repeated_attribute, :object_type
152
+
153
+ # class XmlTiedArray < Array
154
+ # def initialize(axmlnode, options={}) # TODO get rid of XmlTiedArray
155
+ # @xmlnode = axmlnode
156
+ # @options = options
157
+ #
158
+ # missing_options = [:xml_repeated_attribute,:xml_items_node_name,:object_type]-@options.keys
159
+ # raise "Some options missing (#{missing_options.inspect})" unless missing_options.empty?
160
+ #
161
+ # unless @xmlnode.nil?
162
+ # @xmlnode.elements.select{|node| node.name == options[:xml_items_node_name]}.each do |group_source_node|
163
+ # self << parse_xml_to_group(group_source_node) # it is in @xmlnode so suffices to add object to @rowgroups
164
+ # end
165
+ # end
166
+ # @itemcache=Hash.new()
167
+ # end
168
+ # def parse_xml_to_group(size_or_xmlnode) # parses xml to new RowGroup which can be added at the end
169
+ # # reading params
170
+ # if size_or_xmlnode.kind_of? LibXML::XML::Node
171
+ # size = (size_or_xmlnode[@options[:xml_repeated_attribute]] || 1).to_i
172
+ # node = size_or_xmlnode
173
+ # elsif size_or_xmlnode.to_i>0
174
+ # size = size_or_xmlnode.to_i
175
+ # node = nil
176
+ # else
177
+ # return nil
178
+ # end
179
+ # index = first_unused_index
180
+ # # construct result
181
+ # Rspreadsheet::XmlTiedArrayItemGroup.new(self,index..index+size-1,node)
182
+ # end
183
+ # def add_item_group(size_or_xmlnode)
184
+ # result = parse_xml_to_group(size_or_xmlnode)
185
+ # self << result
186
+ # @xmlnode << result.xmlnode
187
+ # result
188
+ # end
189
+ # def first_unused_index
190
+ # empty? ? 1 : last.range.end+1
191
+ # end
192
+ # # prolonges the RowArray to cantain rowi and returns it
193
+ # def detach_of_bound_item(index)
194
+ # fill_row_group_size = index-first_unused_index
195
+ # if fill_row_group_size>0
196
+ # add_item_group(fill_row_group_size)
197
+ # end
198
+ # add_item_group(1)
199
+ # get_item(index) # aby se odpoved nacacheovala
200
+ # end
201
+ # def get_item_group(index)
202
+ # find{ |item_group| item_group.range.cover?(index) }
203
+ # end
204
+ # def detach_item(index); get_item(index) end # TODO předělat do lazy podoby, kdy tohle nebude stejny
205
+ # def get_item(index)
206
+ # if index>= first_unused_index
207
+ # nil
208
+ # else
209
+ # @itemcache[index] ||= Rspreadsheet::XmlTiedArrayItem.new(self,index)
210
+ # end
211
+ # end
212
+ # # This detaches item index from the group and perhaps splits the RowGroup
213
+ # # into two pieces. This makes the row individually editable.
214
+ # def detach(index)
215
+ # group_index = get_group_index(index)
216
+ # item_group = self[group_index]
217
+ # range = item_group.range
218
+ # return self if range==(index..index)
219
+ #
220
+ # # prepare new components
221
+ # replaceby = []
222
+ # replaceby << RowGroup.new(self,range.begin..index-1)
223
+ # replaceby << (result = SingleRow.new(self,index))
224
+ # replaceby << RowGroup.new(self,index+1..range.end)
225
+ #
226
+ # # put original range somewhere in replaceby and shorten it
227
+ #
228
+ # if index>range.begin
229
+ # replaceby[0] = item_group
230
+ # item_group.range = range.begin..index-1
231
+ # else
232
+ # replaceby[2] = item_group
233
+ # item_group.range = index+1..range.end
234
+ # end
235
+ #
236
+ # # normalize and delete empty parts
237
+ # replaceby = replaceby.map(&:normalize).compact
238
+ #
239
+ # # do the replacement in xml
240
+ # marker = LibXML::XML::Node.new('temporarymarker')
241
+ # item_group.xmlnode.next = marker
242
+ # item_group.xmlnode.remove!
243
+ # replaceby.each{ |rg|
244
+ # marker.prev = rg.xmlnode
245
+ # }
246
+ # marker.remove!
247
+ #
248
+ # # do the replacement in array
249
+ # self[group_index..group_index]=replaceby
250
+ # result
251
+ # end
252
+ # private
253
+ # def get_group_index(index)
254
+ # self.find_index{ |rowgroup| rowgroup.range.cover?(index) }
255
+ # end
256
+ # end
257
+
258
+ # class XmlTiedArrayItem
259
+ # attr_reader :index
260
+ # def initialize(aarray,aindex)
261
+ # @array = aarray
262
+ # @index = aindex
263
+ # if self.virtual?
264
+ # @object = nil
265
+ # else
266
+ # @object = @array.options[:object_type].new(group.xmlnode)
267
+ # end
268
+ # end
269
+ # def group; @array.get_item_group(index) end
270
+ # def repeated?; group.repeated? end
271
+ # def virtual?; ! self.repeated? end
272
+ # def array
273
+ # raise 'Group empty' if @group.nil?
274
+ # @array
275
+ # end
276
+ # end
277
+
278
+ # class RowArray < XmlTiedArray
279
+ # attr_reader :row_array_cache
280
+ # def initialize(aworksheet,aworksheet_node)
281
+ # @worksheet = aworksheet
282
+ # @row_array_cache = Hash.new()
283
+ # super(aworksheet_node, :xml_items_node_name => 'table-row', :xml_repeated_attribute => xml_repeated_attribute, :object_type=>Row)
284
+ # end
285
+ # def get_row(rowi)
286
+ # if @row_array_cache.has_key?(rowi)
287
+ # return @row_array_cache[rowi]
288
+ # end
289
+ # item = self.get_item(rowi)
290
+ # @row_array_cache[rowi] = if item.nil?
291
+ # if rowi>0 then Rspreadsheet::UninitializedEmptyRow.new(self,rowi) else nil end
292
+ # else
293
+ # if item.repeated?
294
+ # Rspreadsheet::MemberOfRowGroup.new(item.index, item.group.to_rowgroup)
295
+ # else
296
+ # Rspreadsheet::SingleRow.new_from_rowgroup(item.group.to_rowgroup)
297
+ # end
298
+ # end
299
+ # end
300
+ # # aliases
301
+ # def first_unused_row_index; first_unused_index end
302
+ # def worksheet; @worksheet end
303
+ # def detach_of_bound_row_group(index)
304
+ # super(index)
305
+ # return get_row(index)
306
+ # end
307
+ # end
308
+
309
+ # class Row
310
+ # def initialize
311
+ # @readonly = :unknown
312
+ # @cells = {}
313
+ # end
314
+ # def self.empty_row_node
315
+ # LibXML::XML::Node.new('table-row',nil, Tools.get_namespace('table'))
316
+ # end
317
+ # def worksheet; @parent_array.worksheet end
318
+ # def parent_array; @parent_array end # for debug only
319
+ # def used_col_range; 1..first_unused_column_index-1 end
320
+ # def used_range; used_col_range end
321
+ # def first_unused_column_index; raise 'this should be redefined in subclasses' end
322
+ # def cells(coli)
323
+ # coli = coli.to_i
324
+ # return nil if coli.to_i<=0
325
+ # @cells[coli] ||= get_cell(coli)
326
+ # end
327
+ # end
328
+
329
+ # class RowWithXMLNode < Row
330
+ # attr_accessor :xmlnode
331
+ # def style_name=(value); Tools.set_ns_attribute(@xmlnode,'table','style-name',value) end
332
+ # def get_cell(coli)
333
+ # Cell.new(self,coli,cellnodes(coli))
334
+ # end
335
+ # def nonemptycells
336
+ # nonemptycellsindexes.collect{ |index| cells(index) }
337
+ # end
338
+ # def nonemptycellsindexes
339
+ # used_col_range.to_a.select do |coli|
340
+ # cellnode = cellnodes(coli)
341
+ # !(cellnode.content.nil? or cellnode.content.empty? or cellnode.content =='') or
342
+ # !cellnode.attributes.to_a.reject{ |attr| attr.name == 'number-columns-repeated'}.empty?
343
+ # end
344
+ # end
345
+ # def cellnodes(coli)
346
+ # cellnode = nil
347
+ # while true
348
+ # curr_coli=1
349
+ # cellnode = @xmlnode.elements.select{|n| n.name=='table-cell'}.find do |el|
350
+ # curr_coli += (Tools.get_ns_attribute_value(el, 'table', 'number-columns-repeated') || 1).to_i
351
+ # curr_coli > coli
352
+ # end
353
+ # unless cellnode.nil?
354
+ # return cellnode
355
+ # else
356
+ # add_cell
357
+ # end
358
+ # end
359
+ # end
360
+ # def add_cell(repeated=1)
361
+ # cell = Cell.new(self,first_unused_column_index)
362
+ # Tools.set_ns_attribute(cell.xmlnode,'table','number-columns-repeated',repeated) if repeated>1
363
+ # @xmlnode << cell.xmlnode
364
+ # cell
365
+ # end
366
+ # def first_unused_column_index
367
+ # 1 + @xmlnode.elements.select{|n| n.name=='table-cell'}.reduce(0) do |sum, el|
368
+ # sum + (Tools.get_ns_attribute_value(el, 'table', 'number-columns-repeated') || 1).to_i
369
+ # end
370
+ # end
371
+ # end
372
+
373
+ # class RowGroup < RowWithXMLNode
374
+ # @readonly = :yes_always
375
+ # attr_reader :range
376
+ # attr_accessor :parent_array, :xmlnode
377
+ # def initialize(aparent_array,arange,axmlnode=nil)
378
+ # super()
379
+ # @parent_array = aparent_array
380
+ # @range = arange
381
+ # if axmlnode.nil?
382
+ # axmlnode = Row.empty_row_node
383
+ # Tools.set_ns_attribute(axmlnode,'table','number-rows-repeated',range.size) if range.size>1
384
+ # end
385
+ # @xmlnode = axmlnode
386
+ # end
387
+ # # returns SingleRow if size of range is 1 and nil if it is 0 or less
388
+ # def normalize
389
+ # case range.size
390
+ # when 2..Float::INFINITY then self
391
+ # when 1 then SingleRow.new_from_rowgroup(self)
392
+ # else nil
393
+ # end
394
+ # end
395
+ # def repeated; range.size end
396
+ # def repeated?; range.size>1 end
397
+ # def range=(arange)
398
+ # @range=arange
399
+ # Tools.set_ns_attribute(@xmlnode,'table','number-rows-repeated',range.size, 1)
400
+ # end
401
+ # end
402
+
403
+ # class SingleRow < RowWithXMLNode
404
+ # @readonly = :no
405
+ # attr_accessor :xmlnode
406
+ # # index Integer
407
+ # def initialize(aparent_array,aindex,axmlnode=nil)
408
+ # super()
409
+ # @parent_array = aparent_array
410
+ # @index = aindex
411
+ # if axmlnode.nil?
412
+ # axmlnode = Row.empty_row_node
413
+ # end
414
+ # @xmlnode = axmlnode
415
+ # end
416
+ # def self.new_from_rowgroup(rg)
417
+ # anode = rg.xmlnode
418
+ # Tools.remove_ns_attribute(anode,'table','number-rows-repeated')
419
+ # SingleRow.new(rg.parent_array,rg.range.begin,anode)
420
+ # end
421
+ # def normalize; self end
422
+ # def repeated?; false end
423
+ # def repeated; 1 end
424
+ # def range; (@index..@index) end
425
+ # def detach; self end
426
+ # def row; @index end
427
+ # def still_out_of_used_range?; false end
428
+ # end
429
+
430
+ # class LazyDetachableRow < Row
431
+ # @readonly = :yes_but_detachable
432
+ # def initialize(rowi)
433
+ # super()
434
+ # @index = rowi.to_i
435
+ # end
436
+ # def add_cell; detach.add_cell end
437
+ # def style_name=(value); detach.style_name=value end
438
+ # def row; @index end
439
+ # end
440
+
441
+ # ## there are not data in this object, they are taken from RowGroup, but this is only readonly
442
+ # class MemberOfRowGroup < LazyDetachableRow
443
+ # @readonly = :yes_but_detachable
444
+ # extend Forwardable
445
+ # delegate [:repeated?, :repeated, :xmlnode, :parent_array] => :@row_group
446
+ # attr_accessor :row_group # for dubugging
447
+ #
448
+ # # @index Integer
449
+ # # @row_group RepeatedRow
450
+ # def initialize(arowi,arow_group)
451
+ # super(arowi)
452
+ # @row_group = arow_group
453
+ # raise 'Wrong parameter given - class is '+@row_group.class.to_a unless @row_group.is_a? RowGroup
454
+ # end
455
+ # def detach # detaches MemberOfRowGroup from its RowGroup perhaps splitting RowGroup
456
+ # @row_group.parent_array.detach(@index)
457
+ # end
458
+ # def get_cell(coli)
459
+ # c = Cell.new(self,coli,@row_group.cellnodes(coli))
460
+ # c.mode = :repeated
461
+ # c
462
+ # end
463
+ # def first_unused_column_index
464
+ # @row_group.first_unused_column_index
465
+ # end
466
+ # def nonemptycells
467
+ # @row_group.nonemptycellsindexes.collect{ |coli| cells(coli) }
468
+ # end
469
+ # end
470
+
471
+
123
472
  end
@@ -1,3 +1,3 @@
1
1
  module Rspreadsheet
2
- VERSION = "0.2.14"
2
+ VERSION = "0.2.15"
3
3
  end
@@ -56,17 +56,23 @@ class Workbook
56
56
  end
57
57
  # @param [String] Optional new filename
58
58
  # Saves the worksheet. Optionally you can provide new filename.
59
- def save(new_filename=nil)
60
- if @filename.nil? and new_filename.nil? then raise 'New file should be named on first save.' end
61
- # if the filename has changed than first copy the original file to new location (or template if it is a new file)
62
- if new_filename
63
- FileUtils.cp(@filename || File.dirname(__FILE__)+'/empty_file_template.ods', new_filename)
64
- @filename = new_filename
65
- end
66
- Zip::File.open(@filename) do |zip|
67
- # it is easy, because @xmlnode in in sync with contents all the time
68
- zip.get_output_stream('content.xml') do |f|
69
- f.write @content_xml.to_s(:indent => false)
59
+ def save(new_filename_or_io_object=nil)
60
+ if @filename.nil? and new_filename_or_io_object.nil? then raise 'New file should be named on first save.' end
61
+
62
+ if new_filename_or_io_object.kind_of? StringIO
63
+ new_filename_or_io_object.write(@content_xml.to_s(indent: false))
64
+ elsif new_filename_or_io_object.nil? or new_filename_or_io_object.kind_of? String
65
+
66
+ if new_filename_or_io_object.kind_of? String # the filename has changed
67
+ # first copy the original file to new location (or template if it is a new file)
68
+ FileUtils.cp(@filename || File.dirname(__FILE__)+'/empty_file_template.ods', new_filename_or_io_object)
69
+ @filename = new_filename_or_io_object
70
+ end
71
+ Zip::File.open(@filename) do |zip|
72
+ # it is easy, because @xmlnode in in sync with contents all the time
73
+ zip.get_output_stream('content.xml') do |f|
74
+ f.write @content_xml.to_s(:indent => false)
75
+ end
70
76
  end
71
77
  end
72
78
  end
@@ -1,7 +1,6 @@
1
1
  require 'rspreadsheet/row'
2
2
  require 'rspreadsheet/column'
3
3
  require 'rspreadsheet/tools'
4
- require 'helpers/class_extensions'
5
4
  # require 'forwardable'
6
5
 
7
6
  module Rspreadsheet
@@ -1,9 +1,5 @@
1
- require 'helpers/class_extensions'
2
-
3
1
  module Rspreadsheet
4
2
 
5
- using ClassExtensions if RUBY_VERSION > '2.1'
6
-
7
3
  # @private
8
4
  class XMLTied
9
5
  def xml
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rspreadsheet do
4
+ it 'can open spreadsheet and save it to file, resulting file has same content as original' do
5
+ spreadsheet = Rspreadsheet.new($test_filename) # open a file
6
+
7
+ # save it to temp file
8
+ tmp_filename = '/tmp/testfile1.ods'
9
+ File.delete(tmp_filename) if File.exists?(tmp_filename) # first delete temp file
10
+ spreadsheet.save(tmp_filename) # and save spreadsheet as temp file
11
+
12
+ # now compare content saved file to original
13
+ contents_of_files_are_identical($test_filename,tmp_filename)
14
+ end
15
+
16
+ # it 'can open spreadsheet and store it to IO object', :xpending => 'Under development' do
17
+ # spreadsheet = Rspreadsheet.new($test_filename) # open a file
18
+ #
19
+ # stringio = StringIO.new
20
+ # spreadsheet.save(stringio)
21
+ # raise stringio.read
22
+ #
23
+ # end
24
+ end
25
+
26
+ def contents_of_files_are_identical(filename1,filename2)
27
+ @content_xml1 = Zip::File.open(filename1) do |zip|
28
+ LibXML::XML::Document.io zip.get_input_stream('content.xml')
29
+ end
30
+ @content_xml2 = Zip::File.open(filename2) do |zip|
31
+ LibXML::XML::Document.io zip.get_input_stream('content.xml')
32
+ end
33
+
34
+ @content_xml2.root.first_diff(@content_xml1.root).should be_nil
35
+ @content_xml1.root.first_diff(@content_xml2.root).should be_nil
36
+
37
+ @content_xml1.root.equals?(@content_xml2.root).should == true
38
+ end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- using ClassExtensions if RUBY_VERSION > '2.1'
3
2
 
4
3
  describe Rspreadsheet do
5
4
  it 'can open ods testfile and reads its content correctly' do
@@ -26,25 +25,6 @@ describe Rspreadsheet do
26
25
  @sheet2[cell.rowi,cell.coli].should == cell.value
27
26
  end
28
27
  end
29
- it 'can open and save file, and saved file is exactly same as original' do
30
- tmp_filename = '/tmp/testfile1.ods' # first delete temp file
31
- File.delete(tmp_filename) if File.exists?(tmp_filename)
32
- book = Rspreadsheet.new($test_filename) # than open test file
33
- book.save(tmp_filename) # and save it as temp file
34
-
35
- # now compare them
36
- @content_xml1 = Zip::File.open($test_filename) do |zip|
37
- LibXML::XML::Document.io zip.get_input_stream('content.xml')
38
- end
39
- @content_xml2 = Zip::File.open(tmp_filename) do |zip|
40
- LibXML::XML::Document.io zip.get_input_stream('content.xml')
41
- end
42
-
43
- @content_xml2.root.first_diff(@content_xml1.root).should be_nil
44
- @content_xml1.root.first_diff(@content_xml2.root).should be_nil
45
-
46
- @content_xml1.root.should == @content_xml2.root
47
- end
48
28
  it 'when open and save file modified, than the file is different' do
49
29
  tmp_filename = '/tmp/testfile1.ods' # first delete temp file
50
30
  File.delete(tmp_filename) if File.exists?(tmp_filename)
@@ -88,7 +68,7 @@ describe Rspreadsheet do
88
68
  sheet.cells(5,2).format.bold = true
89
69
  sheet.cells(5,2).format.background_color = '#FF0000'
90
70
  }.not_to raise_error
91
-
71
+
92
72
  sheet.rows(4).cellvalues.sum{|val| val.to_f}.should eq 4+7*4
93
73
  sheet.rows(4).cells.sum{ |cell| cell.value.to_f }.should eq 4+7*4
94
74
 
Binary file
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- using ClassExtensions if RUBY_VERSION > '2.1'
3
2
 
4
3
  describe Rspreadsheet::Worksheet do
5
4
  describe "from test workbook file" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspreadsheet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.14
4
+ version: 0.2.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub A.Těšínský
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-20 00:00:00.000000000 Z
11
+ date: 2016-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libxml-ruby
@@ -191,8 +191,8 @@ files:
191
191
  - reinstall_local_gem.sh
192
192
  - rspreadsheet.gemspec
193
193
  - spec/cell_spec.rb
194
- - spec/class_extensions_spec.rb
195
194
  - spec/column_spec.rb
195
+ - spec/io_spec.rb
196
196
  - spec/row_spec.rb
197
197
  - spec/rspreadsheet_spec.rb
198
198
  - spec/spec_helper.rb
@@ -220,15 +220,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
220
  version: '0'
221
221
  requirements: []
222
222
  rubyforge_project:
223
- rubygems_version: 2.4.1
223
+ rubygems_version: 2.2.2
224
224
  signing_key:
225
225
  specification_version: 4
226
226
  summary: Manipulating spreadsheets with Ruby (read / create / modify OpenDocument
227
227
  Spreadsheet).
228
228
  test_files:
229
229
  - spec/cell_spec.rb
230
- - spec/class_extensions_spec.rb
231
230
  - spec/column_spec.rb
231
+ - spec/io_spec.rb
232
232
  - spec/row_spec.rb
233
233
  - spec/rspreadsheet_spec.rb
234
234
  - spec/spec_helper.rb
@@ -1,46 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if RUBY_VERSION > '2.1'
4
- using ClassExtensions
5
-
6
- describe Array do
7
- it 'can sum simple array' do
8
- a = [1,2,3,4]
9
- a.sum.should == 10
10
- end
11
- it 'ignores text and nils while summing' do
12
- a = [1,nil, nil,2,3,'foo',5.0]
13
- a.sum.should == 11
14
- [nil, 'nic'].sum.should == 0
15
- [].sum.should == 0
16
- end
17
- end
18
-
19
- describe LibXML::XML::Node do
20
- before do
21
- @n = LibXML::XML::Node.new('a')
22
- @n << LibXML::XML::Node.new('i','italic')
23
- b = LibXML::XML::Node.new('p','paragraph')
24
- b << LibXML::XML::Node.new('b','boldtext')
25
- @n << b
26
- @n << LibXML::XML::Node.new_text('textnode')
27
-
28
- @m = LibXML::XML::Node.new('a')
29
- @m << LibXML::XML::Node.new('i','italic')
30
- c = LibXML::XML::Node.new('p','paragraph')
31
- c << LibXML::XML::Node.new('b','boldtext')
32
- @m << c
33
- @m << LibXML::XML::Node.new_text('textnode')
34
-
35
- @m2 = LibXML::XML::Node.new('a')
36
- end
37
- it 'can compare nodes' do
38
- @n.should == @m
39
- @n.should_not == @m2
40
- end
41
- it 'has correct elements' do
42
- # raise @n.first_diff(@m).inspect
43
- end
44
- end
45
-
46
- end