open_xml 0.0.2 → 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 +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +6 -1
- data/README.md +21 -7
- data/lib/open_xml/template_document.rb +118 -18
- data/lib/open_xml/version.rb +1 -1
- data/lib/open_xml.rb +1 -1
- data/open_xml.gemspec +2 -2
- data/spec/.DS_Store +0 -0
- data/spec/alternate_chunk_spec.rb +43 -0
- data/spec/samples/caterpillar.jpg +0 -0
- data/spec/samples/report.docx +0 -0
- data/spec/samples/template_sample.docx +0 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/template_document_spec.rb +38 -43
- metadata +30 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b75c6c22557762c26b167295be1afa1e6598abc1
|
4
|
+
data.tar.gz: e149a88a547038884e322ddb66f5dea018591027
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 071829499a303aeeb9d536e1ee07d8f1f9537b207fd17352a5a350cae341a8c97d715a8d5b88e39542f2cb04f65386804f7803c91f1e0696ee2257a181a86ed6
|
7
|
+
data.tar.gz: f76afcba14892b117bbcf1ff0d2d03da1ff029e046bd3a1952c690432aa4a423c774719ae92fa3e5df2256cffcb7ef7e72095e948175bec3e4d733c7257873cf
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
-
## v0.0
|
1
|
+
## v0.1.0
|
2
|
+
* API Change!!! the template document is now created once and the data
|
3
|
+
is passed in through the process call. This allows you to loop over
|
4
|
+
lots of data and generate documents without having to instatiate a new
|
5
|
+
template document object.
|
2
6
|
|
7
|
+
## v0.0.1
|
3
8
|
* initial release
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
OpenXml
|
2
2
|
========
|
3
3
|
|
4
|
-
|
4
|
+
A ruby library for generating word documents that can handle basic html and images too.
|
5
5
|
|
6
6
|
## Installation
|
7
7
|
|
@@ -17,27 +17,41 @@ Or install it yourself as:
|
|
17
17
|
|
18
18
|
$ gem install open_xml
|
19
19
|
|
20
|
-
|
20
|
+
|
21
21
|
## Usage
|
22
22
|
Provide a path to a docx with the text **[SUPERPOWER]** placed anywhere.
|
23
23
|
|
24
24
|
```ruby
|
25
25
|
require 'open_xml'
|
26
26
|
|
27
|
-
doc = OpenXml::TemplateDocument.new(path: "[path to template]"
|
28
|
-
doc.process
|
29
|
-
|
27
|
+
doc = OpenXml::TemplateDocument.new(path: "[path to template]")
|
28
|
+
doc.process({"[SUPERPOWER]" => {text: "Bug Fixing!!!!"}})
|
29
|
+
|
30
30
|
IO.write "./powers.docx", doc.to_zip_buffer.string
|
31
31
|
```
|
32
32
|
|
33
|
+
HTML content
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
doc = OpenXml::TemplateDocument.new(path: "[path to template]")
|
37
|
+
doc.process({"[SUPERPOWER]" => {text: "<h1>Bug Fixing!!!!</h1>", html: true}})
|
38
|
+
```
|
39
|
+
|
40
|
+
HTML with images
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
doc = OpenXml::TemplateDocument.new(path: "[path to template]")
|
44
|
+
doc.process({"[SUPERPOWER]" => {text: "<img src='/powers.png' />", html: true, images: {'/powers.png' => "[Base64 encoded image]"}}})
|
45
|
+
```
|
46
|
+
|
33
47
|
## Todo
|
34
48
|
* ~~Implement reading and writing the word zip files~~
|
35
49
|
* ~~Create a template word document with formatted key words (bold, 14pt).~~
|
36
50
|
* ~~Replace the key words with the supplied plain text content but maintain all the formatting.~~
|
37
51
|
* ~~Handle replacing a key with multiple content~~
|
38
52
|
* ~~Extract these features into a gem~~
|
39
|
-
* Format html content for wordprocessingML e.x. bold, italic,
|
40
|
-
underline
|
53
|
+
* ~~Format html content for wordprocessingML e.x. bold, italic,
|
54
|
+
underline and handle images~~
|
41
55
|
|
42
56
|
## Contributing
|
43
57
|
|
@@ -2,49 +2,149 @@ require 'zip'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
|
4
4
|
module OpenXml
|
5
|
-
|
6
|
-
|
7
5
|
class TemplateDocument
|
8
|
-
attr_reader :template_path, :parts
|
6
|
+
attr_reader :template_path, :parts
|
9
7
|
|
10
8
|
def initialize(options)
|
11
|
-
@template_path = options
|
9
|
+
@template_path = options.fetch(:path)
|
12
10
|
@parts = {}
|
13
|
-
|
14
|
-
|
11
|
+
|
12
|
+
read_files
|
15
13
|
end
|
16
14
|
|
17
15
|
def to_zip_buffer
|
18
16
|
Zip::OutputStream.write_buffer do |w|
|
19
|
-
parts.each do |
|
20
|
-
w.put_next_entry
|
21
|
-
w.write
|
17
|
+
parts.each do |key, value|
|
18
|
+
w.put_next_entry key
|
19
|
+
w.write value
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
25
23
|
|
26
|
-
def process
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
def process(data)
|
25
|
+
@parts = @parts_cache.clone
|
26
|
+
register_type 'message/rfc822', 'mht'
|
27
|
+
|
28
|
+
doc = Nokogiri::XML(parts['word/document.xml'])
|
29
|
+
doc.xpath('//w:t').each do |node|
|
30
|
+
data.each do |key, value|
|
31
|
+
|
32
|
+
if node.content[/#{key}/]
|
33
|
+
process_plain_text(node, key, value, doc) unless value[:html]
|
34
|
+
process_html(node, key, value, doc) if value[:html]
|
35
|
+
end
|
36
|
+
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
34
|
-
parts[
|
40
|
+
parts['word/document.xml'] = flatten_xml doc
|
35
41
|
end
|
36
42
|
|
37
43
|
private
|
38
44
|
|
39
|
-
def
|
45
|
+
def process_plain_text(node, key, value, doc)
|
46
|
+
values = Array(value[:text])
|
47
|
+
|
48
|
+
if values.size > 1
|
49
|
+
values.each do |v|
|
50
|
+
br = Nokogiri::XML::Node.new 'w:br', doc
|
51
|
+
n = Nokogiri::XML::Node.new 'w:t', doc
|
52
|
+
|
53
|
+
n.content = v.to_s
|
54
|
+
|
55
|
+
node.parent << n
|
56
|
+
node.parent << br
|
57
|
+
end
|
58
|
+
|
59
|
+
node.remove
|
60
|
+
else
|
61
|
+
node.content = node.content.gsub(key, values.first.to_s) if values.first
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def process_html(node, key, value, doc)
|
66
|
+
new_node = create_chunk_file(key, value, doc)
|
67
|
+
node.parent.parent.add_next_sibling new_node
|
68
|
+
node.remove
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_chunk_file(key, content, doc)
|
72
|
+
id = key
|
73
|
+
|
74
|
+
parts["word/#{id}.mht"] = build_mht(content)
|
75
|
+
add_relation id
|
76
|
+
|
77
|
+
chunk = Nokogiri::XML::Node.new 'w:altChunk', doc
|
78
|
+
chunk['r:id'] = id
|
79
|
+
chunk
|
80
|
+
end
|
81
|
+
|
82
|
+
def add_relation(id)
|
83
|
+
relationships = Nokogiri::XML(parts['word/_rels/document.xml.rels'])
|
84
|
+
rel = Nokogiri::XML::Node.new 'Relationship', relationships
|
85
|
+
rel['Id'] = id
|
86
|
+
rel['Type'] = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk'
|
87
|
+
rel['Target'] = "/word/#{id}.mht"
|
88
|
+
|
89
|
+
relationships.at_xpath('//xmlns:Relationships') << rel
|
90
|
+
parts['word/_rels/document.xml.rels'] = flatten_xml relationships
|
91
|
+
end
|
92
|
+
|
93
|
+
def register_type(type, extension)
|
94
|
+
content = Nokogiri::XML(parts['[Content_Types].xml'])
|
95
|
+
node = Nokogiri::XML::Node.new 'Default', content
|
96
|
+
node['ContentType'] = type
|
97
|
+
node['Extension'] = extension
|
98
|
+
|
99
|
+
content.at_xpath('//xmlns:Default').add_next_sibling node
|
100
|
+
parts['[Content_Types].xml'] = flatten_xml content
|
101
|
+
end
|
102
|
+
|
103
|
+
def flatten_xml(doc)
|
104
|
+
doc.to_xml(indent: 0).gsub("\n","")
|
105
|
+
end
|
106
|
+
|
107
|
+
def read_files
|
40
108
|
Zip::File.new(template_path).each do |f|
|
41
109
|
parts[f.name] = f.get_input_stream.read
|
42
110
|
end
|
43
111
|
|
44
|
-
parts
|
112
|
+
@parts_cache = parts.clone
|
45
113
|
end
|
46
114
|
|
115
|
+
def build_mht(content)
|
116
|
+
message =<<MESSAGE
|
117
|
+
MIME-Version: 1.0
|
118
|
+
Content-Type: multipart/related; boundary=MY-SEPARATOR
|
119
|
+
|
120
|
+
--MY-SEPARATOR
|
121
|
+
Content-Type: text/html; charset=utf-8
|
122
|
+
Content-Transfer-Encoding: 8bit
|
123
|
+
|
124
|
+
#{content[:text]}
|
125
|
+
|
126
|
+
MESSAGE
|
47
127
|
|
48
|
-
end
|
49
128
|
|
129
|
+
content.fetch(:images){{}}.each do |key, value|
|
130
|
+
message << img_template(key, value)
|
131
|
+
end
|
132
|
+
|
133
|
+
message << "\n--MY-SEPARATOR--"
|
134
|
+
message
|
135
|
+
end
|
136
|
+
|
137
|
+
def img_template(key, value)
|
138
|
+
<<IMG
|
139
|
+
|
140
|
+
--MY-SEPARATOR
|
141
|
+
Content-Location: #{key}
|
142
|
+
Content-Transfer-Encoding: Base64
|
143
|
+
|
144
|
+
#{value}
|
145
|
+
|
146
|
+
IMG
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
50
150
|
end
|
data/lib/open_xml/version.rb
CHANGED
data/lib/open_xml.rb
CHANGED
data/open_xml.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = OpenXml::VERSION
|
9
9
|
spec.authors = ["Carlos Espejo"]
|
10
10
|
spec.email = ["carlosespejo@gmail.com"]
|
11
|
-
spec.description = %q{
|
12
|
-
spec.summary = %q{
|
11
|
+
spec.description = %q{Generate Word documents from a template, also handle html and images too.}
|
12
|
+
spec.summary = %q{A ruby library for generating word documents that can handle basic html and images too.}
|
13
13
|
spec.homepage = "https://github.com/CarlosEspejo/open_xml"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/spec/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
describe "Adding HTML and Images through the alternate chunk feature" do
|
5
|
+
|
6
|
+
let(:report_path){"#{File.expand_path('samples', __dir__)}/report.docx"}
|
7
|
+
let(:encoded_img){Base64.encode64(File.read("#{File.expand_path('samples', __dir__)}/caterpillar.jpg"))}
|
8
|
+
|
9
|
+
let(:t){TemplateDocument.new(path: report_path)}
|
10
|
+
|
11
|
+
it "should register MIME html type" do
|
12
|
+
t.process 'my_content' => {text: 'empty', html: true}
|
13
|
+
doc = Nokogiri::XML(t.parts['[Content_Types].xml'])
|
14
|
+
doc.xpath('//xmlns:Default/@ContentType').map(&:value).must_include 'message/rfc822'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should add the chunk id to the rels file" do
|
18
|
+
t.process 'my_content' => {text: 'empty', html: true}
|
19
|
+
doc = Nokogiri::XML(t.parts['word/_rels/document.xml.rels'])
|
20
|
+
doc.xpath('//xmlns:Relationship/@Id').map(&:value).must_include 'my_content'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should generate MIME html file" do
|
24
|
+
t.process 'my_content' => {text: '<u>This is underlined</u>', html: true}
|
25
|
+
t.parts['word/my_content.mht'].must_match(/#{'<u>This is underlined</u>'}/)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should generate MIME html file with a image" do
|
29
|
+
content = '<h1>Look at the image</h1><img src="./image.jpg" />'
|
30
|
+
|
31
|
+
t.process 'my_content' => {text: content, html: true, images: {"./image.jpg" => encoded_img}}
|
32
|
+
t.parts['word/my_content.mht'].must_match(/#{'Content-Location: ./image.jpg'}/)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should geneate MIME html file with multiple images" do
|
36
|
+
content = '<h1>Look at the images</h1>'
|
37
|
+
content << '<img src="/image.jpg" /><br/><br/><img src="/image2.jpg" />'
|
38
|
+
t.process 'my_content' => {text: content, html: true, images: {"/image.jpg" => encoded_img, '/image2.jpg' => encoded_img}}
|
39
|
+
t.parts['word/my_content.mht'].must_match(/#{'Content-Location: /image.jpg'}/)
|
40
|
+
t.parts['word/my_content.mht'].must_match(/#{'Content-Location: /image2.jpg'}/)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
data/spec/spec_helper.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'tempfile'
|
3
3
|
require 'nokogiri'
|
4
|
+
require 'pry'
|
4
5
|
|
5
6
|
describe TemplateDocument do
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
t.parts.keys.must_equal template_parts.keys
|
8
|
+
let(:template_path){"#{File.expand_path('samples', File.dirname(__FILE__))}/template_sample.docx"}
|
9
|
+
let(:report_path){"#{File.expand_path('samples', File.dirname(__FILE__))}/report.docx"}
|
10
10
|
|
11
|
+
it 'should read the template file and split it into parts' do
|
12
|
+
t = TemplateDocument.new(path: template_path)
|
13
|
+
t.parts.keys.must_include 'word/document.xml'
|
11
14
|
end
|
12
15
|
|
13
|
-
it
|
14
|
-
t = Tempfile.new(['output','.docx'])
|
16
|
+
it 'should create a new file from the template parts' do
|
17
|
+
t = Tempfile.new(['output', '.docx'])
|
15
18
|
|
16
19
|
temp_doc = TemplateDocument.new(path: template_path)
|
17
20
|
|
@@ -23,56 +26,48 @@ describe TemplateDocument do
|
|
23
26
|
|
24
27
|
end
|
25
28
|
|
26
|
-
it
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
t.process
|
31
|
-
IO.write temp.path, t.to_zip_buffer.string
|
32
|
-
|
33
|
-
processed = TemplateDocument.new(path: temp.path)
|
34
|
-
doc = Nokogiri::XML(processed.parts["word/document.xml"])
|
29
|
+
it 'should replace key words in the document xml' do
|
30
|
+
t = TemplateDocument.new(path: template_path)
|
31
|
+
t.process({ 'person_name' => {text: '<b>Carlos</b>'}, 'person_age' => {text: 30} })
|
32
|
+
doc = Nokogiri::XML(t.parts['word/document.xml'])
|
35
33
|
|
36
|
-
doc.xpath('//w:t').text
|
37
|
-
|
34
|
+
text = doc.xpath('//w:t').text
|
35
|
+
text[/Carlos/].wont_be_nil
|
36
|
+
text[/30/].wont_be_nil
|
38
37
|
end
|
39
38
|
|
40
|
-
it
|
39
|
+
it 'should replace one key word with many items' do
|
41
40
|
data = {
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
]
|
41
|
+
'my_list' => {text: [
|
42
|
+
'list 1',
|
43
|
+
'list 2',
|
44
|
+
'list 3',
|
45
|
+
'list 4',
|
46
|
+
'list 5'
|
47
|
+
]}
|
49
48
|
}
|
50
49
|
|
51
|
-
t = TemplateDocument.new(path: template_path
|
52
|
-
t.process
|
53
|
-
|
50
|
+
t = TemplateDocument.new(path: template_path)
|
51
|
+
t.process(data)
|
52
|
+
|
53
|
+
doc = Nokogiri::XML(t.parts['word/document.xml'])
|
54
54
|
|
55
55
|
text = doc.xpath('//w:t').text
|
56
56
|
|
57
|
-
text[/list
|
57
|
+
text[/list 2/].wont_be_nil
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
it "should cache the template document" do
|
61
|
+
t = TemplateDocument.new(path: template_path)
|
62
|
+
t.process({'person_name' => {text: 'steve'}})
|
63
|
+
doc = Nokogiri::XML(t.parts['word/document.xml'])
|
61
64
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
"word/styles.xml" => '',
|
69
|
-
"word/fontTable.xml" => '',
|
70
|
-
"word/header.xml" => '',
|
71
|
-
"word/footer.xml" => '',
|
72
|
-
"word/settings.xml" => '',
|
73
|
-
"word/_rels/document.xml.rels" => '',
|
74
|
-
"[Content_Types].xml" => ''
|
75
|
-
}
|
65
|
+
doc.text[/steve/].wont_be_nil
|
66
|
+
|
67
|
+
t.process({'person_name' => {text: 'carlos'}})
|
68
|
+
doc = Nokogiri::XML(t.parts['word/document.xml'])
|
69
|
+
|
70
|
+
doc.text[/carlos/].wont_be_nil
|
76
71
|
end
|
77
72
|
|
78
73
|
end
|
metadata
CHANGED
@@ -1,107 +1,108 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: open_xml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Espejo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: pry
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: nokogiri
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '1.6'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.6'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rubyzip
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '1.1'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.1'
|
97
|
-
description:
|
97
|
+
description: Generate Word documents from a template, also handle html and images
|
98
|
+
too.
|
98
99
|
email:
|
99
100
|
- carlosespejo@gmail.com
|
100
101
|
executables: []
|
101
102
|
extensions: []
|
102
103
|
extra_rdoc_files: []
|
103
104
|
files:
|
104
|
-
- .gitignore
|
105
|
+
- ".gitignore"
|
105
106
|
- CHANGELOG.md
|
106
107
|
- Gemfile
|
107
108
|
- LICENSE
|
@@ -111,6 +112,10 @@ files:
|
|
111
112
|
- lib/open_xml/template_document.rb
|
112
113
|
- lib/open_xml/version.rb
|
113
114
|
- open_xml.gemspec
|
115
|
+
- spec/.DS_Store
|
116
|
+
- spec/alternate_chunk_spec.rb
|
117
|
+
- spec/samples/caterpillar.jpg
|
118
|
+
- spec/samples/report.docx
|
114
119
|
- spec/samples/template_sample.docx
|
115
120
|
- spec/spec_helper.rb
|
116
121
|
- spec/template_document_spec.rb
|
@@ -124,22 +129,26 @@ require_paths:
|
|
124
129
|
- lib
|
125
130
|
required_ruby_version: !ruby/object:Gem::Requirement
|
126
131
|
requirements:
|
127
|
-
- -
|
132
|
+
- - ">="
|
128
133
|
- !ruby/object:Gem::Version
|
129
134
|
version: '0'
|
130
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
136
|
requirements:
|
132
|
-
- -
|
137
|
+
- - ">="
|
133
138
|
- !ruby/object:Gem::Version
|
134
139
|
version: '0'
|
135
140
|
requirements: []
|
136
141
|
rubyforge_project:
|
137
|
-
rubygems_version: 2.
|
142
|
+
rubygems_version: 2.2.2
|
138
143
|
signing_key:
|
139
144
|
specification_version: 4
|
140
|
-
summary:
|
141
|
-
|
145
|
+
summary: A ruby library for generating word documents that can handle basic html and
|
146
|
+
images too.
|
142
147
|
test_files:
|
148
|
+
- spec/.DS_Store
|
149
|
+
- spec/alternate_chunk_spec.rb
|
150
|
+
- spec/samples/caterpillar.jpg
|
151
|
+
- spec/samples/report.docx
|
143
152
|
- spec/samples/template_sample.docx
|
144
153
|
- spec/spec_helper.rb
|
145
154
|
- spec/template_document_spec.rb
|