spreadbase 0.1.4 → 0.4.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +25 -0
- data/Gemfile +4 -0
- data/README.md +3 -5
- data/lib/spreadbase/codecs/open_document_12.rb +21 -9
- data/lib/spreadbase/codecs/open_document_12_modules/decoding.rb +34 -9
- data/lib/spreadbase/version.rb +1 -1
- data/spec/codecs/open_document_12_spec.rb +89 -3
- data/spec/elements/document_spec.rb +23 -0
- data/spec/fixtures/test.ods +0 -0
- data/spreadbase.gemspec +3 -3
- metadata +11 -10
- data/.travis.yml +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37e52d4079a3f0f7c0ba6fef6db24dbe8426f1f47d66904ea9fa418744719e27
|
4
|
+
data.tar.gz: 79304c560419b6500e95f9c4fb5c8d8bfbf9ffe3ed1b591125ab696be5652560
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[](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", :
|
142
|
+
`SpreadBase::Document.new( "Random numbers für alle!.ods", floats_as_bigdecimal: true )`
|
143
143
|
|
144
|
-
- The gem
|
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 '
|
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::
|
41
|
-
zip_file.
|
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 =
|
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
|
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
|
-
|
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
|
-
|
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
|
88
|
-
|
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
|
-
|
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
|
-
|
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)
|
data/lib/spreadbase/version.rb
CHANGED
@@ -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'
|
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(
|
60
|
-
expect(value_3).to eq(
|
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.
|
11
|
+
s.required_ruby_version = '>= 2.4.0'
|
12
12
|
s.authors = ["Saverio Miroddi"]
|
13
|
-
s.date = '
|
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 "
|
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.
|
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:
|
11
|
+
date: 2021-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rubyzip
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
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:
|
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.
|
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.
|
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.
|