yalab-ruby-ods 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +49 -0
- data/Rakefile +12 -0
- data/VERSION +1 -0
- data/lib/nokogiri_ext.rb +26 -0
- data/lib/ods.rb +208 -0
- data/test/cook.ods +0 -0
- data/test/ods_test.rb +132 -0
- data/yalab-ruby-ods.gemspec +53 -0
- metadata +81 -0
data/README.txt
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
= README
|
2
|
+
|
3
|
+
release:: 0.0.0
|
4
|
+
copyright:: copyright(c) 2006-2009 ya-lab.org all rights reserved.
|
5
|
+
|
6
|
+
|
7
|
+
== About yalab-ruby-ods
|
8
|
+
|
9
|
+
This library is read and write OpenOffice Document SpreadSheet(ods) file.
|
10
|
+
This version only use string of cell format.
|
11
|
+
|
12
|
+
|
13
|
+
== Installation
|
14
|
+
|
15
|
+
$ sudo gem install yalab-ruby-ods -s http://gemcutter.org
|
16
|
+
|
17
|
+
== Usage
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'ods'
|
21
|
+
|
22
|
+
ods = Ods.new('some_document.ods')
|
23
|
+
|
24
|
+
sheet = ods.sheets[0]
|
25
|
+
sheet[3, :A].text #=> get A3 cell value
|
26
|
+
sheet[4, :B].text = 'foobar'
|
27
|
+
sheet[4, :B].text #=> foobar
|
28
|
+
|
29
|
+
values = []
|
30
|
+
sheet.rows.each do |row|
|
31
|
+
row.each{|cell|
|
32
|
+
values.push cell.text
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
new_sheet = ods.create_sheet
|
37
|
+
new_sheet[1, :A].annotation = 'hint'
|
38
|
+
new_sheet[1, :A].text = 'baz'
|
39
|
+
|
40
|
+
ods.save
|
41
|
+
|
42
|
+
== License
|
43
|
+
|
44
|
+
MIT License
|
45
|
+
|
46
|
+
|
47
|
+
== Author
|
48
|
+
|
49
|
+
yalab <rudeboyjet@gmail.com>
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'jeweler'
|
2
|
+
Jeweler::Tasks.new do |gemspec|
|
3
|
+
gemspec.name = "yalab-ruby-ods"
|
4
|
+
gemspec.summary = "This is using OpenOffice SpreadSheet document file via ruby"
|
5
|
+
gemspec.email = "rudeboyjet@gmail.com"
|
6
|
+
gemspec.homepage = "http://github.com/yalab/ruby-ods"
|
7
|
+
gemspec.description = ""
|
8
|
+
gemspec.authors = ["yalab"]
|
9
|
+
gemspec.add_dependency "nokogiri", ">= 1.4.0"
|
10
|
+
gemspec.add_dependency "rubyzip", ">= 0.9.1"
|
11
|
+
end
|
12
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/lib/nokogiri_ext.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
Nokogiri::XML::Element.module_eval do
|
3
|
+
def add_element(name, attributes={})
|
4
|
+
(prefix, name) = name.split(':') if name.include?(':')
|
5
|
+
node = Nokogiri::XML::Node.new(name, self)
|
6
|
+
attributes.each do |attr, val|
|
7
|
+
node.set_attribute(attr, val)
|
8
|
+
end
|
9
|
+
ns = node.add_namespace_definition(prefix, Ods::NAMESPACES[prefix])
|
10
|
+
node.namespace = ns
|
11
|
+
self.add_child(node)
|
12
|
+
node
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch(xpath)
|
16
|
+
if node = self.xpath(xpath).first
|
17
|
+
return node
|
18
|
+
end
|
19
|
+
|
20
|
+
return self.add_element(xpath) unless xpath.include?('/')
|
21
|
+
|
22
|
+
xpath = xpath.split('/')
|
23
|
+
last_path = xpath.pop
|
24
|
+
fetch(xpath.join('/')).fetch(last_path)
|
25
|
+
end
|
26
|
+
end
|
data/lib/ods.rb
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'forwardable'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'nokogiri_ext'
|
6
|
+
require 'zip/zip'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
class Ods
|
10
|
+
attr_reader :content, :sheets
|
11
|
+
XPATH_SHEETS = '//office:body/office:spreadsheet/table:table'
|
12
|
+
|
13
|
+
NAMESPACES = {
|
14
|
+
'office' => 'urn:oasis:names:tc:opendocument:xmlns:office:1.0',
|
15
|
+
'style' => 'urn:oasis:names:tc:opendocument:xmlns:style:1.0',
|
16
|
+
'text' => 'urn:oasis:names:tc:opendocument:xmlns:text:1.0',
|
17
|
+
'table' => 'urn:oasis:names:tc:opendocument:xmlns:table:1.0',
|
18
|
+
'draw' => 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0',
|
19
|
+
'fo' => 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0',
|
20
|
+
'xlink' => 'http://www.w3.org/1999/xlink',
|
21
|
+
'dc' => 'http://purl.org/dc/elements/1.1/',
|
22
|
+
'meta' => 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0',
|
23
|
+
'number' => 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0',
|
24
|
+
'presentation' => 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0',
|
25
|
+
'svg' => 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0',
|
26
|
+
'chart' => 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0',
|
27
|
+
'dr3d' => 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0',
|
28
|
+
'math' => 'http://www.w3.org/1998/Math/MathML',
|
29
|
+
'form' => 'urn:oasis:names:tc:opendocument:xmlns:form:1.0',
|
30
|
+
'script' => 'urn:oasis:names:tc:opendocument:xmlns:script:1.0',
|
31
|
+
'ooo' => 'http://openoffice.org/2004/office',
|
32
|
+
'ooow' => 'http://openoffice.org/2004/writer',
|
33
|
+
'oooc' => 'http://openoffice.org/2004/calc',
|
34
|
+
'dom' => 'http://www.w3.org/2001/xml-events',
|
35
|
+
'xforms' => 'http://www.w3.org/2002/xforms',
|
36
|
+
'xsd' => 'http://www.w3.org/2001/XMLSchema',
|
37
|
+
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
38
|
+
'rpt' => 'http://openoffice.org/2005/report',
|
39
|
+
'of' => 'urn:oasis:names:tc:opendocument:xmlns:of:1.2',
|
40
|
+
'rdfa' => 'http://docs.oasis-open.org/opendocument/meta/rdfa#',
|
41
|
+
'field' => 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0',
|
42
|
+
'formx' => 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0'
|
43
|
+
}
|
44
|
+
|
45
|
+
def initialize(path)
|
46
|
+
@path = path
|
47
|
+
Zip::ZipFile.open(@path) do |zip|
|
48
|
+
@content = Nokogiri::XML::Document.parse(zip.read('content.xml'))
|
49
|
+
end
|
50
|
+
@sheets = []
|
51
|
+
@content.root.xpath(XPATH_SHEETS).each do |sheet|
|
52
|
+
@sheets.push(Sheet.new(sheet))
|
53
|
+
end
|
54
|
+
@content
|
55
|
+
end
|
56
|
+
|
57
|
+
def save(dest=nil)
|
58
|
+
if dest
|
59
|
+
FileUtils.cp(@path, dest)
|
60
|
+
else
|
61
|
+
dest = @path
|
62
|
+
end
|
63
|
+
|
64
|
+
@sheets.each do |sheet|
|
65
|
+
column = sheet.column
|
66
|
+
max_length = 0
|
67
|
+
column.content.parent.xpath('table:table-row').each do |row|
|
68
|
+
length = row.xpath('table:table-cell').length
|
69
|
+
max_length = length if max_length < length
|
70
|
+
end
|
71
|
+
column.set_attr('repeated', max_length)
|
72
|
+
end
|
73
|
+
|
74
|
+
Zip::ZipFile.open(dest) do |zip|
|
75
|
+
zip.get_output_stream('content.xml') do |io|
|
76
|
+
io << @content.to_s
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def create_sheet
|
82
|
+
parent = @content.root.xpath(XPATH_SHEETS.split('/')[0..-2].join('/'))[0]
|
83
|
+
table = parent.add_element('table:table',
|
84
|
+
'name' => "Sheet#{@sheets.length + 1}",
|
85
|
+
'style-name' => 'ta1',
|
86
|
+
'print' => 'false')
|
87
|
+
table.add_element('table:table-column',
|
88
|
+
'style-name' => 'co1',
|
89
|
+
'default-cell-style-name' => 'Default')
|
90
|
+
new_sheet = Sheet.new(table)
|
91
|
+
@sheets.push(new_sheet)
|
92
|
+
new_sheet
|
93
|
+
end
|
94
|
+
|
95
|
+
class Sheet
|
96
|
+
attr_reader :content
|
97
|
+
def initialize(content)
|
98
|
+
@content = content
|
99
|
+
end
|
100
|
+
|
101
|
+
def name
|
102
|
+
@content.attribute('name').to_s
|
103
|
+
end
|
104
|
+
|
105
|
+
def name=(name)
|
106
|
+
@content.set_attribute('table:name', name)
|
107
|
+
end
|
108
|
+
|
109
|
+
def [](row, col)
|
110
|
+
(row - rows.length).times do
|
111
|
+
rows.push(Row.new(@content.add_element('table:table-row',
|
112
|
+
'table:style-name' => 'ro1'), rows.length+1))
|
113
|
+
end
|
114
|
+
row = rows[row-1]
|
115
|
+
col = ('A'..col.to_s).to_a.index(col.to_s)
|
116
|
+
cols = row.cols
|
117
|
+
(col - cols.length + 1).times do
|
118
|
+
no = (cols.last) ? cols.last.no.to_s.succ : 'A'
|
119
|
+
cols.push(Cell.new(row.add_element('table:table-cell', 'office:value-type' => 'string'), no))
|
120
|
+
end
|
121
|
+
cols[col]
|
122
|
+
end
|
123
|
+
|
124
|
+
def rows
|
125
|
+
return @rows if @rows
|
126
|
+
@rows = []
|
127
|
+
@content.xpath('./table:table-row').each_with_index{|row, index|
|
128
|
+
@rows << Row.new(row, index+1)
|
129
|
+
}
|
130
|
+
@rows
|
131
|
+
end
|
132
|
+
|
133
|
+
def column
|
134
|
+
Column.new(@content.xpath('table:table-column').first)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class Row
|
139
|
+
extend Forwardable
|
140
|
+
|
141
|
+
def_delegator :@content, :xpath, :xpath
|
142
|
+
def_delegator :@content, :add_element, :add_element
|
143
|
+
attr_reader :no
|
144
|
+
|
145
|
+
def initialize(content, no)
|
146
|
+
@content = content
|
147
|
+
@no = no
|
148
|
+
end
|
149
|
+
|
150
|
+
def cols
|
151
|
+
return @cols if @cols
|
152
|
+
@cols = []
|
153
|
+
no = 'A'
|
154
|
+
xpath('table:table-cell').each{|cell|
|
155
|
+
@cols << Cell.new(cell, no)
|
156
|
+
no.succ!
|
157
|
+
}
|
158
|
+
@cols
|
159
|
+
end
|
160
|
+
|
161
|
+
def create_cell
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Cell
|
167
|
+
extend Forwardable
|
168
|
+
|
169
|
+
def_delegator :@content, :fetch, :fetch
|
170
|
+
attr_reader :no
|
171
|
+
|
172
|
+
def initialize(content, no)
|
173
|
+
@content = content
|
174
|
+
@no = no.to_sym
|
175
|
+
end
|
176
|
+
|
177
|
+
def value
|
178
|
+
fetch('text:p').content
|
179
|
+
end
|
180
|
+
|
181
|
+
def value=(value)
|
182
|
+
fetch('text:p').content = value
|
183
|
+
end
|
184
|
+
|
185
|
+
def annotation
|
186
|
+
fetch('office:annotation/text:p').content
|
187
|
+
end
|
188
|
+
|
189
|
+
def annotation=(value)
|
190
|
+
fetch('office:annotation/text:p').content = value
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
class Column
|
195
|
+
attr_reader :content
|
196
|
+
def initialize(content)
|
197
|
+
@content = content
|
198
|
+
end
|
199
|
+
|
200
|
+
def attr(name)
|
201
|
+
@content['number-columns-' + name]
|
202
|
+
end
|
203
|
+
|
204
|
+
def set_attr(name, value)
|
205
|
+
@content['table:number-columns-' + name] = value.to_s
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
data/test/cook.ods
ADDED
Binary file
|
data/test/ods_test.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'test/unit'
|
3
|
+
require File.dirname(File.expand_path(__FILE__)) + '/../lib/ods'
|
4
|
+
|
5
|
+
class OdsTest < Test::Unit::TestCase
|
6
|
+
BASE_DIR = File.dirname(File.expand_path(__FILE__))
|
7
|
+
def setup
|
8
|
+
@ods = Ods.new(BASE_DIR + '/cook.ods')
|
9
|
+
@file_path = BASE_DIR + '/modified.ods'
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
File.unlink(@file_path) if File.exists?(@file_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_sheet_count
|
17
|
+
assert_equal 3, @ods.sheets.length
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_sheet_name
|
21
|
+
assert_equal 'さつま揚げとキャベツのお味噌汁', @ods.sheets[0].name
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_sheet_name_modify
|
25
|
+
modified_name = 'hogehoge'
|
26
|
+
offset = 2
|
27
|
+
|
28
|
+
assert_not_equal modified_name, @ods.sheets[offset].name
|
29
|
+
@ods.sheets[offset].name = modified_name
|
30
|
+
@ods.save(@file_path)
|
31
|
+
modified_ods = Ods.new(@file_path)
|
32
|
+
assert_equal modified_name, modified_ods.sheets[offset].name
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_get_column
|
36
|
+
sheet = @ods.sheets[0]
|
37
|
+
assert_equal 'だし汁', sheet[2, :A].value
|
38
|
+
assert_equal '適量', sheet[6, :B].value
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_modify_column
|
42
|
+
sheet_offset = 0
|
43
|
+
row = 2
|
44
|
+
col = :B
|
45
|
+
sheet = @ods.sheets[sheet_offset]
|
46
|
+
modified_text = '酢味噌'
|
47
|
+
assert_not_equal modified_text, sheet[row, col].value
|
48
|
+
sheet[row, col].value = modified_text
|
49
|
+
@ods.save(@file_path)
|
50
|
+
modified_ods = Ods.new(@file_path)
|
51
|
+
assert_equal modified_text, modified_ods.sheets[sheet_offset][row, col].value
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_access_not_existed_sheet
|
55
|
+
ods_length = @ods.sheets.length
|
56
|
+
new_sheet = @ods.create_sheet
|
57
|
+
assert_equal "Sheet#{ods_length+1}", new_sheet.name
|
58
|
+
assert_equal '', new_sheet[1, :A].value
|
59
|
+
(col, row) = [100, :CC]
|
60
|
+
assert_nothing_raised { new_sheet[col, row].value = 'hoge' }
|
61
|
+
assert_equal 'hoge', new_sheet[col, row].value
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_read_annotation
|
65
|
+
cell = @ods.sheets[0][2, :A]
|
66
|
+
assert_equal '昆布だし', cell.annotation
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_write_annotation
|
70
|
+
sheet_offset = 0
|
71
|
+
row = 3
|
72
|
+
col = :A
|
73
|
+
cell = @ods.sheets[sheet_offset][row, col]
|
74
|
+
assert_equal '', cell.annotation
|
75
|
+
text = 'foobar'
|
76
|
+
cell.annotation = text
|
77
|
+
assert_equal text, @ods.sheets[sheet_offset][row, col].annotation
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_columns_repeated
|
81
|
+
sheet = @ods.create_sheet
|
82
|
+
row = 10
|
83
|
+
col = :C
|
84
|
+
sheet[row, col].value = 'hoge'
|
85
|
+
@ods.save(@file_path)
|
86
|
+
|
87
|
+
modified_ods = Ods.new(@file_path)
|
88
|
+
sheet = modified_ods.sheets[modified_ods.sheets.length-1]
|
89
|
+
assert_equal "3", sheet.column.attr('repeated')
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_each_rows_and_cols
|
93
|
+
sheet = @ods.create_sheet
|
94
|
+
row_offset = 10
|
95
|
+
col_offset = :C
|
96
|
+
sheet[row_offset, col_offset].value = 'foo'
|
97
|
+
count = 0
|
98
|
+
sheet.rows.each do |row|
|
99
|
+
count += 1
|
100
|
+
end
|
101
|
+
assert_instance_of Ods::Row, sheet.rows[0]
|
102
|
+
assert_equal row_offset, count
|
103
|
+
|
104
|
+
count = 0
|
105
|
+
sheet.rows[row_offset-1].cols.each do |col|
|
106
|
+
count += 1
|
107
|
+
end
|
108
|
+
assert_instance_of Ods::Cell, sheet.rows[row_offset-1].cols[0]
|
109
|
+
assert_equal ('A'..col_offset.to_s).to_a.length, count
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_row_no
|
113
|
+
sheet = @ods.sheets[0]
|
114
|
+
count = 0
|
115
|
+
sheet.rows.each_with_index do |row, index|
|
116
|
+
assert_equal index + 1, row.no
|
117
|
+
count += 1
|
118
|
+
end
|
119
|
+
|
120
|
+
sheet[count+1, :A].value = 'hoge'
|
121
|
+
assert_equal count+1, sheet.rows.last.no
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_cell_no
|
125
|
+
sheet = @ods.create_sheet
|
126
|
+
sheet[1, :A].value = 'hoge'
|
127
|
+
sheet[2, :B].value = 'foo'
|
128
|
+
assert_equal :A, sheet.rows.first.cols.first.no
|
129
|
+
assert_equal :A, sheet.rows.first.cols.last.no
|
130
|
+
assert_equal :B, sheet.rows.last.cols.last.no
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{yalab-ruby-ods}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["yalab"]
|
12
|
+
s.date = %q{2009-11-27}
|
13
|
+
s.description = %q{}
|
14
|
+
s.email = %q{rudeboyjet@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.txt"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"README.txt",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"lib/nokogiri_ext.rb",
|
23
|
+
"lib/ods.rb",
|
24
|
+
"test/cook.ods",
|
25
|
+
"test/ods_test.rb",
|
26
|
+
"yalab-ruby-ods.gemspec"
|
27
|
+
]
|
28
|
+
s.homepage = %q{http://github.com/yalab/ruby-ods}
|
29
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
30
|
+
s.require_paths = ["lib"]
|
31
|
+
s.rubygems_version = %q{1.3.5}
|
32
|
+
s.summary = %q{This is using OpenOffice SpreadSheet document file via ruby}
|
33
|
+
s.test_files = [
|
34
|
+
"test/ods_test.rb"
|
35
|
+
]
|
36
|
+
|
37
|
+
if s.respond_to? :specification_version then
|
38
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
39
|
+
s.specification_version = 3
|
40
|
+
|
41
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
42
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.0"])
|
43
|
+
s.add_runtime_dependency(%q<rubyzip>, [">= 0.9.1"])
|
44
|
+
else
|
45
|
+
s.add_dependency(%q<nokogiri>, [">= 1.4.0"])
|
46
|
+
s.add_dependency(%q<rubyzip>, [">= 0.9.1"])
|
47
|
+
end
|
48
|
+
else
|
49
|
+
s.add_dependency(%q<nokogiri>, [">= 1.4.0"])
|
50
|
+
s.add_dependency(%q<rubyzip>, [">= 0.9.1"])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yalab-ruby-ods
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- yalab
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-27 00:00:00 +09:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: nokogiri
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.4.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rubyzip
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.9.1
|
34
|
+
version:
|
35
|
+
description: ""
|
36
|
+
email: rudeboyjet@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.txt
|
43
|
+
files:
|
44
|
+
- README.txt
|
45
|
+
- Rakefile
|
46
|
+
- VERSION
|
47
|
+
- lib/nokogiri_ext.rb
|
48
|
+
- lib/ods.rb
|
49
|
+
- test/cook.ods
|
50
|
+
- test/ods_test.rb
|
51
|
+
- yalab-ruby-ods.gemspec
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: http://github.com/yalab/ruby-ods
|
54
|
+
licenses: []
|
55
|
+
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options:
|
58
|
+
- --charset=UTF-8
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.3.5
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: This is using OpenOffice SpreadSheet document file via ruby
|
80
|
+
test_files:
|
81
|
+
- test/ods_test.rb
|