rspreadsheet 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.gitignore +3 -0
- data/.travis.yml +13 -0
- data/COPYING.txt +15 -0
- data/DEVEL_BLOG.md +22 -0
- data/GUIDE.md +28 -12
- data/Gemfile.lock +89 -0
- data/Guardfile +11 -0
- data/LICENSE.md +544 -0
- data/README.md +18 -12
- data/Rakefile +10 -1
- data/lib/class_extensions.rb +36 -0
- data/lib/rspreadsheet/cell.rb +47 -0
- data/lib/rspreadsheet/empty_file_template.ods +0 -0
- data/lib/rspreadsheet/row.rb +30 -0
- data/lib/rspreadsheet/version.rb +1 -1
- data/lib/rspreadsheet/workbook.rb +55 -0
- data/lib/rspreadsheet/worksheet.rb +112 -0
- data/lib/rspreadsheet.rb +10 -1
- data/rspreadsheet.gemspec +19 -3
- data/spec/rspreadsheet_spec.rb +154 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/testfile1.ods +0 -0
- metadata +148 -16
- data/LICENSE.txt +0 -22
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'andand'
|
2
|
+
|
3
|
+
module Rspreadsheet
|
4
|
+
class Cell
|
5
|
+
attr_reader :value,:col,:row, :source_node
|
6
|
+
def initialize(arow,acol,source_node=nil)
|
7
|
+
@col = acol
|
8
|
+
@row = arow
|
9
|
+
@source_node = source_node
|
10
|
+
unless @source_node.nil?
|
11
|
+
@type = @source_node.attributes['value-type'].to_s
|
12
|
+
if (@source_node.children.size == 0) and (not @source_node.attributes?)
|
13
|
+
@value = nil
|
14
|
+
else
|
15
|
+
# here you also ned to read style not only value
|
16
|
+
@value = case @type
|
17
|
+
when 'float'
|
18
|
+
@source_node.attributes['value'].to_f
|
19
|
+
when 'string'
|
20
|
+
@source_node.elements.first.andand.content.to_s
|
21
|
+
when 'date'
|
22
|
+
Date.strptime(@source_node.attributes['date-value'].to_s, '%Y-%m-%d')
|
23
|
+
when 'percentage'
|
24
|
+
@source_node.attributes['value'].to_f
|
25
|
+
else
|
26
|
+
if @source_node.children.size == 0
|
27
|
+
nil
|
28
|
+
else
|
29
|
+
nil
|
30
|
+
# raise "Unknown type from #{@source_node.to_s} / children size=#{@source_node.children.size.to_s} / type=#{@type}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
def to_s
|
37
|
+
value
|
38
|
+
end
|
39
|
+
def value=(avalue)
|
40
|
+
@value=avalue
|
41
|
+
self
|
42
|
+
end
|
43
|
+
def coordinates
|
44
|
+
[row,col]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
Binary file
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require('rspreadsheet/cell')
|
2
|
+
|
3
|
+
# Currently this is only syntax sugar for cells and contains no functionality
|
4
|
+
|
5
|
+
module Rspreadsheet
|
6
|
+
|
7
|
+
class Row
|
8
|
+
def initialize(workbook,rowi)
|
9
|
+
@rowi = rowi
|
10
|
+
@workbook = workbook
|
11
|
+
@rowcells = RowCells.new(workbook,rowi)
|
12
|
+
end
|
13
|
+
def cells
|
14
|
+
@rowcells
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# this allows the row.cells[c] syntax
|
19
|
+
# this object is result of row.cells
|
20
|
+
class RowCells
|
21
|
+
def initialize(workbook,rowi)
|
22
|
+
@rowi = rowi
|
23
|
+
@workbook = workbook
|
24
|
+
end
|
25
|
+
def [] coli
|
26
|
+
@workbook.cells[@rowi,coli]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/rspreadsheet/version.rb
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'zip'
|
2
|
+
require 'libxml'
|
3
|
+
|
4
|
+
module Rspreadsheet
|
5
|
+
class Workbook
|
6
|
+
attr_reader :worksheets, :filename
|
7
|
+
def initialize(afilename=nil)
|
8
|
+
@worksheets={}
|
9
|
+
@filename = afilename
|
10
|
+
if filename.nil?
|
11
|
+
else
|
12
|
+
@content_xml = Zip::File.open(filename) do |zip|
|
13
|
+
LibXML::XML::Document.io zip.get_input_stream('content.xml')
|
14
|
+
end
|
15
|
+
|
16
|
+
ndx = 0
|
17
|
+
@content_xml.find_first('//office:spreadsheet').each_element { |node|
|
18
|
+
sheet = Worksheet.new(node)
|
19
|
+
@worksheets[ndx]=sheet
|
20
|
+
@worksheets[node.name]=sheet
|
21
|
+
ndx+=1
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
def save(new_filename=nil)
|
26
|
+
if @filename.nil? and new_filename.nil? then raise 'New file should be named on first save.' end
|
27
|
+
# if the filename has changed than first copy the original file to new location (or template if it is a new file)
|
28
|
+
if new_filename
|
29
|
+
FileUtils.cp(@filename || './lib/rspreadsheet/empty_file_template.ods', new_filename)
|
30
|
+
@filename = new_filename
|
31
|
+
end
|
32
|
+
Zip::File.open(@filename) do |zip|
|
33
|
+
# it is easy, because @content_xml in in sync with contents all the time
|
34
|
+
zip.get_output_stream('content.xml') do |f|
|
35
|
+
f.write @content_xml
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
def create_worksheet(node=nil)
|
40
|
+
sheet = Worksheet.new(node)
|
41
|
+
@worksheets[worksheets_count]=sheet
|
42
|
+
@worksheets[node.name]=sheet unless node.nil?
|
43
|
+
return sheet
|
44
|
+
end
|
45
|
+
def worksheets
|
46
|
+
@worksheets
|
47
|
+
end
|
48
|
+
def worksheets_count
|
49
|
+
@worksheets.keys.select{ |k| k.kind_of? Numeric }.size #TODO: ?? max
|
50
|
+
end
|
51
|
+
def worksheet_names
|
52
|
+
@worksheets.keys.reject{ |k| k.kind_of? Numeric }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'rspreadsheet/row'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module Rspreadsheet
|
5
|
+
|
6
|
+
module Tools
|
7
|
+
## converts cell adress like 'F12' to pair od integers [row,col]
|
8
|
+
def self.convert_cell_address(*coords)
|
9
|
+
if coords.length == 1
|
10
|
+
coords.match(/^([A-Z]{1,3})(\d{1,8})$/)
|
11
|
+
colname = $~[1]
|
12
|
+
rowname = $~[2]
|
13
|
+
elsif coords.length == 2
|
14
|
+
colname = coords[0]
|
15
|
+
rowname = coords[1]
|
16
|
+
else
|
17
|
+
raise 'Wrong number of arguments'
|
18
|
+
end
|
19
|
+
|
20
|
+
colname=colname.rjust(3,'@')
|
21
|
+
col = (colname[-1].ord-65)+(colname[-2].ord-64)*26+(colname[-3].ord-64)*26*26
|
22
|
+
row = rowname.to_i-1
|
23
|
+
return [row,col]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Worksheet
|
28
|
+
attr_accessor :name
|
29
|
+
extend Forwardable
|
30
|
+
def_delegators :@worksheetcells, :nonemptycells
|
31
|
+
|
32
|
+
def initialize(source_node=nil)
|
33
|
+
@source_node = source_node
|
34
|
+
@worksheetcells=WorksheetCells.new
|
35
|
+
rowi = 0
|
36
|
+
unless @source_node.nil?
|
37
|
+
@source_node.elements.select{ |node| node.name == 'table-row'}.each do |row_source_node|
|
38
|
+
coli = 0
|
39
|
+
row_source_node.elements.select{ |node| node.name == 'table-cell'}.each do |cell_source_node|
|
40
|
+
cells.initialize_cell(rowi,coli,cell_source_node)
|
41
|
+
coli += 1
|
42
|
+
end
|
43
|
+
rowi += 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
def cells
|
48
|
+
@worksheetcells
|
49
|
+
end
|
50
|
+
def [](r,c)
|
51
|
+
cells[r,c].value
|
52
|
+
end
|
53
|
+
def []=(r,c,avalue)
|
54
|
+
cells[r,c].value=avalue
|
55
|
+
end
|
56
|
+
def rows
|
57
|
+
WorksheetRows.new(self)
|
58
|
+
end
|
59
|
+
def method_missing method_name, *args, &block
|
60
|
+
if method_name.to_s.match(/^([A-Z]{1,3})(\d{1,8})(=?)$/)
|
61
|
+
row,col = Tools.convert_cell_address($~[1],$~[2])
|
62
|
+
assignchar = $~[3]
|
63
|
+
if assignchar == '='
|
64
|
+
self.cells[row,col].value = args.first
|
65
|
+
else
|
66
|
+
self.cells[row,col].value
|
67
|
+
end
|
68
|
+
else
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# this allows the sheet.cells[r,c] syntax
|
75
|
+
# this object is result of sheet.cells
|
76
|
+
class WorksheetCells
|
77
|
+
def initialize
|
78
|
+
@cells = Hash.new do |hash, coords|
|
79
|
+
# we create empty cell and place it to hash, we do not have to check whether there is a cell in XML already, because it would be in hash as well
|
80
|
+
hash[coords]=Cell.new(coords[0],coords[1])
|
81
|
+
# TODO: create XML empty node here or upon save?
|
82
|
+
end
|
83
|
+
end
|
84
|
+
def [](r,c)
|
85
|
+
cells_object(r,c)
|
86
|
+
end
|
87
|
+
def nonemptycells
|
88
|
+
@cells.values
|
89
|
+
end
|
90
|
+
|
91
|
+
### internal
|
92
|
+
def cells_object(r,c)
|
93
|
+
@cells[[r,c]]
|
94
|
+
end
|
95
|
+
def initialize_cell(r,c,source_node)
|
96
|
+
@cells[[r,c]]=Cell.new(r,c,source_node)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# this allows the sheet.rows[r] syntax
|
101
|
+
# this object is result of sheet.rows
|
102
|
+
class WorksheetRows
|
103
|
+
def initialize(aworkbook)
|
104
|
+
@workbook = aworkbook
|
105
|
+
@spredsheetrows=Array.new()
|
106
|
+
end
|
107
|
+
def [] rowi
|
108
|
+
@spredsheetrows[rowi] ||= Row.new(@workbook,rowi)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
data/lib/rspreadsheet.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
require "rspreadsheet/version"
|
2
|
+
require 'rspreadsheet/workbook'
|
3
|
+
require 'rspreadsheet/worksheet'
|
4
|
+
require 'class_extensions'
|
2
5
|
|
3
6
|
module Rspreadsheet
|
4
|
-
|
7
|
+
|
8
|
+
def self.new(filename=nil)
|
9
|
+
Workbook.new(filename)
|
10
|
+
end
|
11
|
+
def self.open(filename)
|
12
|
+
Workbook.new(filename)
|
13
|
+
end
|
5
14
|
end
|
data/rspreadsheet.gemspec
CHANGED
@@ -9,15 +9,31 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Jakub A.Těšínský"]
|
10
10
|
spec.email = ["jAkub.cz (A is at)"]
|
11
11
|
spec.summary = %q{Manipulating spreadsheets with Ruby (read / create / modify OpenDocument Spreadsheet).}
|
12
|
-
|
12
|
+
spec.description = %q{Manipulating spreadsheets with Ruby (read / create / modify OpenDocument Spreadsheet).}
|
13
13
|
spec.homepage = "https://github.com/gorn/rspreadsheet"
|
14
|
-
|
14
|
+
spec.license = "GPL"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
# runtime dependencies
|
22
|
+
spec.add_runtime_dependency 'libxml-ruby', '~>2.7' # parsing XML files
|
23
|
+
spec.add_runtime_dependency 'rubyzip', '~>1.1' # opening zip files
|
24
|
+
spec.add_runtime_dependency 'andand', '~>1.3'
|
25
|
+
|
26
|
+
|
27
|
+
# development dependencies
|
21
28
|
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
-
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "rake", '~>0.9'
|
30
|
+
# testig - see http://bit.ly/1n5yM51
|
31
|
+
spec.add_development_dependency "rspec", '~>2'
|
32
|
+
|
33
|
+
# optional and testing
|
34
|
+
spec.add_development_dependency "coveralls", '~>0.7'
|
35
|
+
spec.add_development_dependency "test_notifier", '~>2.0' # test notifier for kde and other platforms
|
36
|
+
spec.add_development_dependency "guard", '~>2.6'
|
37
|
+
spec.add_development_dependency "guard-rspec", '~>2.6'
|
38
|
+
|
23
39
|
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
$test_filename = './spec/testfile1.ods'
|
4
|
+
|
5
|
+
describe Rspreadsheet do
|
6
|
+
it 'can open ods testfile and reads its content correctly' do
|
7
|
+
book = Rspreadsheet.new($test_filename)
|
8
|
+
book.worksheets[0].should_not == nil
|
9
|
+
book.worksheets[0].class.should == Rspreadsheet::Worksheet
|
10
|
+
s = book.worksheets[0]
|
11
|
+
(1..10).each do |i|
|
12
|
+
s[i-1,0].should === i
|
13
|
+
end
|
14
|
+
s[0,1].should === 'text'
|
15
|
+
s[1,1].should === Date.new(2014,1,1)
|
16
|
+
end
|
17
|
+
it 'can open and save file, and saved file has same cells as original' do
|
18
|
+
tmp_filename = '/tmp/testfile1.ods' # first delete temp file
|
19
|
+
File.delete(tmp_filename) if File.exists?(tmp_filename)
|
20
|
+
book = Rspreadsheet.new($test_filename) # than open test file
|
21
|
+
book.save(tmp_filename) # and save it as temp file
|
22
|
+
|
23
|
+
book1 = Rspreadsheet.new($test_filename) # now open both again
|
24
|
+
book2 = Rspreadsheet.new(tmp_filename)
|
25
|
+
@sheet1 = book1.worksheets[0]
|
26
|
+
@sheet2 = book2.worksheets[0]
|
27
|
+
|
28
|
+
@sheet1.nonemptycells.each do |cell| # and test identity
|
29
|
+
@sheet2[cell.row,cell.col].should == cell.value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
it 'can open and save file, and saved file is exactly same as original' do
|
33
|
+
tmp_filename = '/tmp/testfile1.ods' # first delete temp file
|
34
|
+
File.delete(tmp_filename) if File.exists?(tmp_filename)
|
35
|
+
book = Rspreadsheet.new($test_filename) # than open test file
|
36
|
+
book.save(tmp_filename) # and save it as temp file
|
37
|
+
|
38
|
+
# now compare them
|
39
|
+
@content_xml1 = Zip::File.open($test_filename) do |zip|
|
40
|
+
LibXML::XML::Document.io zip.get_input_stream('content.xml')
|
41
|
+
end
|
42
|
+
@content_xml2 = Zip::File.open(tmp_filename) do |zip|
|
43
|
+
LibXML::XML::Document.io zip.get_input_stream('content.xml')
|
44
|
+
end
|
45
|
+
@content_xml1.root.equals?(@content_xml2.root).should == true
|
46
|
+
end
|
47
|
+
it 'when open and save file modified, than the file is different' do
|
48
|
+
tmp_filename = '/tmp/testfile1.ods' # first delete temp file
|
49
|
+
File.delete(tmp_filename) if File.exists?(tmp_filename)
|
50
|
+
book = Rspreadsheet.new($test_filename) # than open test file
|
51
|
+
book.worksheets[0][0,0].should_not == 'xyzxyz'
|
52
|
+
book.worksheets[0][0,0]='xyzxyz'
|
53
|
+
book.worksheets[0][0,0].should == 'xyzxyz'
|
54
|
+
book.save(tmp_filename) # and save it as temp file
|
55
|
+
|
56
|
+
# now compare them
|
57
|
+
@content_doc1 = Zip::File.open($test_filename) do |zip|
|
58
|
+
LibXML::XML::Document.io zip.get_input_stream('content.xml')
|
59
|
+
end
|
60
|
+
@content_doc2 = Zip::File.open(tmp_filename) do |zip|
|
61
|
+
LibXML::XML::Document.io zip.get_input_stream('content.xml')
|
62
|
+
end
|
63
|
+
@content_doc1.eql?(@content_doc2).should == false
|
64
|
+
end
|
65
|
+
it 'can create file' do
|
66
|
+
book = Rspreadsheet.new
|
67
|
+
end
|
68
|
+
it 'can create new worksheet' do
|
69
|
+
book = Rspreadsheet.new
|
70
|
+
book.create_worksheet
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe Rspreadsheet::Cell do
|
75
|
+
before do
|
76
|
+
book1 = Rspreadsheet.new
|
77
|
+
@sheet1 = book1.create_worksheet
|
78
|
+
@sheet1[0,0] = 'text'
|
79
|
+
book2 = Rspreadsheet.new($test_filename)
|
80
|
+
@sheet2 = book2.worksheets[0]
|
81
|
+
end
|
82
|
+
it 'contains good row and col coordinates' do
|
83
|
+
@cell = @sheet1.cells[1,3]
|
84
|
+
@cell.row.should == 1
|
85
|
+
@cell.col.should == 3
|
86
|
+
@cell.coordinates.should == [1,3]
|
87
|
+
|
88
|
+
@cell = @sheet2.cells[0,1]
|
89
|
+
@cell.row.should == 0
|
90
|
+
@cell.col.should == 1
|
91
|
+
@cell.coordinates.should == [0,1]
|
92
|
+
end
|
93
|
+
it 'can be referenced by more vars and both are synchromized' do
|
94
|
+
@cell = @sheet1.cells[0,0]
|
95
|
+
@sheet1[0,0] = 'novinka'
|
96
|
+
@cell.value.should == 'novinka'
|
97
|
+
end
|
98
|
+
it 'can be modyfied by more ways and all are identical' do
|
99
|
+
@cell = @sheet1.cells[2,2]
|
100
|
+
@sheet1[2,2] = 'zaprve'
|
101
|
+
@cell.value.should == 'zaprve'
|
102
|
+
@sheet1.cells[2,2].value = 'zadruhe'
|
103
|
+
@cell.value.should == 'zadruhe'
|
104
|
+
@sheet1.C3 = 'zatreti'
|
105
|
+
@cell.value.should == 'zatreti'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
describe Rspreadsheet::Worksheet do
|
111
|
+
before do
|
112
|
+
book = Rspreadsheet.new
|
113
|
+
@sheet = book.create_worksheet
|
114
|
+
end
|
115
|
+
it 'remembers the value stored to A1 cell' do
|
116
|
+
@sheet[0,0].should == nil
|
117
|
+
@sheet[0,0] = 'test text'
|
118
|
+
@sheet[0,0].class.should == String
|
119
|
+
@sheet[0,0].should == 'test text'
|
120
|
+
end
|
121
|
+
it 'value stored to A1 is accesible using different syntax' do
|
122
|
+
@sheet[0,0] = 'test text'
|
123
|
+
@sheet[0,0].should == 'test text'
|
124
|
+
@sheet.cells[0,0].value.should == 'test text'
|
125
|
+
end
|
126
|
+
it 'makes Cell object accessible' do
|
127
|
+
@sheet.cells[0,0].value = 'test text'
|
128
|
+
@sheet.cells[0,0].class.should == Rspreadsheet::Cell
|
129
|
+
end
|
130
|
+
it 'has name, which can be changed and is remembered' do
|
131
|
+
@sheet.name.should be(nil)
|
132
|
+
@sheet.name = 'Icecream'
|
133
|
+
@sheet.name.should == 'Icecream'
|
134
|
+
@sheet.name = 'Cofee'
|
135
|
+
@sheet.name.should == 'Cofee'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe Rspreadsheet::Row do
|
140
|
+
before do
|
141
|
+
book1 = Rspreadsheet.new
|
142
|
+
@sheet1 = book1.create_worksheet
|
143
|
+
end
|
144
|
+
it 'allows access to cells in a row' do
|
145
|
+
(2..5).each { |i| @sheet1[7,i] = i }
|
146
|
+
(2..5).each { |i|
|
147
|
+
a = @sheet1.rows
|
148
|
+
b = a[7]
|
149
|
+
c = b.cells
|
150
|
+
d = c[i]
|
151
|
+
d.value.should == i
|
152
|
+
}
|
153
|
+
end
|
154
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/testfile1.ods
ADDED
Binary file
|
metadata
CHANGED
@@ -1,61 +1,190 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspreadsheet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
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
|
+
date: 2014-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: libxml-ruby
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubyzip
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: andand
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
13
55
|
- !ruby/object:Gem::Dependency
|
14
56
|
name: bundler
|
15
57
|
requirement: !ruby/object:Gem::Requirement
|
16
58
|
requirements:
|
17
|
-
- - ~>
|
59
|
+
- - "~>"
|
18
60
|
- !ruby/object:Gem::Version
|
19
61
|
version: '1.5'
|
20
62
|
type: :development
|
21
63
|
prerelease: false
|
22
64
|
version_requirements: !ruby/object:Gem::Requirement
|
23
65
|
requirements:
|
24
|
-
- - ~>
|
66
|
+
- - "~>"
|
25
67
|
- !ruby/object:Gem::Version
|
26
68
|
version: '1.5'
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: rake
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
30
72
|
requirements:
|
31
|
-
- -
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.9'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.9'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: coveralls
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.7'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.7'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: test_notifier
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
32
116
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
117
|
+
version: '2.0'
|
34
118
|
type: :development
|
35
119
|
prerelease: false
|
36
120
|
version_requirements: !ruby/object:Gem::Requirement
|
37
121
|
requirements:
|
38
|
-
- -
|
122
|
+
- - "~>"
|
39
123
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
|
124
|
+
version: '2.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: guard
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.6'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.6'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: guard-rspec
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '2.6'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '2.6'
|
153
|
+
description: Manipulating spreadsheets with Ruby (read / create / modify OpenDocument
|
154
|
+
Spreadsheet).
|
42
155
|
email:
|
43
156
|
- jAkub.cz (A is at)
|
44
157
|
executables: []
|
45
158
|
extensions: []
|
46
159
|
extra_rdoc_files: []
|
47
160
|
files:
|
48
|
-
- .
|
161
|
+
- ".coveralls.yml"
|
162
|
+
- ".gitignore"
|
163
|
+
- ".travis.yml"
|
164
|
+
- COPYING.txt
|
165
|
+
- DEVEL_BLOG.md
|
49
166
|
- GUIDE.md
|
50
167
|
- Gemfile
|
51
|
-
-
|
168
|
+
- Gemfile.lock
|
169
|
+
- Guardfile
|
170
|
+
- LICENSE.md
|
52
171
|
- README.md
|
53
172
|
- Rakefile
|
173
|
+
- lib/class_extensions.rb
|
54
174
|
- lib/rspreadsheet.rb
|
175
|
+
- lib/rspreadsheet/cell.rb
|
176
|
+
- lib/rspreadsheet/empty_file_template.ods
|
177
|
+
- lib/rspreadsheet/row.rb
|
55
178
|
- lib/rspreadsheet/version.rb
|
179
|
+
- lib/rspreadsheet/workbook.rb
|
180
|
+
- lib/rspreadsheet/worksheet.rb
|
56
181
|
- rspreadsheet.gemspec
|
182
|
+
- spec/rspreadsheet_spec.rb
|
183
|
+
- spec/spec_helper.rb
|
184
|
+
- spec/testfile1.ods
|
57
185
|
homepage: https://github.com/gorn/rspreadsheet
|
58
|
-
licenses:
|
186
|
+
licenses:
|
187
|
+
- GPL
|
59
188
|
metadata: {}
|
60
189
|
post_install_message:
|
61
190
|
rdoc_options: []
|
@@ -63,19 +192,22 @@ require_paths:
|
|
63
192
|
- lib
|
64
193
|
required_ruby_version: !ruby/object:Gem::Requirement
|
65
194
|
requirements:
|
66
|
-
- -
|
195
|
+
- - ">="
|
67
196
|
- !ruby/object:Gem::Version
|
68
197
|
version: '0'
|
69
198
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
199
|
requirements:
|
71
|
-
- -
|
200
|
+
- - ">="
|
72
201
|
- !ruby/object:Gem::Version
|
73
202
|
version: '0'
|
74
203
|
requirements: []
|
75
204
|
rubyforge_project:
|
76
|
-
rubygems_version: 2.
|
205
|
+
rubygems_version: 2.2.2
|
77
206
|
signing_key:
|
78
207
|
specification_version: 4
|
79
208
|
summary: Manipulating spreadsheets with Ruby (read / create / modify OpenDocument
|
80
209
|
Spreadsheet).
|
81
|
-
test_files:
|
210
|
+
test_files:
|
211
|
+
- spec/rspreadsheet_spec.rb
|
212
|
+
- spec/spec_helper.rb
|
213
|
+
- spec/testfile1.ods
|