rspreadsheet 0.2.14 → 0.2.15

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