sablon 0.1.1 → 0.2.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/Gemfile.lock +2 -2
- data/README.md +36 -5
- data/lib/sablon.rb +0 -3
- data/lib/sablon/configuration/html_tag.rb +1 -1
- data/lib/sablon/content.rb +56 -0
- data/lib/sablon/context.rb +2 -0
- data/lib/sablon/document_object_model/content_types.rb +35 -0
- data/lib/sablon/document_object_model/file_handler.rb +26 -0
- data/lib/sablon/document_object_model/model.rb +94 -0
- data/lib/sablon/document_object_model/numbering.rb +94 -0
- data/lib/sablon/document_object_model/relationships.rb +111 -0
- data/lib/sablon/environment.rb +13 -16
- data/lib/sablon/html/ast.rb +14 -13
- data/lib/sablon/html/ast_builder.rb +18 -5
- data/lib/sablon/html/node_properties.rb +3 -3
- data/lib/sablon/operations.rb +59 -0
- data/lib/sablon/processor/document.rb +48 -11
- data/lib/sablon/processor/section_properties.rb +11 -4
- data/lib/sablon/template.rb +88 -47
- data/lib/sablon/version.rb +1 -1
- data/misc/image-example.png +0 -0
- data/test/configuration_test.rb +22 -22
- data/test/content_test.rb +50 -0
- data/test/context_test.rb +37 -1
- data/test/environment_test.rb +4 -1
- data/test/executable_test.rb +0 -2
- data/test/fixtures/cv_sample.docx +0 -0
- data/test/fixtures/html_sample.docx +0 -0
- data/test/fixtures/images/c3po.jpg +0 -0
- data/test/fixtures/images/clone.jpg +0 -0
- data/test/fixtures/images/darth_vader.jpg +0 -0
- data/test/fixtures/images/r2d2.jpg +0 -0
- data/test/fixtures/images_sample.docx +0 -0
- data/test/fixtures/images_template.docx +0 -0
- data/test/fixtures/loops_sample.docx +0 -0
- data/test/fixtures/loops_template.docx +0 -0
- data/test/fixtures/recipe_sample.docx +0 -0
- data/test/fixtures/xml/image.xml +91 -0
- data/test/fixtures/xml/loop_with_unique_ids.xml +152 -0
- data/test/fixtures/xml/mock_document/word/document.xml +12 -0
- data/test/html/ast_test.rb +10 -5
- data/test/html/converter_style_test.rb +9 -9
- data/test/html/converter_test.rb +66 -81
- data/test/html/node_properties_test.rb +2 -2
- data/test/html_test.rb +2 -6
- data/test/processor/document_test.rb +80 -3
- data/test/processor/section_properties_test.rb +68 -0
- data/test/sablon_test.rb +77 -5
- data/test/test_helper.rb +109 -9
- metadata +33 -9
- data/lib/sablon/numbering.rb +0 -23
- data/lib/sablon/processor/numbering.rb +0 -47
- data/lib/sablon/relationship.rb +0 -47
- data/lib/sablon/test/assertions.rb +0 -22
- data/test/section_properties_test.rb +0 -41
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sablon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yves Senn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -117,26 +117,28 @@ files:
|
|
117
117
|
- lib/sablon/configuration/html_tag.rb
|
118
118
|
- lib/sablon/content.rb
|
119
119
|
- lib/sablon/context.rb
|
120
|
+
- lib/sablon/document_object_model/content_types.rb
|
121
|
+
- lib/sablon/document_object_model/file_handler.rb
|
122
|
+
- lib/sablon/document_object_model/model.rb
|
123
|
+
- lib/sablon/document_object_model/numbering.rb
|
124
|
+
- lib/sablon/document_object_model/relationships.rb
|
120
125
|
- lib/sablon/environment.rb
|
121
126
|
- lib/sablon/html/ast.rb
|
122
127
|
- lib/sablon/html/ast_builder.rb
|
123
128
|
- lib/sablon/html/converter.rb
|
124
129
|
- lib/sablon/html/node_properties.rb
|
125
130
|
- lib/sablon/html/visitor.rb
|
126
|
-
- lib/sablon/numbering.rb
|
127
131
|
- lib/sablon/operations.rb
|
128
132
|
- lib/sablon/parser/mail_merge.rb
|
129
133
|
- lib/sablon/processor/document.rb
|
130
|
-
- lib/sablon/processor/numbering.rb
|
131
134
|
- lib/sablon/processor/section_properties.rb
|
132
|
-
- lib/sablon/relationship.rb
|
133
135
|
- lib/sablon/template.rb
|
134
136
|
- lib/sablon/test.rb
|
135
|
-
- lib/sablon/test/assertions.rb
|
136
137
|
- lib/sablon/version.rb
|
137
138
|
- misc/TEMPLATE.md
|
138
139
|
- misc/cv_sample.png
|
139
140
|
- misc/cv_template.png
|
141
|
+
- misc/image-example.png
|
140
142
|
- misc/recipe_sample.png
|
141
143
|
- misc/recipe_template.png
|
142
144
|
- misc/step_1.png
|
@@ -162,8 +164,16 @@ files:
|
|
162
164
|
- test/fixtures/cv_template.docx
|
163
165
|
- test/fixtures/html/html_test_content.html
|
164
166
|
- test/fixtures/html_sample.docx
|
167
|
+
- test/fixtures/images/c3po.jpg
|
168
|
+
- test/fixtures/images/clone.jpg
|
169
|
+
- test/fixtures/images/darth_vader.jpg
|
170
|
+
- test/fixtures/images/r2d2.jpg
|
171
|
+
- test/fixtures/images_sample.docx
|
172
|
+
- test/fixtures/images_template.docx
|
165
173
|
- test/fixtures/insertion_template.docx
|
166
174
|
- test/fixtures/insertion_template_no_styles.docx
|
175
|
+
- test/fixtures/loops_sample.docx
|
176
|
+
- test/fixtures/loops_template.docx
|
167
177
|
- test/fixtures/markdown_sample.docx
|
168
178
|
- test/fixtures/recipe_context.json
|
169
179
|
- test/fixtures/recipe_sample.docx
|
@@ -178,7 +188,10 @@ files:
|
|
178
188
|
- test/fixtures/xml/conditional_without_ending.xml
|
179
189
|
- test/fixtures/xml/corrupt_table.xml
|
180
190
|
- test/fixtures/xml/edited_complex_field.xml
|
191
|
+
- test/fixtures/xml/image.xml
|
192
|
+
- test/fixtures/xml/loop_with_unique_ids.xml
|
181
193
|
- test/fixtures/xml/loop_without_ending.xml
|
194
|
+
- test/fixtures/xml/mock_document/word/document.xml
|
182
195
|
- test/fixtures/xml/paragraph_loop.xml
|
183
196
|
- test/fixtures/xml/paragraph_loop_within_table_cell.xml
|
184
197
|
- test/fixtures/xml/simple_field.xml
|
@@ -195,9 +208,9 @@ files:
|
|
195
208
|
- test/html_test.rb
|
196
209
|
- test/mail_merge_parser_test.rb
|
197
210
|
- test/processor/document_test.rb
|
211
|
+
- test/processor/section_properties_test.rb
|
198
212
|
- test/sablon_test.rb
|
199
213
|
- test/sandbox/.gitkeep
|
200
|
-
- test/section_properties_test.rb
|
201
214
|
- test/support/document_xml_helper.rb
|
202
215
|
- test/support/html_snippets.rb
|
203
216
|
- test/support/xml_snippets.rb
|
@@ -222,7 +235,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
235
|
version: '0'
|
223
236
|
requirements: []
|
224
237
|
rubyforge_project:
|
225
|
-
rubygems_version: 2.
|
238
|
+
rubygems_version: 2.6.8
|
226
239
|
signing_key:
|
227
240
|
specification_version: 4
|
228
241
|
summary: docx template processor
|
@@ -239,8 +252,16 @@ test_files:
|
|
239
252
|
- test/fixtures/cv_template.docx
|
240
253
|
- test/fixtures/html/html_test_content.html
|
241
254
|
- test/fixtures/html_sample.docx
|
255
|
+
- test/fixtures/images/c3po.jpg
|
256
|
+
- test/fixtures/images/clone.jpg
|
257
|
+
- test/fixtures/images/darth_vader.jpg
|
258
|
+
- test/fixtures/images/r2d2.jpg
|
259
|
+
- test/fixtures/images_sample.docx
|
260
|
+
- test/fixtures/images_template.docx
|
242
261
|
- test/fixtures/insertion_template.docx
|
243
262
|
- test/fixtures/insertion_template_no_styles.docx
|
263
|
+
- test/fixtures/loops_sample.docx
|
264
|
+
- test/fixtures/loops_template.docx
|
244
265
|
- test/fixtures/markdown_sample.docx
|
245
266
|
- test/fixtures/recipe_context.json
|
246
267
|
- test/fixtures/recipe_sample.docx
|
@@ -255,7 +276,10 @@ test_files:
|
|
255
276
|
- test/fixtures/xml/conditional_without_ending.xml
|
256
277
|
- test/fixtures/xml/corrupt_table.xml
|
257
278
|
- test/fixtures/xml/edited_complex_field.xml
|
279
|
+
- test/fixtures/xml/image.xml
|
280
|
+
- test/fixtures/xml/loop_with_unique_ids.xml
|
258
281
|
- test/fixtures/xml/loop_without_ending.xml
|
282
|
+
- test/fixtures/xml/mock_document/word/document.xml
|
259
283
|
- test/fixtures/xml/paragraph_loop.xml
|
260
284
|
- test/fixtures/xml/paragraph_loop_within_table_cell.xml
|
261
285
|
- test/fixtures/xml/simple_field.xml
|
@@ -272,9 +296,9 @@ test_files:
|
|
272
296
|
- test/html_test.rb
|
273
297
|
- test/mail_merge_parser_test.rb
|
274
298
|
- test/processor/document_test.rb
|
299
|
+
- test/processor/section_properties_test.rb
|
275
300
|
- test/sablon_test.rb
|
276
301
|
- test/sandbox/.gitkeep
|
277
|
-
- test/section_properties_test.rb
|
278
302
|
- test/support/document_xml_helper.rb
|
279
303
|
- test/support/html_snippets.rb
|
280
304
|
- test/support/xml_snippets.rb
|
data/lib/sablon/numbering.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module Sablon
|
2
|
-
class Numbering
|
3
|
-
attr_reader :definitions
|
4
|
-
|
5
|
-
Definition = Struct.new(:numid, :style) do
|
6
|
-
def inspect
|
7
|
-
"#<Numbering #{numid}:#{style}"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@numid = 1000
|
13
|
-
@definitions = []
|
14
|
-
end
|
15
|
-
|
16
|
-
def register(style)
|
17
|
-
@numid += 1
|
18
|
-
definition = Definition.new(@numid, style)
|
19
|
-
@definitions << definition
|
20
|
-
definition
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
module Sablon
|
2
|
-
module Processor
|
3
|
-
class Numbering
|
4
|
-
LIST_DEFINITION = <<-XML.gsub(/^\s+/, '').tr("\n", '')
|
5
|
-
<w:num w:numId="%s">
|
6
|
-
<w:abstractNumId w:val="%s" />
|
7
|
-
</w:num>
|
8
|
-
XML
|
9
|
-
|
10
|
-
def self.process(doc, env)
|
11
|
-
processor = new(doc)
|
12
|
-
processor.manipulate env
|
13
|
-
doc
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(doc)
|
17
|
-
@doc = doc
|
18
|
-
end
|
19
|
-
|
20
|
-
def manipulate(env)
|
21
|
-
env.numbering.definitions.each do |definition|
|
22
|
-
abstract_num_ref = find_definition(definition.style)
|
23
|
-
abstract_num_copy = abstract_num_ref.dup
|
24
|
-
abstract_num_copy['w:abstractNumId'] = definition.numid
|
25
|
-
abstract_num_copy.xpath('./w:nsid').each(&:remove)
|
26
|
-
container.prepend_child abstract_num_copy
|
27
|
-
container.add_child(LIST_DEFINITION % [definition.numid, abstract_num_copy['w:abstractNumId']])
|
28
|
-
end
|
29
|
-
@doc
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
def container
|
34
|
-
@container ||= @doc.xpath('//w:numbering').first
|
35
|
-
end
|
36
|
-
|
37
|
-
def find_definition(style)
|
38
|
-
abstract_num = @doc.xpath("//w:abstractNum[descendant-or-self::*[w:pStyle[@w:val='#{style}']]]").first
|
39
|
-
if abstract_num
|
40
|
-
abstract_num
|
41
|
-
else
|
42
|
-
raise ArgumentError, "Could not find w:abstractNum definition for style: #{style.inspect}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
data/lib/sablon/relationship.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
module Sablon
|
2
|
-
# Handles storing referenced relationships in the document.xml file and
|
3
|
-
# writing them to the document.xml.rels file
|
4
|
-
class Relationship
|
5
|
-
attr_accessor :relationships
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@relationships = []
|
9
|
-
end
|
10
|
-
|
11
|
-
def add_found_relationships(content, output_stream)
|
12
|
-
output_stream.put_next_entry('word/_rels/document.xml.rels')
|
13
|
-
#
|
14
|
-
unless @relationships.empty?
|
15
|
-
rels_doc = Nokogiri::XML(content)
|
16
|
-
rels_doc_root = rels_doc.root
|
17
|
-
# convert new rels to nodes
|
18
|
-
node_set = convert_relationships_to_node_set(rels_doc)
|
19
|
-
@relationships = []
|
20
|
-
# add new nodes to XML content
|
21
|
-
rels_doc_root.last_element_child.after(node_set)
|
22
|
-
content = rels_doc.to_xml(indent: 0, save_with: 0)
|
23
|
-
end
|
24
|
-
#
|
25
|
-
output_stream.write(content)
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
# Builds a set of Relationship XML nodes from the stored relationships
|
31
|
-
def convert_relationships_to_node_set(doc)
|
32
|
-
node_set = Nokogiri::XML::NodeSet.new(doc)
|
33
|
-
@relationships.each do |relationship|
|
34
|
-
rel_tag = "<Relationship#{relationship_attributes(relationship)}/>"
|
35
|
-
node_set << Nokogiri::XML.fragment(rel_tag).children.first
|
36
|
-
end
|
37
|
-
#
|
38
|
-
node_set
|
39
|
-
end
|
40
|
-
|
41
|
-
# Builds the attribute string for the relationship XML node
|
42
|
-
def relationship_attributes(relationship)
|
43
|
-
return '' if relationship.nil? || relationship.empty?
|
44
|
-
' ' + relationship.map { |k, v| %(#{k}="#{v}") }.join(' ')
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Sablon
|
2
|
-
module Test
|
3
|
-
module Assertions
|
4
|
-
def assert_docx_equal(expected_path, actual_path)
|
5
|
-
if get_document_xml(expected_path) != get_document_xml(actual_path)
|
6
|
-
msg = <<-error
|
7
|
-
The generated document does not match the sample. Please investigate.
|
8
|
-
|
9
|
-
If the generated document is correct, the sample needs to be updated:
|
10
|
-
\t cp #{actual_path} #{expected_path}
|
11
|
-
error
|
12
|
-
fail msg
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def get_document_xml(path)
|
17
|
-
document_xml_entry = Zip::File.open(path).get_entry("word/document.xml")
|
18
|
-
document_xml_entry.get_input_stream.read
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,41 +0,0 @@
|
|
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_nil properties.start_page_number
|
38
|
-
properties.start_page_number = "16"
|
39
|
-
assert_equal "16", properties.start_page_number
|
40
|
-
end
|
41
|
-
end
|