docxer 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +119 -0
- data/Rakefile +9 -0
- data/lib/docxer.rb +29 -0
- data/lib/docxer/content_types.rb +68 -0
- data/lib/docxer/content_types/default.rb +18 -0
- data/lib/docxer/content_types/override.rb +18 -0
- data/lib/docxer/document.rb +36 -0
- data/lib/docxer/properties.rb +29 -0
- data/lib/docxer/properties/app.rb +37 -0
- data/lib/docxer/properties/core.rb +32 -0
- data/lib/docxer/relationships.rb +49 -0
- data/lib/docxer/relationships/relationship.rb +19 -0
- data/lib/docxer/version.rb +3 -0
- data/lib/docxer/word.rb +16 -0
- data/lib/docxer/word/contents.rb +6 -0
- data/lib/docxer/word/contents/break.rb +33 -0
- data/lib/docxer/word/contents/image.rb +38 -0
- data/lib/docxer/word/contents/paragraph.rb +59 -0
- data/lib/docxer/word/contents/table.rb +223 -0
- data/lib/docxer/word/contents/table_of_content.rb +75 -0
- data/lib/docxer/word/contents/text.rb +34 -0
- data/lib/docxer/word/document.rb +144 -0
- data/lib/docxer/word/effects.rb +210 -0
- data/lib/docxer/word/endnotes.rb +39 -0
- data/lib/docxer/word/fonts.rb +42 -0
- data/lib/docxer/word/fonts/font.rb +25 -0
- data/lib/docxer/word/footers.rb +30 -0
- data/lib/docxer/word/footers/footer.rb +118 -0
- data/lib/docxer/word/footnotes.rb +40 -0
- data/lib/docxer/word/headers.rb +30 -0
- data/lib/docxer/word/headers/header.rb +142 -0
- data/lib/docxer/word/helpers.rb +37 -0
- data/lib/docxer/word/medias.rb +31 -0
- data/lib/docxer/word/medias/media.rb +37 -0
- data/lib/docxer/word/numbering.rb +141 -0
- data/lib/docxer/word/relationships.rb +57 -0
- data/lib/docxer/word/relationships/relationship.rb +21 -0
- data/lib/docxer/word/settings.rb +61 -0
- data/lib/docxer/word/styles.rb +235 -0
- data/lib/docxer/word/themes.rb +30 -0
- data/lib/docxer/word/themes/theme.rb +313 -0
- data/lib/docxer/word/web_settings.rb +29 -0
- metadata +121 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a012fa9eb5553b91d77c00ea040618f646eb9968
|
4
|
+
data.tar.gz: c905f121249032839c8a0f420d5f6a558aa7ffa4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f049b16bc00315cae6605fdafe14aacf9be7de1d8fdeb676184793016ba8b745109bd0c462eeabd8183c10afb8ea2f600f07046f7486cc8f87909f3c347ed31e
|
7
|
+
data.tar.gz: 85332d781045ba12b3e961100c4ccee41f01a8d7d3d838c355dca7bc6cfc1f83ec43148535d833dacc1c5edcbe585c99f9697afd0b3685514f691eaa63e70138
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Timur Gabdrakipov
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
Docxer gem provides ability to create docx documents using Ruby.
|
2
|
+
|
3
|
+
## Features
|
4
|
+
|
5
|
+
1. Paragraphs
|
6
|
+
2. Text formatting
|
7
|
+
3. Header and Footer (limited)
|
8
|
+
4. Tables (limited)
|
9
|
+
5. Images
|
10
|
+
6. Table of Content
|
11
|
+
7. Page Numbering
|
12
|
+
|
13
|
+
At the moment, the gem supports a limited number of functions, but the development of the gem is still in progress, and perhaps functionality will be expanded in the future. First of all, try to add documentation for the code and tests.
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
word = Docxer::Document.new
|
19
|
+
document = word.document
|
20
|
+
|
21
|
+
# Creates Header
|
22
|
+
header = Docxer::Word::Headers::Header.new do |h|
|
23
|
+
# Inserts image into header
|
24
|
+
header_logo = document.add_media File.open('logo.png')
|
25
|
+
h.image header_logo, align: 'right', width: 100, height: 100
|
26
|
+
end
|
27
|
+
|
28
|
+
# Adds header
|
29
|
+
document.add_header(header)
|
30
|
+
|
31
|
+
# Creates Footer
|
32
|
+
footer = Docxer::Word::Footers::Footer.new do |f|
|
33
|
+
# Adds footer text
|
34
|
+
f.text "Footer Text", size: 8, align: 'center'
|
35
|
+
# Adds page numbers
|
36
|
+
f.page_numbers
|
37
|
+
end
|
38
|
+
# Adds footer
|
39
|
+
document.add_footer(footer)
|
40
|
+
|
41
|
+
# Creates paragraph
|
42
|
+
document.p(size: 16, align: "center") do |p|
|
43
|
+
p.text "Title"
|
44
|
+
# Adds 3 break lines
|
45
|
+
p.br times: 3
|
46
|
+
end
|
47
|
+
|
48
|
+
document.p do |p|
|
49
|
+
# Adds text with specific styles
|
50
|
+
p.text "Subtitle", size: 14, color: '568AB2', bold: true
|
51
|
+
end
|
52
|
+
|
53
|
+
# Adds break page
|
54
|
+
document.br(page: true)
|
55
|
+
|
56
|
+
|
57
|
+
# Adds TOC
|
58
|
+
document.text "Table of Content", size: 18, color: 'D36C8A', bold: true
|
59
|
+
document.table_of_content(size: 14, bold: true) do |table|
|
60
|
+
# Adds TOC element
|
61
|
+
table.add_row("Table", 1)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Adds break page
|
65
|
+
document.br(page: true)
|
66
|
+
|
67
|
+
# Adds table
|
68
|
+
document.table( columns_width: [ 316, 160, 135 ] ) do |table|
|
69
|
+
# Adds row with specific styles
|
70
|
+
table.tr(fill: "FBD4B4", bold: true, align: 'center' ) do |tr|
|
71
|
+
# Adds cells
|
72
|
+
tr.tc(borders: { top: 1, right: nil, bottom: 1, left: 1 }) do |tc|
|
73
|
+
tc.text "Header 1"
|
74
|
+
end
|
75
|
+
tr.tc(borders: { top: 1, right: nil, bottom: 1, left: nil }) do |tc|
|
76
|
+
tc.text "Header 2"
|
77
|
+
end
|
78
|
+
tr.tc(borders: { top: 1, right: 1, bottom: 1, left: nil }) do |tc|
|
79
|
+
tc.text "Header 3"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Adds another row
|
84
|
+
table.tr(align: 'center') do |tr|
|
85
|
+
# Adds rowspan
|
86
|
+
tr.tc(rowspan: true, borders: { top: 1, right: 1, bottom: 1, left: 1 }, valign: 'center') do |tc|
|
87
|
+
tc.text "Rowspan", align: 'left'
|
88
|
+
end
|
89
|
+
tr.tc(borders: { top: 1, right: 1, bottom: 1, left: 1 }) do |tc|
|
90
|
+
tc.text "Cell Value 2"
|
91
|
+
end
|
92
|
+
tr.tc(borders: { top: 1, right: 1, bottom: 1, left: 1 }) do |tc|
|
93
|
+
tc.text "Cell Value 3"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
table.tr(fill: "D9D9D9", bold: true, align: 'center' ) do |tr|
|
98
|
+
tr.tc(borders: { top: 1, right: 1, bottom: 1, left: 1 }, merged: true) # Use with rowspan to mark cell as merged
|
99
|
+
# Adds colspan
|
100
|
+
tr.tc(colspan: 2, valign: 'bottom', borders: { top: 1, right: 1, bottom: 1, left: 1 }) do |tc|
|
101
|
+
tc.text "Colspan"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Adds image
|
107
|
+
document.p do |p|
|
108
|
+
p.text "Image Example", size: 16, bold: true, italic: true, underline: true, br: true
|
109
|
+
|
110
|
+
# Adds image to container
|
111
|
+
media = document.add_media File.open('image.png')
|
112
|
+
# Insert media into paragraph
|
113
|
+
p.image media, style: { width: '200pt', height: '200pt' }
|
114
|
+
end
|
115
|
+
|
116
|
+
# Creates Word Document
|
117
|
+
io = word.render
|
118
|
+
File.open('doc_1.docx', 'wb'){|f| f.write(io.string) }
|
119
|
+
```
|
data/Rakefile
ADDED
data/lib/docxer.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'zip/zip'
|
3
|
+
|
4
|
+
require 'docxer/relationships'
|
5
|
+
require 'docxer/content_types'
|
6
|
+
require 'docxer/properties'
|
7
|
+
require 'docxer/word'
|
8
|
+
require 'docxer/document'
|
9
|
+
|
10
|
+
module Docxer
|
11
|
+
|
12
|
+
def self.to_xml(document)
|
13
|
+
document.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML).gsub("\n", "\r\n").strip
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.test
|
17
|
+
word = Docxer::Document.new
|
18
|
+
|
19
|
+
word.document.break
|
20
|
+
word.document.break
|
21
|
+
word.document.break
|
22
|
+
|
23
|
+
file = word.render
|
24
|
+
File.open('test.docx', 'wb') do |f|
|
25
|
+
f.write(file.string)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'docxer/content_types/default'
|
2
|
+
require 'docxer/content_types/override'
|
3
|
+
|
4
|
+
module Docxer
|
5
|
+
class ContentTypes
|
6
|
+
|
7
|
+
attr_accessor :content_types
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@content_types = []
|
11
|
+
add(:default, "rels", "application/vnd.openxmlformats-package.relationships+xml")
|
12
|
+
add(:default, "xml", "application/xml")
|
13
|
+
add(:default, "png", "image/png")
|
14
|
+
add(:override, "/word/document.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")
|
15
|
+
add(:override, "/word/styles.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml")
|
16
|
+
add(:override, "/word/stylesWithEffects.xml", "application/vnd.ms-word.stylesWithEffects+xml")
|
17
|
+
add(:override, "/word/settings.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml")
|
18
|
+
add(:override, "/word/webSettings.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml")
|
19
|
+
add(:override, "/word/fontTable.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml")
|
20
|
+
add(:override, "/word/theme/theme1.xml", "application/vnd.openxmlformats-officedocument.theme+xml")
|
21
|
+
add(:override, "/docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml")
|
22
|
+
add(:override, "/docProps/app.xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml")
|
23
|
+
add(:override, "/word/numbering.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml")
|
24
|
+
add(:override, "/word/footnotes.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml")
|
25
|
+
add(:override, "/word/endnotes.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml")
|
26
|
+
add(:override, "/word/footer1.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml")
|
27
|
+
add(:override, "/word/header1.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml")
|
28
|
+
end
|
29
|
+
|
30
|
+
def add(type, attr, content)
|
31
|
+
content_type = create_content_type(type, attr, content)
|
32
|
+
@content_types << content_type if content_type
|
33
|
+
content_type
|
34
|
+
end
|
35
|
+
|
36
|
+
def render(zip)
|
37
|
+
zip.put_next_entry('[Content_Types].xml')
|
38
|
+
zip.write(Docxer.to_xml(document))
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def document
|
43
|
+
Nokogiri::XML::Builder.with(Nokogiri::XML('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>')) do |xml|
|
44
|
+
xml.Types(xmlns: 'http://schemas.openxmlformats.org/package/2006/content-types') do
|
45
|
+
@content_types.each do |content_type|
|
46
|
+
content_type.build(xml)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# TODO: Need to rewrite create_content_type method
|
53
|
+
def create_content_type(type, attr, content)
|
54
|
+
send(:"create_#{type.to_s}", attr, content)
|
55
|
+
rescue
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_default(attr, content)
|
60
|
+
Default.new(attr, content)
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_override(attr, content)
|
64
|
+
Override.new(attr, content)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Docxer
|
2
|
+
class ContentTypes
|
3
|
+
class Default
|
4
|
+
|
5
|
+
attr_accessor :extension, :content_type
|
6
|
+
|
7
|
+
def initialize(extension, content_type)
|
8
|
+
@extension = extension
|
9
|
+
@content_type = content_type
|
10
|
+
end
|
11
|
+
|
12
|
+
def build(xml)
|
13
|
+
xml.Default('Extension' => @extension, 'ContentType' => @content_type)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Docxer
|
2
|
+
class ContentTypes
|
3
|
+
class Override
|
4
|
+
|
5
|
+
attr_accessor :part_name, :content_type
|
6
|
+
|
7
|
+
def initialize(part_name, content_type)
|
8
|
+
@part_name = part_name
|
9
|
+
@content_type = content_type
|
10
|
+
end
|
11
|
+
|
12
|
+
def build(xml)
|
13
|
+
xml.Override('PartName' => @part_name, 'ContentType' => @content_type)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Docxer
|
2
|
+
class Document
|
3
|
+
|
4
|
+
attr_accessor :document, :properties, :relationships, :content_types
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
def relationships
|
11
|
+
@relationships ||= Relationships.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def properties
|
15
|
+
@properties ||= Properties.new({})
|
16
|
+
end
|
17
|
+
|
18
|
+
def content_types
|
19
|
+
@content_types ||= ContentTypes.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def document
|
23
|
+
@document ||= Word::Document.new({})
|
24
|
+
end
|
25
|
+
|
26
|
+
def render
|
27
|
+
Zip::ZipOutputStream.write_buffer do |zip|
|
28
|
+
document.render(zip)
|
29
|
+
properties.render(zip)
|
30
|
+
relationships.render(zip)
|
31
|
+
content_types.render(zip)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'docxer/properties/app'
|
2
|
+
require 'docxer/properties/core'
|
3
|
+
|
4
|
+
module Docxer
|
5
|
+
class Properties
|
6
|
+
attr_accessor :options, :app, :core
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def app
|
13
|
+
@app ||= App.new(@options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def core
|
17
|
+
@core ||= Core.new(@options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def render(zip)
|
21
|
+
zip.put_next_entry('docProps/app.xml')
|
22
|
+
zip.write(Docxer.to_xml(app.document))
|
23
|
+
|
24
|
+
zip.put_next_entry('docProps/core.xml')
|
25
|
+
zip.write(Docxer.to_xml(core.document))
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Docxer
|
2
|
+
class Properties
|
3
|
+
class App
|
4
|
+
|
5
|
+
attr_accessor :options
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def document
|
12
|
+
Nokogiri::XML::Builder.with(Nokogiri::XML('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>')) do |xml|
|
13
|
+
xml.Properties('xmlns' => "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties", 'xmlns:vt' => "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes") do
|
14
|
+
xml.Template "Normal.dotm"
|
15
|
+
xml.TotalTime 0
|
16
|
+
xml.Pages 1
|
17
|
+
xml.Words 0
|
18
|
+
xml.Characters 0
|
19
|
+
xml.Application "Docxer Ruby Gem"
|
20
|
+
xml.DocSecurity 0
|
21
|
+
xml.Lines 0
|
22
|
+
xml.Paragraphs 0
|
23
|
+
xml.ScaleCrop false
|
24
|
+
xml.Company options[:creator]
|
25
|
+
xml.LinksUpToDate false
|
26
|
+
xml.CharactersWithSpaces 0
|
27
|
+
xml.SharedDoc false
|
28
|
+
xml.HyperlinksChanged false
|
29
|
+
xml.AppVersion "14.0000"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Docxer
|
2
|
+
class Properties
|
3
|
+
class Core
|
4
|
+
|
5
|
+
attr_accessor :options
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def document
|
12
|
+
Nokogiri::XML::Builder.with(Nokogiri::XML('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>')) do |xml|
|
13
|
+
xml.coreProperties('xmlns:cp' => 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties', 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', 'xmlns:dcterms' => 'http://purl.org/dc/terms/', 'xmlns:dcmitype' => 'http://purl.org/dc/dcmitype/', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance') do
|
14
|
+
xml.parent.namespace = xml.parent.namespace_definitions.find{|ns| ns.prefix=="cp" }
|
15
|
+
# xml['dc'].title options[:title]
|
16
|
+
xml['dc'].creator do
|
17
|
+
options[:creator]
|
18
|
+
end
|
19
|
+
xml['cp'].lastModifiedBy do
|
20
|
+
options[:creator]
|
21
|
+
end
|
22
|
+
xml['cp'].revision 1
|
23
|
+
xml['dcterms'].created(Time.now.strftime('%Y-%m-%dT%H:%M:%SZ'), 'xsi:type' => 'dcterms:W3CDTF')
|
24
|
+
xml['dcterms'].modified(Time.now.strftime('%Y-%m-%dT%H:%M:%SZ'), 'xsi:type' => 'dcterms:W3CDTF')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'docxer/relationships/relationship'
|
2
|
+
|
3
|
+
module Docxer
|
4
|
+
class Relationships
|
5
|
+
@@prefix = 'rId'
|
6
|
+
|
7
|
+
attr_accessor :relationships
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@relationships = []
|
11
|
+
@counter = 0
|
12
|
+
add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", "word/document.xml")
|
13
|
+
add("http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties", "docProps/core.xml")
|
14
|
+
add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties", "docProps/app.xml")
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(type, target)
|
18
|
+
relationship = create_relationship(sequence, type, target)
|
19
|
+
@relationships << relationship if relationship
|
20
|
+
relationship
|
21
|
+
end
|
22
|
+
|
23
|
+
def render(zip)
|
24
|
+
zip.put_next_entry('_rels/.rels')
|
25
|
+
zip.write(Docxer.to_xml(document))
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def document
|
30
|
+
Nokogiri::XML::Builder.with(Nokogiri::XML('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>')) do |xml|
|
31
|
+
xml.Relationships(xmlns: 'http://schemas.openxmlformats.org/package/2006/relationships') do
|
32
|
+
@relationships.each do |relationship|
|
33
|
+
relationship.build(xml)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_relationship(id, type, target)
|
40
|
+
Relationship.new(id, type, target)
|
41
|
+
end
|
42
|
+
|
43
|
+
def sequence
|
44
|
+
@counter += 1
|
45
|
+
@@prefix + @counter.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|