rspreadsheet 0.2.7 → 0.2.9

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: f9603ed2713de6f87efb309a9cd9f36388001731
4
- data.tar.gz: baa73509ae8527b93fa5dc19596a244ed21f5171
3
+ metadata.gz: 6cefcb8b1947902d4008ba3f9a77cbf1789addd1
4
+ data.tar.gz: 841b189fbbe35436ff05e92dcd7fe0cfc368cd0f
5
5
  SHA512:
6
- metadata.gz: 691688a99bd3900f791502e2efd9b74b5fb745f1044ef349885fec3323ff6e95fc074fcd65c5c55a2b972f50a49715d58381e5b7b00f65c662dc4f5293378b90
7
- data.tar.gz: 1a57249cbdceb90ff94a8544a7f370c89124008d6c33dc9777a2aeae83e3fb6e6f4b67bb7380df27496726170d0a84be36feb51083d9fffda525ba34c9ea10d5
6
+ metadata.gz: 69b9f5968540c86671c39cd93efc04f243cf5c441789e60bedd69a6fdc12a68ccf51016021a9a4bd75fffe65c716cadaeaf79289b6d00fedcdfda46973f62898
7
+ data.tar.gz: 52eea9086874e653eddab4374c396a82f09741daf55596a5cb393662d4130b25f5273e8664b43134981e5214d2bcfb3ffe9b3b88136c9d6e50a4eaab77f0df15
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Build Status](https://api.travis-ci.org/gorn/rspreadsheet.svg?branch=master)](https://travis-ci.org/gorn/rspreadsheet) [![Coverage Status](https://coveralls.io/repos/gorn/rspreadsheet/badge.png)](https://coveralls.io/r/gorn/rspreadsheet)
4
4
 
5
- Manipulating spreadsheets with Ruby. Read, modify, write or create new OpenDocument Spreadsheet files from ruby code.
5
+ Manipulating spreadsheets with Ruby. Read, modify, write or create new OpenDocument Spreadsheet files from ruby code.
6
6
 
7
7
  ## Contibutions, ideas and wishes welcomed
8
8
 
@@ -82,8 +82,8 @@ then you might not have installed libxml for ruby. I.e. in debian something like
82
82
 
83
83
  This project arised from the necessity. Alhought it is not true that there are no ruby gems allowing to acess OpenDOcument spreadsheet, I did not find another decent one which would suit my needs. Most of them also look abandoned and inactive. I have investigated these options:
84
84
 
85
- * [ruby-ods](https://github.com/yalab/ruby-ods) - this one seems as if it never really started
86
- * [rodf](https://github.com/thiagoarrais/rodf)- this only server as builder, it can not read existing files
85
+ * [ruby-ods](https://github.com/yalab/ruby-ods) - this one seems abandoned, or even as if it never really started
86
+ * [rodf](https://github.com/thiagoarrais/rodf)- this only serves as builder, it can not read existing files or modify them
87
87
  * [rods](http://www.drbreinlinger.de/ruby/rods/) - this is pretty ok, but it has terrible syntax. I first thought of writing wrapper around it, but it turned to be not so easy. Also last commit is 2 years old.
88
88
  * [rubiod](https://github.com/netoctone/rubiod) - this one is quite ok, the syntax is definitely better that in rods, but it seems also very abandoned. It does not support formats. This is a closest match.
89
89
  * [spreadsheet](https://github.com/zdavatz/spreadsheet) - this does not work with OpenDocument and even with Excel has issues in modyfying document. However since it is supposedly used, and has quite good syntax it might be inspirative. I also find the way this gem handles lazy writing of new rows to Spreadsheet object flawed, as well as strange accesibility of rows array object, which if assigned breaks consistency of sheet.
@@ -1,9 +1,10 @@
1
1
  # @markup markdown
2
2
  # @author Jakub Tesinsky
3
- # @titel rspreadsheet Cell
3
+ # @title rspreadsheet Cell
4
4
 
5
5
  require 'andand'
6
6
  require 'rspreadsheet/xml_tied'
7
+ require 'date'
7
8
 
8
9
 
9
10
 
@@ -72,23 +73,23 @@ class Cell < XMLTiedItem
72
73
  gt = guess_cell_type(avalue)
73
74
  case
74
75
  when gt == nil then raise 'This value type is not storable to cell'
75
- when gt == Float
76
- set_type_attribute('float')
76
+ when gt == Float then
77
77
  remove_all_value_attributes_and_content(xmlnode)
78
+ set_type_attribute('float')
78
79
  Tools.set_ns_attribute(xmlnode,'office','value', avalue.to_s)
79
80
  xmlnode << Tools.prepare_ns_node('text','p', avalue.to_f.to_s)
80
81
  when gt == String then
81
- set_type_attribute('string')
82
82
  remove_all_value_attributes_and_content(xmlnode)
83
+ set_type_attribute('string')
83
84
  xmlnode << Tools.prepare_ns_node('text','p', avalue.to_s)
84
85
  when gt == Date then
85
- set_type_attribute('date')
86
86
  remove_all_value_attributes_and_content(xmlnode)
87
+ set_type_attribute('date')
87
88
  Tools.set_ns_attribute(xmlnode,'office','date-value', avalue.strftime('%Y-%m-%d'))
88
89
  xmlnode << Tools.prepare_ns_node('text','p', avalue.strftime('%Y-%m-%d'))
89
- when gt == :percentage
90
- set_type_attribute('percentage')
90
+ when gt == :percentage then
91
91
  remove_all_value_attributes_and_content(xmlnode)
92
+ set_type_attribute('percentage')
92
93
  Tools.set_ns_attribute(xmlnode,'office','value', '%0.2d%' % avalue.to_f)
93
94
  xmlnode << Tools.prepare_ns_node('text','p', (avalue.to_f*100).round.to_s+'%')
94
95
  end
@@ -98,12 +99,17 @@ class Cell < XMLTiedItem
98
99
  end
99
100
  def set_type_attribute(typestring)
100
101
  Tools.set_ns_attribute(xmlnode,'office','value-type',typestring)
102
+ Tools.set_ns_attribute(xmlnode,'calcext','value-type',typestring)
101
103
  end
102
- def remove_all_value_attributes_and_content(node)
104
+ def remove_all_value_attributes_and_content(node=xmlnode)
103
105
  if att = Tools.get_ns_attribute(node, 'office','value') then att.remove! end
104
106
  if att = Tools.get_ns_attribute(node, 'office','date-value') then att.remove! end
107
+ if att = Tools.get_ns_attribute(node, 'table','formula') then att.remove! end
105
108
  node.content=''
106
109
  end
110
+ def remove_all_type_attributes
111
+ set_type_attribute(nil)
112
+ end
107
113
  def relative(rowdiff,coldiff)
108
114
  @worksheet.cells(self.rowi+rowdiff, self.coli+coldiff)
109
115
  end
@@ -115,6 +121,7 @@ class Cell < XMLTiedItem
115
121
  when gct == Date then :date
116
122
  when gct == :percentage then :percentage
117
123
  when gct == :unassigned then :unassigned
124
+ when gct == NilClass then :empty
118
125
  when gct == nil then :unknown
119
126
  else :unknown
120
127
  end
@@ -161,9 +168,11 @@ class Cell < XMLTiedItem
161
168
  typeguess
162
169
  end
163
170
  else # it not have a typeguess
164
- if (String(avalue) rescue false) # convertible to String
171
+ if (avalue.nil?) # if nil then nil
172
+ NilClass
173
+ elsif (String(avalue) rescue false) # convertible to String
165
174
  String
166
- else
175
+ else # giving up
167
176
  nil
168
177
  end
169
178
  end
@@ -178,6 +187,24 @@ class Cell < XMLTiedItem
178
187
  def address
179
188
  Tools.convert_cell_coordinates_to_address(coordinates)
180
189
  end
190
+
191
+ def formula
192
+ rawformula = Tools.get_ns_attribute(xmlnode,'table','formula',nil).andand.value
193
+ if rawformula.nil?
194
+ nil
195
+ elsif rawformula.match(/^of:(.*)$/)
196
+ $1
197
+ else
198
+ raise "Mischmatched value in table:formula attribute - does not start with of: (#{rawformula.to_s})"
199
+ end
200
+ end
201
+ def formula=(formulastring)
202
+ detach_if_needed
203
+ raise 'Formula string must begin with "=" character' unless formulastring[0,1] == '='
204
+ remove_all_value_attributes_and_content(xmlnode)
205
+ remove_all_type_attributes
206
+ Tools.set_ns_attribute(xmlnode,'table','formula','of:'+formulastring.to_s)
207
+ end
181
208
 
182
209
  end
183
210
 
@@ -209,6 +236,7 @@ class CellFormat
209
236
  def color=(value); set_text_style_node_attribute('color', value) end
210
237
  def font_size=(value);set_text_style_node_attribute('font-size', value) end
211
238
  def set_text_style_node_attribute(attribute_name,value)
239
+ @cell.detach if @cell.mode != :regular
212
240
  if text_style_node.nil?
213
241
  self.create_text_style_node
214
242
  raise 'Style node was not correctly initialized' if text_style_node.nil?
@@ -250,17 +278,22 @@ class CellFormat
250
278
  end
251
279
 
252
280
  def unused_cell_style_name
253
- last = cellnode.doc.root.find('./office:automatic-styles/style:style').
281
+ last = (cellnode.nil? ? [] : cellnode.doc.root.find('./office:automatic-styles/style:style')).
254
282
  collect {|node| node['name']}.
255
283
  collect{ |name| /^ce(\d*)$/.match(name); $1.andand.to_i}.
256
284
  compact.max || 0
257
285
  "ce#{last+1}"
258
286
  end
259
- def automatic_styles_node; cellnode.doc.root.find("./office:automatic-styles").first end
260
- def style_name; Tools.get_ns_attribute_value(cellnode,'table','style-name') end
261
- def style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]").first end
262
- def text_style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]/style:text-properties").first end
263
- def cell_style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]/style:table-cell-properties").first end
287
+ def automatic_styles_node; style_node_with_partial_xpath('') end
288
+ def style_name; Tools.get_ns_attribute_value(cellnode,'table','style-name',nil) end
289
+ def style_node; style_node_with_partial_xpath("/style:style[@style:name=\"#{style_name}\"]") end
290
+ def text_style_node; style_node_with_partial_xpath("/style:style[@style:name=\"#{style_name}\"]/style:text-properties") end
291
+ def cell_style_node; style_node_with_partial_xpath("/style:style[@style:name=\"#{style_name}\"]/style:table-cell-properties") end
292
+ def style_node_with_partial_xpath(xpath)
293
+ return nil if cellnode.nil?
294
+ cellnode.doc.root.find("./office:automatic-styles#{xpath}").first
295
+ end
296
+
264
297
  end
265
298
 
266
299
  end
@@ -130,6 +130,7 @@ module Tools
130
130
  end
131
131
  # sets namespaced attribute "ns_prefix:key" in node to value. if value == delete_value then remove the attribute
132
132
  def self.set_ns_attribute(node,ns_prefix,key,value,delete_value=nil)
133
+ raise 'Tools.set_ns_attribute can not set attribute on nil node' if node.nil?
133
134
  ns = Tools.get_namespace(ns_prefix)
134
135
  attr = node.attributes.get_attribute_ns(ns.href, key)
135
136
 
@@ -152,8 +153,12 @@ module Tools
152
153
  node.nil? ? default : node.attributes.get_attribute_ns(Tools.get_namespace(ns_prefix).href,key) || default
153
154
  end
154
155
  end
155
- def self.get_ns_attribute_value(node,ns_prefix,key)
156
- Tools.get_ns_attribute(node,ns_prefix,key).andand.value
156
+ def self.get_ns_attribute_value(node,ns_prefix,key,default=:undefined_default)
157
+ if default==:undefined_default
158
+ Tools.get_ns_attribute(node,ns_prefix,key).andand.value
159
+ else
160
+ node.nil? ? default : Tools.get_ns_attribute(node,ns_prefix,key,nil).andand.value || default
161
+ end
157
162
  end
158
163
  def self.remove_ns_attribute(node,ns_prefix,key)
159
164
  node.attributes.get_attribute_ns(Tools.get_namespace(ns_prefix).href,key)
@@ -1,3 +1,3 @@
1
1
  module Rspreadsheet
2
- VERSION = "0.2.7"
2
+ VERSION = "0.2.9"
3
3
  end
data/spec/cell_spec.rb CHANGED
@@ -141,7 +141,7 @@ describe Rspreadsheet::Cell do
141
141
 
142
142
  @cell = @sheet2.cells(16,4)
143
143
  @cell.range.should == (1..7)
144
- @cell.value.should == ""
144
+ @cell.value.should == nil
145
145
 
146
146
  @sheet2.rows(15).range.should == (14..18)
147
147
  @sheet2.rows(16).range.should == (14..18)
@@ -155,11 +155,11 @@ describe Rspreadsheet::Cell do
155
155
 
156
156
  @cellA = @sheet2.cells(16,1)
157
157
  @cellA.range.should == (1..2)
158
- @cellA.value.should == ""
158
+ @cellA.value.should be_nil
159
159
 
160
160
  @cellB = @sheet2.cells(16,5)
161
161
  @cellB.range.should == (4..8)
162
- @cellB.value.should == ""
162
+ @cellB.value.should be_nil
163
163
 
164
164
  end
165
165
  it 'inserted has correct class' do # based on real error
@@ -232,7 +232,7 @@ describe Rspreadsheet::Cell do
232
232
  expect { @cell.rowi }.to raise_error
233
233
  expect { @cell.address }.to raise_error
234
234
 
235
- @sheet1.cells(2,2).type.should == :string
235
+ @sheet1.cells(2,2).type.should == :empty
236
236
  @sheet1.cells(3,2).type.should == :unassigned
237
237
  end
238
238
  it 'switches to invalid_reference cell when its row is deleted' do
@@ -271,6 +271,38 @@ describe Rspreadsheet::Cell do
271
271
  @sheet2.cells('BA177').should be @sheet2.cells(177,53)
272
272
  @sheet2.cells('ADA2').should be @sheet2.cells(2,781)
273
273
  end
274
+ it 'setting format in new file detaches the cell' do
275
+ @cell = @sheet1.cells(1,1)
276
+ # bold
277
+ @cell.format.bold.should be_falsey
278
+ @cell.format.bold = true
279
+ @cell.format.bold.should be_truthy
280
+ @cell.mode.should eq :regular
281
+ end
282
+ it 'remembers formula when set' do
283
+ @cell = @sheet1.cells(1,1)
284
+ # bold
285
+ @cell.formula.should be_nil
286
+ @cell.formula='=1+5'
287
+ @cell.formula.should eq '=1+5'
288
+ end
289
+ it 'unsets cell type when formula set - we can not guess it correctly', :focus do
290
+ @cell = @sheet1.cells(1,1)
291
+ @cell.value = 'ahoj'
292
+ @cell.type.should eq :string
293
+ @cell.formula='=1+5'
294
+ typ = @cell.xmlnode.nil? ? 'N/A' : @cell.xmlnode.attributes['value-type']
295
+ @cell.type.should_not eq :string
296
+ @cell.type.should eq :empty
297
+ end
298
+ it 'wipes out formula after assiging value' do
299
+ @cell = @sheet1.cells(1,1)
300
+ @cell.formula='=1+5'
301
+ @cell.formula.should_not be_nil
302
+ @cell.value = 'baf'
303
+ @cell.type.should eq :string
304
+ @cell.formula.should be_nil
305
+ end
274
306
  end
275
307
 
276
308
 
data/spec/testfile1.ods CHANGED
Binary file
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.7
4
+ version: 0.2.9
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: 2014-11-23 00:00:00.000000000 Z
11
+ date: 2015-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libxml-ruby
@@ -216,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
216
216
  version: '0'
217
217
  requirements: []
218
218
  rubyforge_project:
219
- rubygems_version: 2.2.2
219
+ rubygems_version: 2.4.1
220
220
  signing_key:
221
221
  specification_version: 4
222
222
  summary: Manipulating spreadsheets with Ruby (read / create / modify OpenDocument