spreadbase 0.1.3 → 0.1.4
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 +7 -0
- data/.gitignore +3 -2
- data/.rspec +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +674 -0
- data/README.md +12 -17
- data/Rakefile +5 -0
- data/docs/STRUCTURE.md +3 -0
- data/docs/TESTING.md +11 -0
- data/lib/spreadbase/cell.rb +19 -0
- data/lib/spreadbase/codecs/open_document_12.rb +19 -41
- data/lib/spreadbase/codecs/open_document_12_modules/decoding.rb +72 -92
- data/lib/spreadbase/codecs/open_document_12_modules/encoding.rb +43 -72
- data/lib/spreadbase/document.rb +12 -33
- data/lib/spreadbase/helpers/helpers.rb +27 -61
- data/lib/spreadbase/table.rb +120 -86
- data/lib/spreadbase/version.rb +1 -3
- data/lib/spreadbase.rb +7 -28
- data/spec/codecs/open_document_12_spec.rb +42 -64
- data/spec/elements/document_spec.rb +33 -55
- data/spec/elements/table_spec.rb +186 -174
- data/spec/spec_helper.rb +100 -0
- data/spec/spec_helpers.rb +10 -30
- data/spreadbase.gemspec +14 -9
- data/utils/convert_sqlite_to_ods.rb +30 -49
- data/utils/test_ods_folder.rb +7 -26
- data/utils/test_recoding_file.rb +11 -27
- data/utils/test_recoding_from_content.rb +10 -29
- data/utils/utils_helpers.rb +19 -33
- metadata +41 -26
- data/COPYING.LESSER +0 -165
- data/utils/prettify_file.rb +0 -46
data/lib/spreadbase/document.rb
CHANGED
@@ -1,23 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
=begin
|
4
|
-
Copyright 2012 Saverio Miroddi saverio.pub2 <a-hat!> gmail.com
|
5
|
-
|
6
|
-
This file is part of SpreadBase.
|
7
|
-
|
8
|
-
SpreadBase is free software: you can redistribute it and/or modify it under the
|
9
|
-
terms of the GNU Lesser General Public License as published by the Free Software
|
10
|
-
Foundation, either version 3 of the License, or (at your option) any later
|
11
|
-
version.
|
12
|
-
|
13
|
-
SpreadBase is distributed in the hope that it will be useful, but WITHOUT ANY
|
14
|
-
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
15
|
-
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
16
|
-
|
17
|
-
You should have received a copy of the GNU Lesser General Public License along
|
18
|
-
with SpreadBase. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
=end
|
20
|
-
|
21
1
|
module SpreadBase # :nodoc:
|
22
2
|
|
23
3
|
# Represents the abstraction of a document, merging both the file and the
|
@@ -42,16 +22,15 @@ module SpreadBase # :nodoc:
|
|
42
22
|
#
|
43
23
|
# _options_:
|
44
24
|
#
|
45
|
-
# +force_18_strings_encoding+:: ('UTF-8') on ruby 1.8, when converting to UTF-8, assume the strings are using the specified format.
|
46
25
|
# +floats_as_bigdecimal+:: (false) decode floats as BigDecimal instead of Float
|
47
26
|
#
|
48
|
-
def initialize(
|
27
|
+
def initialize(document_path=nil, options={})
|
49
28
|
@document_path = document_path
|
50
29
|
@options = options.clone
|
51
30
|
|
52
|
-
if @document_path && File.
|
53
|
-
document_archive = IO.read(
|
54
|
-
decoded_document = Codecs::OpenDocument12.new.decode_archive(
|
31
|
+
if @document_path && File.exist?(document_path)
|
32
|
+
document_archive = IO.read(document_path)
|
33
|
+
decoded_document = Codecs::OpenDocument12.new.decode_archive(document_archive, options)
|
55
34
|
|
56
35
|
@column_width_styles = decoded_document.column_width_styles
|
57
36
|
@tables = decoded_document.tables
|
@@ -69,28 +48,28 @@ module SpreadBase # :nodoc:
|
|
69
48
|
#
|
70
49
|
# +prettify+:: Prettifies the content.xml file before saving.
|
71
50
|
#
|
72
|
-
def save(
|
73
|
-
options = @options.merge(
|
51
|
+
def save(options={})
|
52
|
+
options = @options.merge(options)
|
74
53
|
|
75
54
|
raise "At least one table must be present" if @tables.empty?
|
76
55
|
raise "Document path not specified" if @document_path.nil?
|
77
56
|
|
78
|
-
document_archive = Codecs::OpenDocument12.new.encode_to_archive(
|
57
|
+
document_archive = Codecs::OpenDocument12.new.encode_to_archive(self, options)
|
79
58
|
|
80
|
-
File.open(
|
59
|
+
File.open(@document_path, 'wb') { | file | file << document_archive }
|
81
60
|
end
|
82
61
|
|
83
62
|
# _options_:
|
84
63
|
#
|
85
64
|
# +with_headers+:: Print the tables with headers.
|
86
65
|
#
|
87
|
-
def to_s(
|
88
|
-
options.merge!(
|
66
|
+
def to_s(options={})
|
67
|
+
options.merge!(row_prefix: ' ')
|
89
68
|
|
90
|
-
tables.inject(
|
69
|
+
tables.inject('') do | output, table |
|
91
70
|
output << "#{ table.name }:" << "\n" << "\n"
|
92
71
|
|
93
|
-
output << table.to_s(
|
72
|
+
output << table.to_s(options) << "\n"
|
94
73
|
end
|
95
74
|
end
|
96
75
|
|
@@ -1,23 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
=begin
|
4
|
-
Copyright 2012 Saverio Miroddi saverio.pub2 <a-hat!> gmail.com
|
5
|
-
|
6
|
-
This file is part of SpreadBase.
|
7
|
-
|
8
|
-
SpreadBase is free software: you can redistribute it and/or modify it under the
|
9
|
-
terms of the GNU Lesser General Public License as published by the Free Software
|
10
|
-
Foundation, either version 3 of the License, or (at your option) any later
|
11
|
-
version.
|
12
|
-
|
13
|
-
SpreadBase is distributed in the hope that it will be useful, but WITHOUT ANY
|
14
|
-
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
15
|
-
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
16
|
-
|
17
|
-
You should have received a copy of the GNU Lesser General Public License along
|
18
|
-
with SpreadBase. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
=end
|
20
|
-
|
21
1
|
module SpreadBase # :nodoc:
|
22
2
|
|
23
3
|
# Currently generic helper class
|
@@ -28,10 +8,10 @@ module SpreadBase # :nodoc:
|
|
28
8
|
#
|
29
9
|
# The instance is duplicated Object#clone, when necessary - note that this method is not meant to do a deep copy.
|
30
10
|
#
|
31
|
-
def make_array_from_repetitions(
|
32
|
-
(
|
11
|
+
def make_array_from_repetitions(instance, repetitions)
|
12
|
+
(1..repetitions).inject([]) do | cumulative_result, i |
|
33
13
|
case instance
|
34
|
-
when
|
14
|
+
when Integer, Float, BigDecimal, Date, Time, TrueClass, FalseClass, NilClass #, DateTime is a Date
|
35
15
|
cumulative_result << instance
|
36
16
|
when String, Array
|
37
17
|
cumulative_result << instance.clone
|
@@ -54,54 +34,49 @@ module SpreadBase # :nodoc:
|
|
54
34
|
# +row_prefix+:: Prefix this string to each row.
|
55
35
|
# +with_header+:: First row will be separated from the remaining ones.
|
56
36
|
#
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
def pretty_print_rows( rows, options={}, &formatting_block )
|
61
|
-
row_prefix = options[ :row_prefix ] || ''
|
62
|
-
with_headers = options[ :with_headers ]
|
37
|
+
def pretty_print_rows(rows, options={})
|
38
|
+
row_prefix = options[:row_prefix] || ''
|
39
|
+
with_headers = options[:with_headers]
|
63
40
|
|
64
41
|
output = ""
|
65
42
|
|
66
|
-
formatting_block = lambda { | value | value.to_s } if ! block_given?
|
67
|
-
|
68
43
|
if rows.size > 0
|
69
|
-
max_column_sizes = [
|
44
|
+
max_column_sizes = [0] * rows.map(&:size).max
|
70
45
|
|
71
46
|
# Compute maximum widths
|
72
47
|
|
73
48
|
rows.each do | values |
|
74
49
|
values.each_with_index do | value, i |
|
75
|
-
formatted_value = pretty_print_value(
|
50
|
+
formatted_value = pretty_print_value(value)
|
76
51
|
formatted_value_width = formatted_value.chars.to_a.size
|
77
52
|
|
78
|
-
max_column_sizes[
|
53
|
+
max_column_sizes[i] = formatted_value_width if formatted_value_width > max_column_sizes[i]
|
79
54
|
end
|
80
55
|
end
|
81
56
|
|
82
57
|
# Print!
|
83
58
|
|
84
|
-
output << row_prefix << '+-' + max_column_sizes.map { | size | '-' * size }.join(
|
59
|
+
output << row_prefix << '+-' + max_column_sizes.map { | size | '-' * size }.join('-+-') + '-+' << "\n"
|
85
60
|
|
86
|
-
print_pattern = '| ' + max_column_sizes.map { | size | "%-#{ size }s" }.join(
|
61
|
+
print_pattern = '| ' + max_column_sizes.map { | size | "%-#{ size }s" }.join(' | ') + ' |'
|
87
62
|
|
88
63
|
rows.each_with_index do | row, row_index |
|
89
64
|
# Ensure that we always have a number of values equal to the max width
|
90
65
|
#
|
91
|
-
formatted_row_values = (
|
92
|
-
value = row[
|
66
|
+
formatted_row_values = (0...max_column_sizes.size).map do | column_index |
|
67
|
+
value = row[column_index]
|
93
68
|
|
94
|
-
pretty_print_value(
|
69
|
+
pretty_print_value(value)
|
95
70
|
end
|
96
71
|
|
97
72
|
output << row_prefix << print_pattern % formatted_row_values << "\n"
|
98
73
|
|
99
74
|
if with_headers && row_index == 0
|
100
|
-
output << row_prefix << '+-' + max_column_sizes.map { | size | '-' * size }.join(
|
75
|
+
output << row_prefix << '+-' + max_column_sizes.map { | size | '-' * size }.join('-+-') + '-+' << "\n"
|
101
76
|
end
|
102
77
|
end
|
103
78
|
|
104
|
-
output << row_prefix << '+-' + max_column_sizes.map { | size | '-' * size }.join(
|
79
|
+
output << row_prefix << '+-' + max_column_sizes.map { | size | '-' * size }.join('-+-') + '-+' << "\n"
|
105
80
|
end
|
106
81
|
|
107
82
|
output
|
@@ -109,27 +84,18 @@ module SpreadBase # :nodoc:
|
|
109
84
|
|
110
85
|
private
|
111
86
|
|
112
|
-
def pretty_print_value(
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
87
|
+
def pretty_print_value(value)
|
88
|
+
case value
|
89
|
+
when BigDecimal
|
90
|
+
value.to_s('F')
|
91
|
+
when Time, DateTime
|
92
|
+
value.strftime('%Y-%m-%d %H:%M:%S %z')
|
93
|
+
when String, Date, Numeric, TrueClass, FalseClass
|
94
|
+
value.to_s
|
95
|
+
when nil
|
96
|
+
"NIL"
|
117
97
|
else
|
118
|
-
|
119
|
-
when BigDecimal
|
120
|
-
value.to_s( 'F' )
|
121
|
-
when Time, DateTime
|
122
|
-
# Time#to_s renders differently between 1.8.7 and 1.9.3; 1.8.7's rendering is bizarrely
|
123
|
-
# inconsistent with the Date and DateTime ones.
|
124
|
-
#
|
125
|
-
value.strftime( '%Y-%m-%d %H:%M:%S %z' )
|
126
|
-
when String, Date, Numeric, TrueClass, FalseClass
|
127
|
-
value.to_s
|
128
|
-
when nil
|
129
|
-
"NIL"
|
130
|
-
else
|
131
|
-
value.inspect
|
132
|
-
end
|
98
|
+
value.inspect
|
133
99
|
end
|
134
100
|
end
|
135
101
|
|
data/lib/spreadbase/table.rb
CHANGED
@@ -1,23 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
=begin
|
4
|
-
Copyright 2012 Saverio Miroddi saverio.pub2 <a-hat!> gmail.com
|
5
|
-
|
6
|
-
This file is part of SpreadBase.
|
7
|
-
|
8
|
-
SpreadBase is free software: you can redistribute it and/or modify it under the
|
9
|
-
terms of the GNU Lesser General Public License as published by the Free Software
|
10
|
-
Foundation, either version 3 of the License, or (at your option) any later
|
11
|
-
version.
|
12
|
-
|
13
|
-
SpreadBase is distributed in the hope that it will be useful, but WITHOUT ANY
|
14
|
-
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
15
|
-
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
16
|
-
|
17
|
-
You should have received a copy of the GNU Lesser General Public License along
|
18
|
-
with SpreadBase. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
=end
|
20
|
-
|
21
1
|
module SpreadBase # :nodoc:
|
22
2
|
|
23
3
|
# Represents the abstraction of a table and its contents.
|
@@ -32,7 +12,7 @@ module SpreadBase # :nodoc:
|
|
32
12
|
|
33
13
|
include SpreadBase::Helpers
|
34
14
|
|
35
|
-
attr_accessor :name
|
15
|
+
attr_accessor :name
|
36
16
|
|
37
17
|
# Array of style names; nil when not associated to any column width.
|
38
18
|
#
|
@@ -41,16 +21,24 @@ module SpreadBase # :nodoc:
|
|
41
21
|
# _params_:
|
42
22
|
#
|
43
23
|
# +name+:: (required) Name of the table
|
44
|
-
# +
|
24
|
+
# +raw_data+:: (Array.new) 2d matrix of the data. if not empty, the rows need to be all of the same size
|
45
25
|
#
|
46
|
-
def initialize(
|
26
|
+
def initialize(name, raw_data=[])
|
47
27
|
raise "Table name required" if name.nil? || name == ''
|
48
28
|
|
49
29
|
@name = name
|
50
|
-
|
30
|
+
self.data = raw_data
|
51
31
|
@column_width_styles = []
|
52
32
|
end
|
53
33
|
|
34
|
+
def data=(the_data)
|
35
|
+
@data = the_data.map { | the_row | array_to_cells(the_row) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def data(options={})
|
39
|
+
@data.map { | the_row | the_row.map { | cell | cell_to_value(cell, options) } }
|
40
|
+
end
|
41
|
+
|
54
42
|
# Access a cell value.
|
55
43
|
#
|
56
44
|
# _params_:
|
@@ -60,13 +48,14 @@ module SpreadBase # :nodoc:
|
|
60
48
|
#
|
61
49
|
# _returns_ the value, which is automatically converted to the Ruby data type.
|
62
50
|
#
|
63
|
-
def [](
|
64
|
-
|
65
|
-
column_index = decode_column_identifier( column_identifier )
|
51
|
+
def [](column_identifier, row_index, options={})
|
52
|
+
the_row = row(row_index, options)
|
66
53
|
|
67
|
-
|
54
|
+
column_index = decode_column_identifier(column_identifier)
|
68
55
|
|
69
|
-
|
56
|
+
check_column_index(the_row, column_index)
|
57
|
+
|
58
|
+
the_row[column_index]
|
70
59
|
end
|
71
60
|
|
72
61
|
# Writes a value in a cell.
|
@@ -77,13 +66,15 @@ module SpreadBase # :nodoc:
|
|
77
66
|
# +row_index+:: int (0-based). see notes about the rows indexing.
|
78
67
|
# +value+:: value
|
79
68
|
#
|
80
|
-
def []=(
|
81
|
-
|
82
|
-
|
69
|
+
def []=(column_identifier, row_index, value)
|
70
|
+
check_row_index(row_index)
|
71
|
+
|
72
|
+
the_row = @data[row_index]
|
73
|
+
column_index = decode_column_identifier(column_identifier)
|
83
74
|
|
84
|
-
check_column_index(
|
75
|
+
check_column_index(the_row, column_index)
|
85
76
|
|
86
|
-
|
77
|
+
the_row[column_index] = value_to_cell(value)
|
87
78
|
end
|
88
79
|
|
89
80
|
# Returns an array containing the values of a single row.
|
@@ -92,10 +83,14 @@ module SpreadBase # :nodoc:
|
|
92
83
|
#
|
93
84
|
# +row_index+:: int or range (0-based). see notes about the rows indexing.
|
94
85
|
#
|
95
|
-
def row(
|
96
|
-
check_row_index(
|
86
|
+
def row(row_index, options={})
|
87
|
+
check_row_index(row_index)
|
97
88
|
|
98
|
-
|
89
|
+
if row_index.is_a?(Range)
|
90
|
+
@data[row_index].map { | row | cells_to_array(row, options) }
|
91
|
+
else
|
92
|
+
cells_to_array(@data[row_index], options)
|
93
|
+
end
|
99
94
|
end
|
100
95
|
|
101
96
|
# Deletes a row.
|
@@ -108,10 +103,16 @@ module SpreadBase # :nodoc:
|
|
108
103
|
#
|
109
104
|
# _returns_ the deleted row[s]
|
110
105
|
#
|
111
|
-
def delete_row(
|
112
|
-
check_row_index(
|
106
|
+
def delete_row(row_index)
|
107
|
+
check_row_index(row_index)
|
108
|
+
|
109
|
+
deleted_cells = @data.slice!(row_index)
|
113
110
|
|
114
|
-
|
111
|
+
if row_index.is_a?(Range)
|
112
|
+
deleted_cells.map { | row | cells_to_array(row) }
|
113
|
+
else
|
114
|
+
cells_to_array(deleted_cells)
|
115
|
+
end
|
115
116
|
end
|
116
117
|
|
117
118
|
# Inserts a row.
|
@@ -123,16 +124,18 @@ module SpreadBase # :nodoc:
|
|
123
124
|
# +row_index+:: int (0-based). must be between 0 and (including) the table rows size.
|
124
125
|
# +row+:: array of values. if the table is not empty, must have the same size of the table width.
|
125
126
|
#
|
126
|
-
def insert_row(
|
127
|
-
check_row_index(
|
127
|
+
def insert_row(row_index, row)
|
128
|
+
check_row_index(row_index, allow_append: true)
|
128
129
|
|
129
|
-
|
130
|
+
cells = array_to_cells(row)
|
131
|
+
|
132
|
+
@data.insert(row_index, cells)
|
130
133
|
end
|
131
134
|
|
132
135
|
# This operation won't modify the column width styles in any case.
|
133
136
|
#
|
134
|
-
def append_row(
|
135
|
-
insert_row(
|
137
|
+
def append_row(row)
|
138
|
+
insert_row(@data.size, row)
|
136
139
|
end
|
137
140
|
|
138
141
|
# Returns an array containing the values of a single column.
|
@@ -146,21 +149,25 @@ module SpreadBase # :nodoc:
|
|
146
149
|
# for multiple access, use a range either of int or excel-format identifiers - pay attention, because ( 'A'..'c' ) is not semantically correct.
|
147
150
|
# interestingly, ruby letter ranges convention is the same as the excel columns one.
|
148
151
|
#
|
149
|
-
def column(
|
150
|
-
if column_identifier.is_a?(
|
151
|
-
min_index = decode_column_identifier(
|
152
|
-
max_index = decode_column_identifier(
|
152
|
+
def column(column_identifier, options={})
|
153
|
+
if column_identifier.is_a?(Range)
|
154
|
+
min_index = decode_column_identifier(column_identifier.min)
|
155
|
+
max_index = decode_column_identifier(column_identifier.max)
|
153
156
|
|
154
|
-
(
|
155
|
-
@data.map do |
|
156
|
-
|
157
|
+
(min_index..max_index).map do | column_index |
|
158
|
+
@data.map do | the_row |
|
159
|
+
cell = the_row[column_index]
|
160
|
+
|
161
|
+
cell_to_value(cell, options)
|
157
162
|
end
|
158
163
|
end
|
159
164
|
else
|
160
|
-
column_index = decode_column_identifier(
|
165
|
+
column_index = decode_column_identifier(column_identifier)
|
161
166
|
|
162
|
-
@data.map do |
|
163
|
-
|
167
|
+
@data.map do | the_row |
|
168
|
+
cell = the_row[column_index]
|
169
|
+
|
170
|
+
cell_to_value(cell, options)
|
164
171
|
end
|
165
172
|
end
|
166
173
|
end
|
@@ -175,25 +182,29 @@ module SpreadBase # :nodoc:
|
|
175
182
|
#
|
176
183
|
# _returns_ the deleted column
|
177
184
|
#
|
178
|
-
def delete_column(
|
179
|
-
if column_identifier.is_a?(
|
180
|
-
min_index = decode_column_identifier(
|
181
|
-
max_index = decode_column_identifier(
|
185
|
+
def delete_column(column_identifier)
|
186
|
+
if column_identifier.is_a?(Range)
|
187
|
+
min_index = decode_column_identifier(column_identifier.min)
|
188
|
+
max_index = decode_column_identifier(column_identifier.max)
|
182
189
|
|
183
|
-
reverse_result = max_index.downto(
|
190
|
+
reverse_result = max_index.downto(min_index).map do | column_index |
|
184
191
|
@data.map do | row |
|
185
|
-
row.slice!(
|
192
|
+
cell = row.slice!(column_index)
|
193
|
+
|
194
|
+
cell_to_value(cell)
|
186
195
|
end
|
187
196
|
end
|
188
197
|
|
189
198
|
reverse_result.reverse
|
190
199
|
else
|
191
|
-
column_index = decode_column_identifier(
|
200
|
+
column_index = decode_column_identifier(column_identifier)
|
192
201
|
|
193
|
-
@column_width_styles.slice!(
|
202
|
+
@column_width_styles.slice!(column_index)
|
194
203
|
|
195
204
|
@data.map do | row |
|
196
|
-
row.slice!(
|
205
|
+
cell = row.slice!(column_index)
|
206
|
+
|
207
|
+
cell_to_value(cell)
|
197
208
|
end
|
198
209
|
end
|
199
210
|
end
|
@@ -208,37 +219,63 @@ module SpreadBase # :nodoc:
|
|
208
219
|
# when int, follow the same idea of the rows indexing (ruby semantics).
|
209
220
|
# +column+:: array of values. if the table is not empty, it must have the same size of the table height.
|
210
221
|
#
|
211
|
-
def insert_column(
|
222
|
+
def insert_column(column_identifier, column)
|
212
223
|
raise "Inserting column size (#{ column.size }) different than existing columns size (#{ @data.size })" if @data.size > 0 && column.size != @data.size
|
213
224
|
|
214
|
-
column_index = decode_column_identifier(
|
225
|
+
column_index = decode_column_identifier(column_identifier)
|
215
226
|
|
216
|
-
@column_width_styles.insert(
|
227
|
+
@column_width_styles.insert(column_index, nil)
|
217
228
|
|
218
229
|
if @data.size > 0
|
219
|
-
@data.zip(
|
220
|
-
|
230
|
+
@data.zip(column).each do | row, value |
|
231
|
+
cell = value_to_cell(value)
|
232
|
+
|
233
|
+
row.insert(column_index, cell)
|
221
234
|
end
|
222
235
|
else
|
223
|
-
@data = column.map
|
236
|
+
@data = column.map do | value |
|
237
|
+
[value_to_cell(value)]
|
238
|
+
end
|
224
239
|
end
|
225
240
|
|
226
241
|
end
|
227
242
|
|
228
|
-
def append_column(
|
243
|
+
def append_column(column)
|
229
244
|
column_index = @data.size > 0 ? @data.first.size : 0
|
230
245
|
|
231
|
-
insert_column(
|
246
|
+
insert_column(column_index, column)
|
232
247
|
end
|
233
248
|
|
234
249
|
# _returns_ a matrix representation of the tables, with the values being separated by commas.
|
235
250
|
#
|
236
|
-
def to_s(
|
237
|
-
pretty_print_rows(
|
251
|
+
def to_s(options={})
|
252
|
+
pretty_print_rows(data, options)
|
238
253
|
end
|
239
254
|
|
240
255
|
private
|
241
256
|
|
257
|
+
def array_to_cells(the_row)
|
258
|
+
the_row.map { | value | value_to_cell(value) }
|
259
|
+
end
|
260
|
+
|
261
|
+
def value_to_cell(value)
|
262
|
+
value.is_a?(Cell) ? value : Cell.new(value)
|
263
|
+
end
|
264
|
+
|
265
|
+
def cells_to_array(cells, options={})
|
266
|
+
cells.map { | cell | cell_to_value(cell, options) }
|
267
|
+
end
|
268
|
+
|
269
|
+
def cell_to_value(cell, options={})
|
270
|
+
as_cell = options[:as_cell]
|
271
|
+
|
272
|
+
if as_cell
|
273
|
+
cell
|
274
|
+
else
|
275
|
+
cell.value if cell
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
242
279
|
# Check that row index points to an existing record, or, in case of :allow_append,
|
243
280
|
# point to one unit above the last row.
|
244
281
|
#
|
@@ -246,17 +283,17 @@ module SpreadBase # :nodoc:
|
|
246
283
|
#
|
247
284
|
# +allow_append+:: Allow pointing to one unit above the last row.
|
248
285
|
#
|
249
|
-
def check_row_index(
|
250
|
-
allow_append = options [
|
286
|
+
def check_row_index(row_index, options={})
|
287
|
+
allow_append = options [:allow_append]
|
251
288
|
|
252
289
|
positive_limit = allow_append ? @data.size : @data.size - 1
|
253
290
|
|
254
|
-
row_index = row_index.max if row_index.is_a?(
|
291
|
+
row_index = row_index.max if row_index.is_a?(Range)
|
255
292
|
|
256
293
|
raise "Invalid row index (#{ row_index }) - allowed 0 to #{ positive_limit }" if row_index < 0 || row_index > positive_limit
|
257
294
|
end
|
258
295
|
|
259
|
-
def check_column_index(
|
296
|
+
def check_column_index(row, column_index)
|
260
297
|
raise "Invalid column index (#{ column_index }) for the given row - allowed 0 to #{ row.size - 1 }" if column_index >= row.size
|
261
298
|
end
|
262
299
|
|
@@ -265,12 +302,9 @@ module SpreadBase # :nodoc:
|
|
265
302
|
# Raises an error for invalid identifiers/indexes.
|
266
303
|
#
|
267
304
|
# _returns_ a 0-based decimal number.
|
268
|
-
#--
|
269
|
-
# Motherf#### base-26 bijective numeration - I would have gladly saved my f* time. At least
|
270
|
-
# there were a few cute ladies at the Charleston lesson.
|
271
305
|
#
|
272
|
-
def decode_column_identifier(
|
273
|
-
if column_identifier.is_a?(
|
306
|
+
def decode_column_identifier(column_identifier)
|
307
|
+
if column_identifier.is_a?(Integer)
|
274
308
|
raise "Negative column indexes not allowed: #{ column_identifier }" if column_identifier < 0
|
275
309
|
|
276
310
|
column_identifier
|
@@ -280,9 +314,9 @@ module SpreadBase # :nodoc:
|
|
280
314
|
|
281
315
|
raise "Invalid letter for in column identifier (allowed 'a/A' to 'z/Z')" if letters.any? { | letter | letter < 'A' || letter > 'Z' }
|
282
316
|
|
283
|
-
base_10_value = letters.inject(
|
284
|
-
letter_ord = letter.unpack(
|
285
|
-
sum * 26 + (
|
317
|
+
base_10_value = letters.inject(0) do | sum, letter |
|
318
|
+
letter_ord = letter.unpack('C').first
|
319
|
+
sum * 26 + (letter_ord - upcase_a_ord + 1)
|
286
320
|
end
|
287
321
|
|
288
322
|
base_10_value -= 1
|
data/lib/spreadbase/version.rb
CHANGED
data/lib/spreadbase.rb
CHANGED
@@ -1,33 +1,12 @@
|
|
1
|
-
|
1
|
+
require_relative 'spreadbase/helpers/helpers'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require_relative 'spreadbase/document'
|
4
|
+
require_relative 'spreadbase/table'
|
5
|
+
require_relative 'spreadbase/cell'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
terms of the GNU Lesser General Public License as published by the Free Software
|
10
|
-
Foundation, either version 3 of the License, or (at your option) any later
|
11
|
-
version.
|
12
|
-
|
13
|
-
SpreadBase is distributed in the hope that it will be useful, but WITHOUT ANY
|
14
|
-
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
15
|
-
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
16
|
-
|
17
|
-
You should have received a copy of the GNU Lesser General Public License along
|
18
|
-
with SpreadBase. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
=end
|
20
|
-
|
21
|
-
require 'rubygems'
|
22
|
-
|
23
|
-
require File.expand_path( '../spreadbase/helpers/helpers', __FILE__ )
|
24
|
-
|
25
|
-
require File.expand_path( '../spreadbase/document', __FILE__ )
|
26
|
-
require File.expand_path( '../spreadbase/table', __FILE__ )
|
27
|
-
|
28
|
-
require File.expand_path( '../spreadbase/codecs/open_document_12_modules/encoding', __FILE__ )
|
29
|
-
require File.expand_path( '../spreadbase/codecs/open_document_12_modules/decoding', __FILE__ )
|
30
|
-
require File.expand_path( '../spreadbase/codecs/open_document_12', __FILE__ )
|
7
|
+
require_relative 'spreadbase/codecs/open_document_12_modules/encoding'
|
8
|
+
require_relative 'spreadbase/codecs/open_document_12_modules/decoding'
|
9
|
+
require_relative 'spreadbase/codecs/open_document_12'
|
31
10
|
|
32
11
|
# = Spreadbase
|
33
12
|
#
|