minimalist_ods 0.1.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.
- checksums.yaml +7 -0
- data/lib/minimalist_ods.rb +215 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 463a57f017a1b0a8761d32fc7a52d9a191a03750725489eb8e12b9e0a0d4cdca
|
4
|
+
data.tar.gz: f3afeb53140f7e7ded4e96b786ec889adc55cbbd8644e20dbd00653d763cac62
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6954e7a37852a4c3b72b3422667755a557818dcc1aa80f07b448e60fe82d0e6e2ae42c418ff28f5b0c1f59e29275928c6ef47660734fc5955557d930c4351d56
|
7
|
+
data.tar.gz: 45be33c3a46aa0b9f2ce7bfbba3dc237a2bb14fe8ae4cc3cdd125f68a5819c61c15f9817fd97ab352174d6937035db8c4bbbbff3be1975f4fec235400b7ab66e
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A Ruby Minimalist ODS
|
4
|
+
require 'rubygems'
|
5
|
+
require 'zip'
|
6
|
+
require 'date'
|
7
|
+
|
8
|
+
class MinimalistODS
|
9
|
+
MIMETYPE = 'application/vnd.oasis.opendocument.spreadsheet'
|
10
|
+
META_TEMPLATE = <<~XML
|
11
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
12
|
+
<office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
|
13
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
14
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
15
|
+
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
|
16
|
+
xmlns:ooo="http://openoffice.org/2004/office"
|
17
|
+
xmlns:grddl="http://www.w3.org/2003/g/data-view#"
|
18
|
+
grddl:transformation="http://docs.oasis-open.org/office/1.2/xslt/odf2rdf.xsl"
|
19
|
+
office:version="1.2">
|
20
|
+
<office:meta>
|
21
|
+
<meta:generator>ARMO</meta:generator>
|
22
|
+
<meta:initial-creator>:CREATOR</meta:initial-creator>
|
23
|
+
<dc:creator>:CREATOR</dc:creator>
|
24
|
+
<meta:creation-date>:TIME</meta:creation-date>
|
25
|
+
<dc:date>:TIME</dc:date>
|
26
|
+
<meta:editing-cycles>1</meta:editing-cycles>
|
27
|
+
</office:meta>
|
28
|
+
</office:document-meta>
|
29
|
+
XML
|
30
|
+
|
31
|
+
MANIFEST_TEMPLATE = <<~XML
|
32
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
33
|
+
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">
|
34
|
+
<manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.spreadsheet" manifest:version="1.2" manifest:full-path="/"/>
|
35
|
+
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/>
|
36
|
+
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml"/>
|
37
|
+
</manifest:manifest>
|
38
|
+
XML
|
39
|
+
|
40
|
+
CONTENT_HEADER = <<~XML
|
41
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
42
|
+
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2">
|
43
|
+
<office:scripts/>
|
44
|
+
<office:font-face-decls>
|
45
|
+
<style:font-face style:name="Liberation Sans" svg:font-family="'Liberation Sans'" style:font-family-generic="swiss" style:font-pitch="variable"/>
|
46
|
+
<style:font-face style:name="Mangal" svg:font-family="Mangal" style:font-family-generic="system" style:font-pitch="variable"/>
|
47
|
+
<style:font-face style:name="Microsoft YaHei" svg:font-family="'Microsoft YaHei'" style:font-family-generic="system" style:font-pitch="variable"/>
|
48
|
+
<style:font-face style:name="Segoe UI" svg:font-family="'Segoe UI'" style:font-family-generic="system" style:font-pitch="variable"/>
|
49
|
+
<style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="system" style:font-pitch="variable"/>
|
50
|
+
</office:font-face-decls>
|
51
|
+
<office:automatic-styles>
|
52
|
+
<style:style style:name="co1" style:family="table-column">
|
53
|
+
<style:table-column-properties fo:break-before="auto" style:column-width="22.58mm"/>
|
54
|
+
</style:style>
|
55
|
+
<style:style style:name="ro1" style:family="table-row">
|
56
|
+
<style:table-row-properties style:row-height="4.52mm" fo:break-before="auto" style:use-optimal-row-height="true"/>
|
57
|
+
</style:style>
|
58
|
+
<style:style style:name="ta1" style:family="table" style:master-page-name="Default">
|
59
|
+
<style:table-properties table:display="true" style:writing-mode="lr-tb"/>
|
60
|
+
</style:style>
|
61
|
+
</office:automatic-styles>
|
62
|
+
<office:body>
|
63
|
+
<office:spreadsheet>
|
64
|
+
<table:calculation-settings table:automatic-find-labels="false"/>
|
65
|
+
XML
|
66
|
+
|
67
|
+
CONTENT_FOOTER = <<~XML
|
68
|
+
<table:named-expressions/>
|
69
|
+
</office:spreadsheet>
|
70
|
+
</office:body>
|
71
|
+
</office:document-content>
|
72
|
+
XML
|
73
|
+
|
74
|
+
TABLE_TEMPLATE = <<~XML
|
75
|
+
<table:table table:name=":NAME" table:style-name="ta1">
|
76
|
+
<table:table-column table:style-name="co1" table:number-columns-repeated=":COL_NUMBER" table:default-cell-style-name="Default"/>
|
77
|
+
XML
|
78
|
+
|
79
|
+
ROW_TEMPLATE = <<~XML
|
80
|
+
<table:table-row table:style-name="ro1">
|
81
|
+
:CELLS
|
82
|
+
</table:table-row>
|
83
|
+
XML
|
84
|
+
|
85
|
+
NUMERIC_CELL_TEMPLATE = <<~XML
|
86
|
+
<table:table-cell office:value-type="float" office:value=":VALUE">
|
87
|
+
<text:p>:VALUE</text:p>
|
88
|
+
</table:table-cell>
|
89
|
+
XML
|
90
|
+
|
91
|
+
TEXT_CELL_TEMPLATE = <<~XML
|
92
|
+
<table:table-cell office:value-type="string" calcext:value-type="string">
|
93
|
+
<text:p>:VALUE</text:p>
|
94
|
+
</table:table-cell>
|
95
|
+
XML
|
96
|
+
|
97
|
+
TABLE_OPEN = 1
|
98
|
+
TABLE_CLOSED = 0
|
99
|
+
|
100
|
+
attr_reader :zip, :save_as, :creator, :buffer
|
101
|
+
|
102
|
+
def initialize(save_as, creator = 'minimalist-ods')
|
103
|
+
@save_as = save_as
|
104
|
+
@creator = creator
|
105
|
+
init_zip!
|
106
|
+
init_mimetype!
|
107
|
+
init_meta!
|
108
|
+
init_manifest!
|
109
|
+
init_content!
|
110
|
+
end
|
111
|
+
|
112
|
+
def init_zip!
|
113
|
+
@zip = Zip::File.open(save_as, Zip::File::CREATE)
|
114
|
+
end
|
115
|
+
|
116
|
+
def init_mimetype!
|
117
|
+
write_to_zip('mimetype', MIMETYPE)
|
118
|
+
end
|
119
|
+
|
120
|
+
def init_meta!
|
121
|
+
meta = META_TEMPLATE.gsub(':CREATOR', creator).gsub(':TIME', Time.now.strftime('%Y-%m-%dT%H:%M:%S'))
|
122
|
+
write_to_zip('meta.xml', meta)
|
123
|
+
end
|
124
|
+
|
125
|
+
def init_manifest!
|
126
|
+
write_to_zip('META-INF/manifest.xml', MANIFEST_TEMPLATE)
|
127
|
+
end
|
128
|
+
|
129
|
+
def init_content!
|
130
|
+
@buffer = @zip.get_output_stream('content.xml')
|
131
|
+
@status = TABLE_CLOSED
|
132
|
+
buffer.write(CONTENT_HEADER)
|
133
|
+
end
|
134
|
+
|
135
|
+
class MinimalistOODSError < StandardError
|
136
|
+
end
|
137
|
+
|
138
|
+
class TableAlreadyOpened < MinimalistOODSError
|
139
|
+
def initialize
|
140
|
+
super('The last table is still opened')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class InvalidRowLength < MinimalistOODSError
|
145
|
+
def initialize(expected, got)
|
146
|
+
super("The number of rows doesn't match. Expected: #{@expected}, got: #{got}")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class TableNotOpened < MinimalistOODSError
|
151
|
+
def initialize
|
152
|
+
super('Currently, there is not table opened')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class InvalidParameter < MinimalistOODSError
|
157
|
+
end
|
158
|
+
|
159
|
+
def open_table(table_name, cols_number)
|
160
|
+
raise TableAlreadyOpened if @status == TABLE_OPEN
|
161
|
+
raise InvalidParameter, "Got invalid value `#{cols_number}' for table size" if cols_number.nil? || !cols_number.is_a?(Integer) || !cols_number.positive?
|
162
|
+
@cols_number = cols_number
|
163
|
+
|
164
|
+
table_header = TABLE_TEMPLATE.gsub(':NAME', table_name).gsub(':COL_NUMBER', cols_number.to_s)
|
165
|
+
buffer.write(table_header)
|
166
|
+
@status = TABLE_OPEN
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_row(row)
|
170
|
+
raise InvalidRowLength.new(@cols_number, row.size) if row.size != @cols_number
|
171
|
+
|
172
|
+
cells = row.map { |cell| cell_to_xml(cell) }.join
|
173
|
+
buffer.write(ROW_TEMPLATE.gsub(':CELLS', cells))
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
def close_table
|
178
|
+
raise TableNotOpened if @status == TABLE_CLOSED
|
179
|
+
|
180
|
+
buffer.write('</table:table>')
|
181
|
+
@status = TABLE_CLOSED
|
182
|
+
end
|
183
|
+
|
184
|
+
def close_file
|
185
|
+
buffer.write(CONTENT_FOOTER)
|
186
|
+
buffer.close
|
187
|
+
zip.close
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def write_to_zip(file_name, content)
|
193
|
+
stream = zip.get_output_stream(file_name)
|
194
|
+
stream.write(content)
|
195
|
+
stream.close
|
196
|
+
end
|
197
|
+
|
198
|
+
def cell_to_xml(cell)
|
199
|
+
if numeric?(cell.to_s)
|
200
|
+
NUMERIC_CELL_TEMPLATE.gsub(':VALUE', cell.to_s)
|
201
|
+
else
|
202
|
+
TEXT_CELL_TEMPLATE.gsub(':VALUE', normalize(cell.to_s))
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def numeric?(str)
|
207
|
+
true if Float(str)
|
208
|
+
rescue StandardError
|
209
|
+
false
|
210
|
+
end
|
211
|
+
|
212
|
+
def normalize(str)
|
213
|
+
str.gsub(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/, '').gsub(/[&<>]/, '&' => '&', '<' => '<', '>' => '>').encode('UTF-8')
|
214
|
+
end
|
215
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minimalist_ods
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gilberto Vargas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-07-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rubyzip
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: A minimalist ODS generator written in Ruby
|
28
|
+
email:
|
29
|
+
- tachoguitar@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- lib/minimalist_ods.rb
|
35
|
+
homepage: https://github.com/TachoMex/minimalist-ods
|
36
|
+
licenses:
|
37
|
+
- MIT
|
38
|
+
metadata: {}
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubygems_version: 3.5.14
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: A minimalist ODS generator
|
58
|
+
test_files: []
|