ruby-ods 0.1.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 19cfa5706fdcfab427e629b4801bb1f8e14bb9c6e7379b73c706b3b87483da73
4
+ data.tar.gz: d768b41cbf282fe3f40fca9e23518550b8253deca15fd7486aec36efdfcae0d5
5
+ SHA512:
6
+ metadata.gz: 6104b0c45fa68f977f94783c02559fb7c6a377e933db25b480337b42a10ae97c1caa73e20e79e2e58c1e7aef511c51d3bfc0ce34d0df1be38630495b286ae20e
7
+ data.tar.gz: 742eda97b8a6e5983b780a30ebe50ad5ca5fdadac26a826193558834a95cb5ba438715736ba39598349db62a97c0c04050182d66a98e0d16ad6c60e36dd9569d
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Ruby::Ods
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/ruby-ods.svg)](https://badge.fury.io/rb/ruby-ods)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'ruby-ods'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install ruby-ods
20
+
21
+ ## Usage
22
+
23
+ For initializing the ODS object
24
+
25
+ ```ruby
26
+ require 'ruby/ods'
27
+ ods = Ruby::Ods::Manager.new('sample1.ods')
28
+ ```
29
+
30
+ For getting sheets
31
+ ```ruby
32
+ sheet = ods.sheets[0]
33
+ ```
34
+
35
+ For getting value of columns
36
+
37
+ ```ruby
38
+ sheet[3, :A].value
39
+ ```
40
+
41
+ For saving a value in the row column
42
+
43
+ ```ruby
44
+ sheet[3, :A].value = "2092"
45
+ ods.save
46
+ ```
47
+
48
+ ## Development
49
+
50
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
51
+
52
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
53
+
54
+ ## Contributing
55
+
56
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ratnamyadav/ruby-ods. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
57
+
58
+ ## License
59
+
60
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
61
+
62
+ ## Code of Conduct
63
+
64
+ Everyone interacting in the Ruby::Ods project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/ruby-ods/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,28 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ Nokogiri::XML::Element.module_eval do
5
+ def add_element(name, attributes={})
6
+ (prefix, name) = name.split(':') if name.include?(':')
7
+ node = Nokogiri::XML::Node.new(name, self)
8
+ attributes.each do |attr, val|
9
+ node.set_attribute(attr, val)
10
+ end
11
+ ns = node.add_namespace_definition(prefix, Ruby::Ods::Manager::NAMESPACES[prefix])
12
+ node.namespace = ns
13
+ self.add_child(node)
14
+ node
15
+ end
16
+
17
+ def fetch(xpath)
18
+ if node = self.xpath(xpath).first
19
+ return node
20
+ end
21
+
22
+ return self.add_element(xpath) unless xpath.include?('/')
23
+
24
+ xpath = xpath.split('/')
25
+ last_path = xpath.pop
26
+ fetch(xpath.join('/')).fetch(last_path)
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module Ruby
2
+ module Ods
3
+ VERSION = "0.1.3"
4
+ end
5
+ end
data/lib/ruby/ods.rb ADDED
@@ -0,0 +1,214 @@
1
+ require "ruby/ods/version"
2
+ require "forwardable"
3
+ require "rubygems"
4
+ require "nokogiri"
5
+ require "ruby/nokogiri_ext"
6
+ require "zip"
7
+ require "fileutils"
8
+
9
+ module Ruby
10
+ module Ods
11
+ class Error < StandardError; end
12
+
13
+ class Manager
14
+ attr_reader :content, :sheets
15
+ XPATH_SHEETS = '//office:body/office:spreadsheet/table:table'
16
+
17
+ NAMESPACES = {
18
+ 'office' => 'urn:oasis:names:tc:opendocument:xmlns:office:1.0',
19
+ 'style' => 'urn:oasis:names:tc:opendocument:xmlns:style:1.0',
20
+ 'text' => 'urn:oasis:names:tc:opendocument:xmlns:text:1.0',
21
+ 'table' => 'urn:oasis:names:tc:opendocument:xmlns:table:1.0',
22
+ 'draw' => 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0',
23
+ 'fo' => 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0',
24
+ 'xlink' => 'http://www.w3.org/1999/xlink',
25
+ 'dc' => 'http://purl.org/dc/elements/1.1/',
26
+ 'meta' => 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0',
27
+ 'number' => 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0',
28
+ 'presentation' => 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0',
29
+ 'svg' => 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0',
30
+ 'chart' => 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0',
31
+ 'dr3d' => 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0',
32
+ 'math' => 'http://www.w3.org/1998/Math/MathML',
33
+ 'form' => 'urn:oasis:names:tc:opendocument:xmlns:form:1.0',
34
+ 'script' => 'urn:oasis:names:tc:opendocument:xmlns:script:1.0',
35
+ 'ooo' => 'http://openoffice.org/2004/office',
36
+ 'ooow' => 'http://openoffice.org/2004/writer',
37
+ 'oooc' => 'http://openoffice.org/2004/calc',
38
+ 'dom' => 'http://www.w3.org/2001/xml-events',
39
+ 'xforms' => 'http://www.w3.org/2002/xforms',
40
+ 'xsd' => 'http://www.w3.org/2001/XMLSchema',
41
+ 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
42
+ 'rpt' => 'http://openoffice.org/2005/report',
43
+ 'of' => 'urn:oasis:names:tc:opendocument:xmlns:of:1.2',
44
+ 'rdfa' => 'http://docs.oasis-open.org/opendocument/meta/rdfa#',
45
+ 'field' => 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0',
46
+ 'formx' => 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0'
47
+ }
48
+
49
+ def initialize(path)
50
+ @path = path
51
+ Zip::File.open(@path) do |zip|
52
+ @content = Nokogiri::XML::Document.parse(zip.read('content.xml'))
53
+ end
54
+ @sheets = []
55
+ @content.root.xpath(XPATH_SHEETS).each do |sheet|
56
+ @sheets.push(Sheet.new(sheet))
57
+ end
58
+ @content
59
+ end
60
+
61
+ def save(dest=nil)
62
+ if dest
63
+ FileUtils.cp(@path, dest)
64
+ else
65
+ dest = @path
66
+ end
67
+
68
+ @sheets.each do |sheet|
69
+ column = sheet.column
70
+ max_length = 0
71
+ column.content.parent.xpath('table:table-row').each do |row|
72
+ length = row.xpath('table:table-cell').length
73
+ max_length = length if max_length < length
74
+ end
75
+ column.set_attr('repeated', max_length)
76
+ end
77
+
78
+ Zip::File.open(dest) do |zip|
79
+ zip.get_output_stream('content.xml') do |io|
80
+ io << @content.to_s
81
+ end
82
+ end
83
+ end
84
+
85
+ def create_sheet
86
+ parent = @content.root.xpath(XPATH_SHEETS.split('/')[0..-2].join('/'))[0]
87
+ table = parent.add_element('table:table',
88
+ 'name' => "Sheet#{@sheets.length + 1}",
89
+ 'style-name' => 'ta1',
90
+ 'print' => 'false')
91
+ table.add_element('table:table-column',
92
+ 'style-name' => 'co1',
93
+ 'default-cell-style-name' => 'Default')
94
+ new_sheet = Sheet.new(table)
95
+ @sheets.push(new_sheet)
96
+ new_sheet
97
+ end
98
+
99
+ class Sheet
100
+ attr_reader :content
101
+ def initialize(content)
102
+ @content = content
103
+ end
104
+
105
+ def name
106
+ @content.attribute('name').to_s
107
+ end
108
+
109
+ def name=(name)
110
+ @content.set_attribute('table:name', name)
111
+ end
112
+
113
+ def [](row, col)
114
+ (row - rows.length).times do
115
+ rows.push(Row.new(@content.add_element('table:table-row',
116
+ 'table:style-name' => 'ro1'), rows.length+1))
117
+ end
118
+ row = rows[row-1]
119
+ col = ('A'..col.to_s).to_a.index(col.to_s)
120
+ cols = row.cols
121
+ (col - cols.length + 1).times do
122
+ no = (cols.last) ? cols.last.no.to_s.succ : 'A'
123
+ cols.push(Cell.new(row.add_element('table:table-cell', 'office:value-type' => 'string'), no))
124
+ end
125
+ cols[col]
126
+ end
127
+
128
+ def rows
129
+ return @rows if @rows
130
+ @rows = []
131
+ @content.xpath('./table:table-row').each_with_index{|row, index|
132
+ @rows << Row.new(row, index+1)
133
+ }
134
+ @rows
135
+ end
136
+
137
+ def column
138
+ Column.new(@content.xpath('table:table-column').first)
139
+ end
140
+ end
141
+
142
+ class Row
143
+ extend Forwardable
144
+
145
+ def_delegator :@content, :xpath, :xpath
146
+ def_delegator :@content, :add_element, :add_element
147
+ attr_reader :no
148
+
149
+ def initialize(content, no)
150
+ @content = content
151
+ @no = no
152
+ end
153
+
154
+ def cols
155
+ return @cols if @cols
156
+ @cols = []
157
+ no = 'A'
158
+ xpath('table:table-cell').each{|cell|
159
+ @cols << Cell.new(cell, no)
160
+ no.succ!
161
+ }
162
+ @cols
163
+ end
164
+
165
+ def create_cell
166
+
167
+ end
168
+ end
169
+
170
+ class Cell
171
+ extend Forwardable
172
+
173
+ def_delegator :@content, :fetch, :fetch
174
+ attr_reader :no
175
+
176
+ def initialize(content, no)
177
+ @content = content
178
+ @no = no.to_sym
179
+ end
180
+
181
+ def value
182
+ fetch('text:p').content
183
+ end
184
+
185
+ def value=(value)
186
+ fetch('text:p').content = value
187
+ end
188
+
189
+ def annotation
190
+ fetch('office:annotation/text:p').content
191
+ end
192
+
193
+ def annotation=(value)
194
+ fetch('office:annotation/text:p').content = value
195
+ end
196
+ end
197
+
198
+ class Column
199
+ attr_reader :content
200
+ def initialize(content)
201
+ @content = content
202
+ end
203
+
204
+ def attr(name)
205
+ @content['number-columns-' + name]
206
+ end
207
+
208
+ def set_attr(name, value)
209
+ @content['table:number-columns-' + name] = value.to_s
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-ods
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Ratnam Yadav
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-01-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.4.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.4'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.4.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: rubyzip
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.3.0
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.3.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 1.3.0
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.3.0
53
+ description: Gem for interacting with Ods files
54
+ email: heartcombo@googlegroups.com
55
+ executables: []
56
+ extensions: []
57
+ extra_rdoc_files: []
58
+ files:
59
+ - README.md
60
+ - lib/ruby/nokogiri_ext.rb
61
+ - lib/ruby/ods.rb
62
+ - lib/ruby/ods/version.rb
63
+ homepage: https://github.com/ratnamyadav/ruby-ods
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 2.1.0
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubygems_version: 3.2.32
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Gem for interacting with Ods files
86
+ test_files: []