rspreadsheet 0.0.1 → 0.0.2
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/.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
|