sablon 0.1.1 → 0.2.0

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