spreadbase 0.1.4 → 0.4.0

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
  SHA256:
3
- metadata.gz: 89cb94c9ff4d62b429681c6d4cca60ea78b168e2764c4a17a8b94f62b3e39ba4
4
- data.tar.gz: be8c13aca79e8ee79ecf409f2d8f009e5e1c71220cf67368243e779d2432f35b
3
+ metadata.gz: 37e52d4079a3f0f7c0ba6fef6db24dbe8426f1f47d66904ea9fa418744719e27
4
+ data.tar.gz: 79304c560419b6500e95f9c4fb5c8d8bfbf9ffe3ed1b591125ab696be5652560
5
5
  SHA512:
6
- metadata.gz: 2f12dcc306f702bba5d0ae6a726c3e61a3a4088d4de68e0fb82aadd04a8b226b5da34f17123326816de6532ffdf4ca5c7c5f0f6f161a52f9216a0ad258c04112
7
- data.tar.gz: eabcb7bd63da042b2aba2013fca3510e2e17f2033d7510bb52970f9d2eff9bcea3698271ffcdc52e0cd9b45dad1219efec1a0a2466ba97f230448c9a36570874
6
+ metadata.gz: c02992b1b27f909a4df2bc93df27965b90277d0343bed2a5c0cb88c99e8ff337146ba6239aa5764f826833e2ebde0793ac20ce0170afa473b9e78796c361e38f
7
+ data.tar.gz: c02bbb08fe16bbb8dff403fac1948bc2f3457f544408c9e5bbd996fd90dbe3d4df6a68ad766f0217592f10823773bd0cdf307210b259ff1690c7ecf02ffadad9
@@ -0,0 +1,25 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ rspec:
7
+ runs-on: ubuntu-latest
8
+
9
+ strategy:
10
+ matrix:
11
+ ruby: ['3.1', '3.0', '2.7', '2.6', '2.5', '2.4']
12
+
13
+ steps:
14
+ - name: Checkout spreadbase repository
15
+ uses: actions/checkout@v2
16
+
17
+ - name: Setup Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: ${{ matrix.ruby }}
21
+ bundler-cache: true
22
+
23
+ - name: Run RSpec
24
+ run: |
25
+ bundle exec rake spec
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ if Gem.ruby_version >= Gem::Version.new('3.0.0')
6
+ gem 'rexml'
7
+ end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status][BS img]](https://travis-ci.org/saveriomiroddi/spreadbase)
1
+ [![CI](https://github.com/saveriomiroddi/spreadbase/actions/workflows/ci.yml/badge.svg)](https://github.com/saveriomiroddi/spreadbase/actions/workflows/ci.yml)
2
2
 
3
3
  SpreadBase!!
4
4
  ============
@@ -139,9 +139,9 @@ Notes
139
139
  - Numbers are decoded to Fixnum or Float, depending on the existence of the fractional part.
140
140
  Alternatively, numbers with a fractional part can be decoded as Bigdecimal, using the option:
141
141
 
142
- `SpreadBase::Document.new( "Random numbers für alle!.ods", :floats_as_bigdecimal => true )`
142
+ `SpreadBase::Document.new( "Random numbers für alle!.ods", floats_as_bigdecimal: true )`
143
143
 
144
- - The gem has been tested on Ruby 1.9.3-p125, on Linux and Mac OS X.
144
+ - The gem is tested on all the supported Ruby versions (see [Build](https://github.com/saveriomiroddi/spreadbase/actions/workflows/ci.yml)), and used mainly on Linux.
145
145
  - The column widths are retained (decoding/encoding), but at the current version, they're not [officially] accessible via any API.
146
146
 
147
147
  Currently unsupported features
@@ -154,5 +154,3 @@ Roadmap/Todo
154
154
  ------------
155
155
 
156
156
  https://github.com/saveriomiroddi/spreadbase/wiki/Todo-%28roadmap%29
157
-
158
- [BS img]: https://travis-ci.org/saveriomiroddi/spreadbase.svg?branch=master
@@ -1,4 +1,4 @@
1
- require 'zipruby'
1
+ require 'zip'
2
2
  require 'rexml/document'
3
3
 
4
4
  module SpreadBase # :nodoc:
@@ -37,11 +37,9 @@ module SpreadBase # :nodoc:
37
37
  document_buffer = encode_to_content_xml(el_document, options)
38
38
  zip_buffer = ''
39
39
 
40
- Zip::Archive.open_buffer(zip_buffer, Zip::CREATE) do | zip_file |
41
- zip_file.add_dir('META-INF')
42
-
43
- zip_file.add_buffer('META-INF/manifest.xml', MANIFEST_XML);
44
- zip_file.add_buffer('content.xml', document_buffer);
40
+ Zip::File.open_buffer(zip_buffer) do | zip_file |
41
+ zip_file.get_output_stream('META-INF/manifest.xml') { |f| f << MANIFEST_XML }
42
+ zip_file.get_output_stream('content.xml') { |f| f << document_buffer }
45
43
  end
46
44
 
47
45
  zip_buffer
@@ -61,9 +59,7 @@ module SpreadBase # :nodoc:
61
59
  # _returns_ the SpreadBase::Document instance.
62
60
  #
63
61
  def decode_archive(zip_buffer, options={})
64
- content_xml_data = Zip::Archive.open_buffer(zip_buffer) do | zip_file |
65
- zip_file.fopen('content.xml') { | file | file.read }
66
- end
62
+ content_xml_data = read_content_xml(zip_buffer)
67
63
 
68
64
  decode_content_xml(content_xml_data, options)
69
65
  end
@@ -109,6 +105,22 @@ module SpreadBase # :nodoc:
109
105
 
110
106
  private
111
107
 
108
+ def read_content_xml(zip_buffer)
109
+ io = StringIO.new(zip_buffer)
110
+
111
+ zip_file = if using_rubyzip_3?
112
+ Zip::File.new(io, buffer: true)
113
+ else
114
+ Zip::File.new(io, false, true)
115
+ end
116
+
117
+ zip_file.read('content.xml')
118
+ end
119
+
120
+ def using_rubyzip_3?
121
+ Gem.loaded_specs['rubyzip'].version >= Gem::Version.new('3.0.0')
122
+ end
123
+
112
124
  def pretty_xml(document)
113
125
  buffer = ""
114
126
 
@@ -59,7 +59,7 @@ module SpreadBase # :nodoc:
59
59
  # A single column/row can represent multiple columns (table:number-(columns|rows)-repeated)
60
60
  #
61
61
  table.column_width_styles = column_nodes.inject([]) { | current_styles, node | current_styles + decode_column_width_style(node) }
62
- table.data = row_nodes.inject([]) { | current_rows, node | current_rows + decode_row_node(node, options) }
62
+ table.data = decode_row_nodes(row_nodes, options)
63
63
 
64
64
  table
65
65
  end
@@ -73,23 +73,48 @@ module SpreadBase # :nodoc:
73
73
  make_array_from_repetitions(style_name, repetitions)
74
74
  end
75
75
 
76
+ def decode_row_nodes(row_nodes, options)
77
+ rows = []
78
+ row_nodes.inject(0) do |size, node|
79
+ row, repetitions = decode_row_node(node, options)
80
+ row.empty? || append_row(rows, size, row, repetitions)
81
+ size + repetitions
82
+ end
83
+ rows
84
+ end
85
+
76
86
  def decode_row_node(row_node, options)
77
87
  repetitions = (row_node.attributes['table:number-rows-repeated'] || '1').to_i
78
88
  cell_nodes = row_node.elements.to_a('table:table-cell')
79
89
 
80
- # Watch out the :flatten; a single cell can represent multiple cells (table:number-columns-repeated)
81
- #
82
- values = cell_nodes.map { | node | decode_cell_node(node, options) }.flatten
90
+ [decode_cell_nodes(cell_nodes, options), repetitions]
91
+ end
83
92
 
84
- make_array_from_repetitions(values, repetitions)
93
+ def append_row(rows, size, row, repetitions)
94
+ (size - rows.size).times { rows << [] }
95
+ rows.concat(make_array_from_repetitions(row, repetitions))
85
96
  end
86
97
 
87
- def decode_cell_node(cell_node, options)
88
- value = decode_cell_value(cell_node, options)
98
+ def decode_cell_nodes(cell_nodes, options)
99
+ cells = []
100
+ cell_nodes.inject(0) do |size, node|
101
+ cell, repetitions = decode_cell_node(node, options)
102
+ cell.nil? || append_cell(cells, size, cell, repetitions)
103
+ size + repetitions
104
+ end
105
+ cells
106
+ end
89
107
 
90
- repetitions = (cell_node.attributes['table:number-columns-repeated'] || '1').to_i
108
+ def decode_cell_node(cell_node, options)
109
+ [
110
+ decode_cell_value(cell_node, options),
111
+ (cell_node.attributes['table:number-columns-repeated'] || '1').to_i
112
+ ]
113
+ end
91
114
 
92
- make_array_from_repetitions(value, repetitions)
115
+ def append_cell(cells, size, cell, repetitions)
116
+ cells[size - 1] = nil if size != cells.size
117
+ cells.concat(make_array_from_repetitions(cell, repetitions))
93
118
  end
94
119
 
95
120
  def decode_cell_value(cell_node, options)
@@ -1,3 +1,3 @@
1
1
  module SpreadBase
2
- VERSION = "0.1.4"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -15,7 +15,7 @@ describe SpreadBase::Codecs::OpenDocument12 do
15
15
  'abc', [
16
16
  [1, 1.1, T_BIGDECIMAL],
17
17
  [T_DATE, T_DATETIME, T_TIME],
18
- [nil, 'a', nil]
18
+ [nil, nil, 'a']
19
19
  ]
20
20
  )
21
21
 
@@ -56,8 +56,8 @@ describe SpreadBase::Codecs::OpenDocument12 do
56
56
 
57
57
  assert_size(row_3, 3) do | value_1, value_2, value_3 |
58
58
  expect(value_1).to eq(nil)
59
- expect(value_2).to eq('a')
60
- expect(value_3).to eq(nil)
59
+ expect(value_2).to eq(nil)
60
+ expect(value_3).to eq('a')
61
61
  end
62
62
 
63
63
  end
@@ -112,4 +112,90 @@ describe SpreadBase::Codecs::OpenDocument12 do
112
112
  expect(value).to eq(T_BIGDECIMAL)
113
113
  end
114
114
 
115
+ context "when cells at the end of the row are empty" do
116
+ let(:document_archive) do
117
+ document = SpreadBase::Document.new
118
+
119
+ document.tables << SpreadBase::Table.new(
120
+ 'abc', [
121
+ [nil],
122
+ [nil, nil],
123
+ [1 , nil],
124
+ [nil, 1 , nil]
125
+ ]
126
+ )
127
+
128
+ SpreadBase::Codecs::OpenDocument12.new.encode_to_archive(document)
129
+ end
130
+
131
+ it "should drop such cells" do
132
+ document = SpreadBase::Codecs::OpenDocument12.new.decode_archive(document_archive)
133
+ table = document.tables[0]
134
+
135
+ assert_size(table.data, 4) do |row_1, row_2, row_3, row_4|
136
+ assert_size(row_1, 0)
137
+
138
+ assert_size(row_2, 0)
139
+
140
+ assert_size(row_3, 1) do |value_1|
141
+ expect(value_1).to eq(1)
142
+ end
143
+
144
+ assert_size(row_4, 2) do |value_1, value_2|
145
+ expect(value_1).to be_nil
146
+ expect(value_2).to eq(1)
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ context "when cells of the last row are empty" do
153
+ let(:document_archive) do
154
+ document = SpreadBase::Document.new
155
+
156
+ document.tables << SpreadBase::Table.new(
157
+ 'abc', [
158
+ []
159
+ ]
160
+ )
161
+
162
+ document.tables << SpreadBase::Table.new(
163
+ 'def', [
164
+ [nil]
165
+ ]
166
+ )
167
+
168
+ document.tables << SpreadBase::Table.new(
169
+ 'ghi', [
170
+ [nil, nil]
171
+ ]
172
+ )
173
+
174
+ document.tables << SpreadBase::Table.new(
175
+ 'jkl', [
176
+ [nil],
177
+ [1],
178
+ [nil]
179
+ ]
180
+ )
181
+
182
+ SpreadBase::Codecs::OpenDocument12.new.encode_to_archive(document)
183
+ end
184
+
185
+ it "should drop such row" do
186
+ document = SpreadBase::Codecs::OpenDocument12.new.decode_archive(document_archive)
187
+ tables = document.tables
188
+
189
+ assert_size(tables, 4) do |table_1, table_2, table_3, table_4|
190
+ assert_size(table_1.data, 0)
191
+
192
+ assert_size(table_2.data, 0)
193
+
194
+ assert_size(table_3.data, 0)
195
+
196
+ assert_size(table_4.data, 2)
197
+ end
198
+ end
199
+ end
200
+
115
201
  end
@@ -109,4 +109,27 @@ abc:
109
109
  expect(@sample_document.to_s(with_headers: true)).to eq(expected_string)
110
110
  end
111
111
 
112
+ it "should parse a existing ODS file" do
113
+ ods_file = File.expand_path('../fixtures/test.ods', __dir__)
114
+ document = SpreadBase::Document.new(ods_file)
115
+
116
+ expect(document.tables[0].name).to eq('Sheet1')
117
+ expect(document.tables[0].data).to match([
118
+ match(['hoge' ]),
119
+ match([nil , 'fuga' ]),
120
+ match([nil , nil , 'piyo' ]),
121
+ match([nil , nil , nil , 'hogera' ]),
122
+ match([nil , nil , nil , nil , 'hogehoge'])
123
+ ])
124
+
125
+ expect(document.tables[1].name).to eq('Sheet2')
126
+ expect(document.tables[1].data).to match([
127
+ match([nil , nil , nil , nil , 'foo']),
128
+ match([nil , nil , nil , 'bar' ]),
129
+ match([nil , nil , 'baz' ]),
130
+ match([nil , 'foobar' ]),
131
+ match(['qux' ])
132
+ ])
133
+ end
134
+
112
135
  end
Binary file
data/spreadbase.gemspec CHANGED
@@ -8,16 +8,16 @@ Gem::Specification.new do |s|
8
8
  s.name = "spreadbase"
9
9
  s.version = SpreadBase::VERSION
10
10
  s.platform = Gem::Platform::RUBY
11
- s.required_ruby_version = '>= 2.3.0'
11
+ s.required_ruby_version = '>= 2.4.0'
12
12
  s.authors = ["Saverio Miroddi"]
13
- s.date = '2020-02-03'
13
+ s.date = '2021-12-31'
14
14
  s.email = ["saverio.pub2@gmail.com"]
15
15
  s.homepage = "https://github.com/saveriomiroddi/spreadbase"
16
16
  s.summary = %q{Library for reading/writing OpenOffice Calc documents.}
17
17
  s.description = %q{Library for reading/writing OpenOffice Calc documents.}
18
18
  s.license = "GPL-3.0"
19
19
 
20
- s.add_runtime_dependency "zipruby", "~>0.3.6"
20
+ s.add_runtime_dependency "rubyzip", ">=2.3.0"
21
21
  s.add_development_dependency "rspec", "~>3.9.0"
22
22
 
23
23
  s.add_development_dependency "rake", "~>13.0"
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spreadbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Saverio Miroddi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-03 00:00:00.000000000 Z
11
+ date: 2021-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: zipruby
14
+ name: rubyzip
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.3.6
19
+ version: 2.3.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.3.6
26
+ version: 2.3.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -59,9 +59,9 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
+ - ".github/workflows/ci.yml"
62
63
  - ".gitignore"
63
64
  - ".rspec"
64
- - ".travis.yml"
65
65
  - Gemfile
66
66
  - LICENSE
67
67
  - README.md
@@ -80,6 +80,7 @@ files:
80
80
  - spec/codecs/open_document_12_spec.rb
81
81
  - spec/elements/document_spec.rb
82
82
  - spec/elements/table_spec.rb
83
+ - spec/fixtures/test.ods
83
84
  - spec/spec_helper.rb
84
85
  - spec/spec_helpers.rb
85
86
  - spreadbase.gemspec
@@ -100,14 +101,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
101
  requirements:
101
102
  - - ">="
102
103
  - !ruby/object:Gem::Version
103
- version: 2.3.0
104
+ version: 2.4.0
104
105
  required_rubygems_version: !ruby/object:Gem::Requirement
105
106
  requirements:
106
107
  - - ">="
107
108
  - !ruby/object:Gem::Version
108
109
  version: '0'
109
110
  requirements: []
110
- rubygems_version: 3.0.6
111
+ rubygems_version: 3.2.22
111
112
  signing_key:
112
113
  specification_version: 4
113
114
  summary: Library for reading/writing OpenOffice Calc documents.
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- dist: bionic
2
- language: ruby
3
- rvm:
4
- - 2.3
5
- - 2.4
6
- - 2.5
7
- - 2.6