sablon 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +109 -0
- data/Rakefile +10 -0
- data/lib/sablon.rb +14 -0
- data/lib/sablon/operations.rb +61 -0
- data/lib/sablon/parser/mail_merge.rb +86 -0
- data/lib/sablon/processor.rb +135 -0
- data/lib/sablon/processor/section_properties.rb +34 -0
- data/lib/sablon/template.rb +35 -0
- data/lib/sablon/version.rb +3 -0
- data/sablon.gemspec +28 -0
- data/test/expression_test.rb +15 -0
- data/test/fixtures/sablon_sample.docx +0 -0
- data/test/fixtures/sablon_template.docx +0 -0
- data/test/mail_merge_parser_test.rb +131 -0
- data/test/processor_test.rb +697 -0
- data/test/sablon_test.rb +52 -0
- data/test/sandbox/.gitkeep +0 -0
- data/test/section_properties_test.rb +41 -0
- data/test/support/document_xml_helper.rb +26 -0
- data/test/test_helper.rb +13 -0
- metadata +163 -0
data/test/sablon_test.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class SablonTest < Sablon::TestCase
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
@base_path = Pathname.new(File.expand_path("../", __FILE__))
|
8
|
+
@output_path = @base_path + "sandbox/sablon.docx"
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_generate_document_from_template
|
12
|
+
template = Sablon.template(@base_path + "fixtures/sablon_template.docx")
|
13
|
+
person = OpenStruct.new "first_name" => "Ronald", "last_name" => "Anderson"
|
14
|
+
item = Struct.new(:index, :label, :rating)
|
15
|
+
position = Struct.new(:duration, :label, :description)
|
16
|
+
language = Struct.new(:name, :skill)
|
17
|
+
context = {
|
18
|
+
"title" => "Letter of application",
|
19
|
+
"person" => person,
|
20
|
+
"items" => [item.new("1.", "Ruby", "★" * 5), item.new("2.", "Java", "★" * 1), item.new("3.", "Python", "★" * 3)],
|
21
|
+
"career" => [position.new("1999 - 2006", "Junior Java Engineer", "Lorem ipsum dolor\nsit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."),
|
22
|
+
position.new("2006 - 2013", "Senior Ruby Developer", "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.")],
|
23
|
+
"technologies" => ["HTML", "CSS", "SASS", "LESS", "JavaScript"],
|
24
|
+
"languages" => [language.new("German", "native speaker"), language.new("English", "fluent")],
|
25
|
+
"training" => "At vero eos et accusam et justo duo dolores et ea rebum.\n\nStet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
|
26
|
+
}
|
27
|
+
properties = {
|
28
|
+
start_page_number: 7
|
29
|
+
}
|
30
|
+
template.render_to_file @output_path, context, properties
|
31
|
+
|
32
|
+
assert_docx_equal @base_path + "fixtures/sablon_sample.docx", @output_path
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def assert_docx_equal(expected_path, actual_path)
|
37
|
+
if get_document_xml(expected_path) != get_document_xml(actual_path)
|
38
|
+
msg = <<-error
|
39
|
+
The generated document does not match the sample. Please investigate.
|
40
|
+
|
41
|
+
If the generated document is correct, the sample needs to be updated:
|
42
|
+
\t cp #{actual_path} #{expected_path}
|
43
|
+
error
|
44
|
+
fail msg
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_document_xml(path)
|
49
|
+
document_xml_entry = Zip::File.open(path).get_entry("word/document.xml")
|
50
|
+
document_xml_entry.get_input_stream.read
|
51
|
+
end
|
52
|
+
end
|
File without changes
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "support/document_xml_helper"
|
3
|
+
|
4
|
+
class SectionPropertiesTest < Sablon::TestCase
|
5
|
+
include DocumentXMLHelper
|
6
|
+
|
7
|
+
def test_assign_start_page_number_with_pgNumType_tag
|
8
|
+
xml = wrap <<-documentxml
|
9
|
+
<w:body>
|
10
|
+
<w:sectPr w:rsidR="00FC1AFD" w:rsidSect="006745DF">
|
11
|
+
<w:pgSz w:w="11900" w:h="16840"/>
|
12
|
+
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="708" w:footer="708" w:gutter="0"/>
|
13
|
+
<w:pgNumType w:start="1"/>
|
14
|
+
<w:cols w:space="708"/>
|
15
|
+
<w:docGrid w:linePitch="360"/>
|
16
|
+
</w:sectPr>
|
17
|
+
</w:body>
|
18
|
+
documentxml
|
19
|
+
properties = Sablon::Processor::SectionProperties.from_document(xml)
|
20
|
+
assert_equal "1", properties.start_page_number
|
21
|
+
properties.start_page_number = "23"
|
22
|
+
assert_equal "23", properties.start_page_number
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_assign_start_page_number_without_pgNumType_tag
|
26
|
+
xml = wrap <<-documentxml
|
27
|
+
<w:body>
|
28
|
+
<w:sectPr w:rsidR="00FC1AFD" w:rsidSect="006745DF">
|
29
|
+
<w:pgSz w:w="11900" w:h="16840"/>
|
30
|
+
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="708" w:footer="708" w:gutter="0"/>
|
31
|
+
<w:cols w:space="708"/>
|
32
|
+
<w:docGrid w:linePitch="360"/>
|
33
|
+
</w:sectPr>
|
34
|
+
</w:body>
|
35
|
+
documentxml
|
36
|
+
properties = Sablon::Processor::SectionProperties.from_document(xml)
|
37
|
+
assert_equal nil, properties.start_page_number
|
38
|
+
properties.start_page_number = "16"
|
39
|
+
assert_equal "16", properties.start_page_number
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DocumentXMLHelper
|
2
|
+
def text(xml)
|
3
|
+
Nokogiri::XML(xml).text.gsub(/\s+/, " ").strip
|
4
|
+
end
|
5
|
+
|
6
|
+
def assert_xml_equal(expected, actual)
|
7
|
+
doc1 = XmlSimple.xml_in(document_xml(expected))
|
8
|
+
doc2 = XmlSimple.xml_in(actual)
|
9
|
+
assert_equal JSON.pretty_generate(doc1), JSON.pretty_generate(doc2)
|
10
|
+
end
|
11
|
+
|
12
|
+
def document_xml(content)
|
13
|
+
<<-documentxml
|
14
|
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
15
|
+
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14">
|
16
|
+
<w:body>
|
17
|
+
#{content}
|
18
|
+
</w:body>
|
19
|
+
</w:document>
|
20
|
+
documentxml
|
21
|
+
end
|
22
|
+
|
23
|
+
def wrap(xml)
|
24
|
+
Nokogiri::XML(document_xml(xml))
|
25
|
+
end
|
26
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
|
3
|
+
require "minitest/autorun"
|
4
|
+
require "minitest/mock"
|
5
|
+
require "xmlsimple"
|
6
|
+
require "json"
|
7
|
+
require "pathname"
|
8
|
+
|
9
|
+
$: << File.expand_path('../../lib', __FILE__)
|
10
|
+
require "sablon"
|
11
|
+
|
12
|
+
class Sablon::TestCase < MiniTest::Test
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sablon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yves Senn
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-30 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: '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
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubyzip
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.6'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: xml-simple
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Sablon is a document template processor. At this time it works only with
|
98
|
+
docx and MailMerge fields.
|
99
|
+
email:
|
100
|
+
- yves.senn@gmail.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".travis.yml"
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- lib/sablon.rb
|
112
|
+
- lib/sablon/operations.rb
|
113
|
+
- lib/sablon/parser/mail_merge.rb
|
114
|
+
- lib/sablon/processor.rb
|
115
|
+
- lib/sablon/processor/section_properties.rb
|
116
|
+
- lib/sablon/template.rb
|
117
|
+
- lib/sablon/version.rb
|
118
|
+
- sablon.gemspec
|
119
|
+
- test/expression_test.rb
|
120
|
+
- test/fixtures/sablon_sample.docx
|
121
|
+
- test/fixtures/sablon_template.docx
|
122
|
+
- test/mail_merge_parser_test.rb
|
123
|
+
- test/processor_test.rb
|
124
|
+
- test/sablon_test.rb
|
125
|
+
- test/sandbox/.gitkeep
|
126
|
+
- test/section_properties_test.rb
|
127
|
+
- test/support/document_xml_helper.rb
|
128
|
+
- test/test_helper.rb
|
129
|
+
homepage: http://github.com/senny/sablon
|
130
|
+
licenses:
|
131
|
+
- MIT
|
132
|
+
metadata: {}
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 2.2.2
|
150
|
+
signing_key:
|
151
|
+
specification_version: 4
|
152
|
+
summary: docx tempalte processor
|
153
|
+
test_files:
|
154
|
+
- test/expression_test.rb
|
155
|
+
- test/fixtures/sablon_sample.docx
|
156
|
+
- test/fixtures/sablon_template.docx
|
157
|
+
- test/mail_merge_parser_test.rb
|
158
|
+
- test/processor_test.rb
|
159
|
+
- test/sablon_test.rb
|
160
|
+
- test/sandbox/.gitkeep
|
161
|
+
- test/section_properties_test.rb
|
162
|
+
- test/support/document_xml_helper.rb
|
163
|
+
- test/test_helper.rb
|