open_xml 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|