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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/README.md +36 -5
  4. data/lib/sablon.rb +0 -3
  5. data/lib/sablon/configuration/html_tag.rb +1 -1
  6. data/lib/sablon/content.rb +56 -0
  7. data/lib/sablon/context.rb +2 -0
  8. data/lib/sablon/document_object_model/content_types.rb +35 -0
  9. data/lib/sablon/document_object_model/file_handler.rb +26 -0
  10. data/lib/sablon/document_object_model/model.rb +94 -0
  11. data/lib/sablon/document_object_model/numbering.rb +94 -0
  12. data/lib/sablon/document_object_model/relationships.rb +111 -0
  13. data/lib/sablon/environment.rb +13 -16
  14. data/lib/sablon/html/ast.rb +14 -13
  15. data/lib/sablon/html/ast_builder.rb +18 -5
  16. data/lib/sablon/html/node_properties.rb +3 -3
  17. data/lib/sablon/operations.rb +59 -0
  18. data/lib/sablon/processor/document.rb +48 -11
  19. data/lib/sablon/processor/section_properties.rb +11 -4
  20. data/lib/sablon/template.rb +88 -47
  21. data/lib/sablon/version.rb +1 -1
  22. data/misc/image-example.png +0 -0
  23. data/test/configuration_test.rb +22 -22
  24. data/test/content_test.rb +50 -0
  25. data/test/context_test.rb +37 -1
  26. data/test/environment_test.rb +4 -1
  27. data/test/executable_test.rb +0 -2
  28. data/test/fixtures/cv_sample.docx +0 -0
  29. data/test/fixtures/html_sample.docx +0 -0
  30. data/test/fixtures/images/c3po.jpg +0 -0
  31. data/test/fixtures/images/clone.jpg +0 -0
  32. data/test/fixtures/images/darth_vader.jpg +0 -0
  33. data/test/fixtures/images/r2d2.jpg +0 -0
  34. data/test/fixtures/images_sample.docx +0 -0
  35. data/test/fixtures/images_template.docx +0 -0
  36. data/test/fixtures/loops_sample.docx +0 -0
  37. data/test/fixtures/loops_template.docx +0 -0
  38. data/test/fixtures/recipe_sample.docx +0 -0
  39. data/test/fixtures/xml/image.xml +91 -0
  40. data/test/fixtures/xml/loop_with_unique_ids.xml +152 -0
  41. data/test/fixtures/xml/mock_document/word/document.xml +12 -0
  42. data/test/html/ast_test.rb +10 -5
  43. data/test/html/converter_style_test.rb +9 -9
  44. data/test/html/converter_test.rb +66 -81
  45. data/test/html/node_properties_test.rb +2 -2
  46. data/test/html_test.rb +2 -6
  47. data/test/processor/document_test.rb +80 -3
  48. data/test/processor/section_properties_test.rb +68 -0
  49. data/test/sablon_test.rb +77 -5
  50. data/test/test_helper.rb +109 -9
  51. metadata +33 -9
  52. data/lib/sablon/numbering.rb +0 -23
  53. data/lib/sablon/processor/numbering.rb +0 -47
  54. data/lib/sablon/relationship.rb +0 -47
  55. data/lib/sablon/test/assertions.rb +0 -22
  56. 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.1.1
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-01-09 00:00:00.000000000 Z
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.5.1
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
@@ -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
@@ -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