spreadbase 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
#
|