sheng 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.gitignore +18 -0
  4. data/.rspec +3 -0
  5. data/.ruby-version +1 -0
  6. data/.watchr +99 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +62 -0
  10. data/Rakefile +10 -0
  11. data/docs/creating_templates.docx +0 -0
  12. data/docs/creating_templates.md +392 -0
  13. data/lib/sheng/block.rb +59 -0
  14. data/lib/sheng/check_box.rb +43 -0
  15. data/lib/sheng/conditional_block.rb +30 -0
  16. data/lib/sheng/data_set.rb +45 -0
  17. data/lib/sheng/docx.rb +75 -0
  18. data/lib/sheng/merge_field.rb +208 -0
  19. data/lib/sheng/merge_field_set.rb +90 -0
  20. data/lib/sheng/path_helpers.rb +15 -0
  21. data/lib/sheng/sequence.rb +66 -0
  22. data/lib/sheng/support.rb +57 -0
  23. data/lib/sheng/version.rb +3 -0
  24. data/lib/sheng/wml_file.rb +47 -0
  25. data/lib/sheng.rb +21 -0
  26. data/sheng.gemspec +31 -0
  27. data/spec/fixtures/bad_docx_files/with_field_not_in_dataset.docx +0 -0
  28. data/spec/fixtures/bad_docx_files/with_missing_sequence_start.docx +0 -0
  29. data/spec/fixtures/bad_docx_files/with_old_mergefields.docx +0 -0
  30. data/spec/fixtures/bad_docx_files/with_poorly_nested_sequences.docx +0 -0
  31. data/spec/fixtures/bad_docx_files/with_unended_sequence.docx +0 -0
  32. data/spec/fixtures/docx_files/input_document.docx +0 -0
  33. data/spec/fixtures/docx_files/old_style/input_document.docx +0 -0
  34. data/spec/fixtures/docx_files/old_style/output_document.docx +0 -0
  35. data/spec/fixtures/docx_files/output_document.docx +0 -0
  36. data/spec/fixtures/inputs/complete.json +61 -0
  37. data/spec/fixtures/inputs/incomplete.json +52 -0
  38. data/spec/fixtures/trees/embedded_sequence.yml +13 -0
  39. data/spec/fixtures/trees/merge_field_set.yml +16 -0
  40. data/spec/fixtures/xml_fragments/input/check_box/check_box.xml +11 -0
  41. data/spec/fixtures/xml_fragments/input/conditional_block/bad/badly_nested_conditional.xml +105 -0
  42. data/spec/fixtures/xml_fragments/input/conditional_block/bad/unclosed_conditional.xml +35 -0
  43. data/spec/fixtures/xml_fragments/input/conditional_block/conditional_block_if.xml +84 -0
  44. data/spec/fixtures/xml_fragments/input/conditional_block/conditional_block_inline.xml +59 -0
  45. data/spec/fixtures/xml_fragments/input/conditional_block/conditional_block_unless.xml +51 -0
  46. data/spec/fixtures/xml_fragments/input/conditional_block/conditional_in_table.xml +176 -0
  47. data/spec/fixtures/xml_fragments/input/conditional_block/embedded_conditional.xml +79 -0
  48. data/spec/fixtures/xml_fragments/input/merge_field/bad/not_a_real_mergefield_new.xml +19 -0
  49. data/spec/fixtures/xml_fragments/input/merge_field/bad/not_a_real_mergefield_old.xml +9 -0
  50. data/spec/fixtures/xml_fragments/input/merge_field/bad/unclosed_merge_field.xml +25 -0
  51. data/spec/fixtures/xml_fragments/input/merge_field/inline_merge_field.xml +26 -0
  52. data/spec/fixtures/xml_fragments/input/merge_field/merge_field.xml +14 -0
  53. data/spec/fixtures/xml_fragments/input/merge_field/new_merge_field.xml +28 -0
  54. data/spec/fixtures/xml_fragments/input/merge_field/split_merge_field.xml +33 -0
  55. data/spec/fixtures/xml_fragments/input/merge_field_set/complex_nesting_and_reuse.xml +231 -0
  56. data/spec/fixtures/xml_fragments/input/merge_field_set/merge_field_set.xml +89 -0
  57. data/spec/fixtures/xml_fragments/input/merge_field_set/with_non_mergefield_fields.xml +43 -0
  58. data/spec/fixtures/xml_fragments/input/sequence/array_sequence.xml +23 -0
  59. data/spec/fixtures/xml_fragments/input/sequence/bad/badly_nested_sequence.xml +62 -0
  60. data/spec/fixtures/xml_fragments/input/sequence/bad/unclosed_sequence.xml +32 -0
  61. data/spec/fixtures/xml_fragments/input/sequence/embedded_sequence.xml +68 -0
  62. data/spec/fixtures/xml_fragments/input/sequence/inline_sequence.xml +24 -0
  63. data/spec/fixtures/xml_fragments/input/sequence/overridden_iterator_array_sequence.xml +23 -0
  64. data/spec/fixtures/xml_fragments/input/sequence/sequence.xml +39 -0
  65. data/spec/fixtures/xml_fragments/input/sequence/sequence_in_table.xml +125 -0
  66. data/spec/fixtures/xml_fragments/input/sequence/sequence_with_section_formatting.xml +41 -0
  67. data/spec/fixtures/xml_fragments/input/sequence/series_with_commas.xml +73 -0
  68. data/spec/fixtures/xml_fragments/output/check_box/check_box.xml +11 -0
  69. data/spec/fixtures/xml_fragments/output/conditional_block/conditional_in_table_does_not_exist.xml +52 -0
  70. data/spec/fixtures/xml_fragments/output/conditional_block/conditional_in_table_exists.xml +84 -0
  71. data/spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_both.xml +11 -0
  72. data/spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_inside.xml +5 -0
  73. data/spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_outside.xml +8 -0
  74. data/spec/fixtures/xml_fragments/output/conditional_block/if_does_not_exist.xml +5 -0
  75. data/spec/fixtures/xml_fragments/output/conditional_block/if_exists.xml +19 -0
  76. data/spec/fixtures/xml_fragments/output/conditional_block/inline_does_not_exist.xml +10 -0
  77. data/spec/fixtures/xml_fragments/output/conditional_block/inline_exists.xml +13 -0
  78. data/spec/fixtures/xml_fragments/output/conditional_block/unless_does_not_exist.xml +11 -0
  79. data/spec/fixtures/xml_fragments/output/conditional_block/unless_exists.xml +5 -0
  80. data/spec/fixtures/xml_fragments/output/merge_field/inline_merge_field.xml +11 -0
  81. data/spec/fixtures/xml_fragments/output/merge_field/merge_field.xml +12 -0
  82. data/spec/fixtures/xml_fragments/output/merge_field/split_merge_field.xml +10 -0
  83. data/spec/fixtures/xml_fragments/output/merge_field_set/complex_nesting_and_reuse.xml +190 -0
  84. data/spec/fixtures/xml_fragments/output/merge_field_set/merge_field_set.xml +75 -0
  85. data/spec/fixtures/xml_fragments/output/merge_field_set/with_non_mergefield_fields.xml +31 -0
  86. data/spec/fixtures/xml_fragments/output/sequence/array_sequence.xml +17 -0
  87. data/spec/fixtures/xml_fragments/output/sequence/embedded_sequence.xml +56 -0
  88. data/spec/fixtures/xml_fragments/output/sequence/inline_sequence.xml +16 -0
  89. data/spec/fixtures/xml_fragments/output/sequence/overridden_iterator_array_sequence.xml +12 -0
  90. data/spec/fixtures/xml_fragments/output/sequence/sequence.xml +28 -0
  91. data/spec/fixtures/xml_fragments/output/sequence/sequence_in_table.xml +120 -0
  92. data/spec/fixtures/xml_fragments/output/sequence/sequence_with_section_formatting.xml +46 -0
  93. data/spec/fixtures/xml_fragments/output/sequence/series_with_commas.xml +43 -0
  94. data/spec/fixtures/xml_fragments/output/sequence/series_with_commas_two_items.xml +31 -0
  95. data/spec/lib/sheng/check_box_spec.rb +87 -0
  96. data/spec/lib/sheng/conditional_block_spec.rb +151 -0
  97. data/spec/lib/sheng/data_set_spec.rb +65 -0
  98. data/spec/lib/sheng/docx_spec.rb +146 -0
  99. data/spec/lib/sheng/merge_field_set_spec.rb +165 -0
  100. data/spec/lib/sheng/merge_field_spec.rb +276 -0
  101. data/spec/lib/sheng/sequence_spec.rb +201 -0
  102. data/spec/lib/sheng/wml_file_spec.rb +38 -0
  103. data/spec/spec_helper.rb +16 -0
  104. data/spec/support/path_helper.rb +15 -0
  105. data/spec/support/xml_helper.rb +28 -0
  106. metadata +355 -0
@@ -0,0 +1,47 @@
1
+ module Sheng
2
+ class WMLFile
3
+ class InvalidWML < StandardError; end
4
+ class MergefieldNotReplacedError < StandardError
5
+ def initialize(unmerged_fields)
6
+ unmerged_keys = unmerged_fields.map(&:raw_key)
7
+ super("Mergefields not replaced: #{unmerged_keys.join(', ')}")
8
+ end
9
+ end
10
+
11
+ attr_reader :xml, :filename
12
+
13
+ def initialize(filename, xml)
14
+ @filename = filename
15
+ @xml = Nokogiri::XML(xml)
16
+ end
17
+
18
+ def interpolate(data_set)
19
+ parent_set.interpolate(data_set)
20
+ check_for_full_interpolation!
21
+ parent_set.xml_fragment.to_s
22
+ end
23
+
24
+ def check_for_full_interpolation!
25
+ modified_parent_set = MergeFieldSet.new('main', xml)
26
+ unmerged_fields = modified_parent_set.basic_nodes.reject { |node|
27
+ node.is_a?(CheckBox)
28
+ }
29
+
30
+ unless unmerged_fields.empty?
31
+ raise MergefieldNotReplacedError.new(unmerged_fields)
32
+ end
33
+ end
34
+
35
+ def parent_set
36
+ @parent_set ||= MergeFieldSet.new('main', xml)
37
+ end
38
+
39
+ def required_hash
40
+ parent_set.required_hash
41
+ end
42
+
43
+ def to_tree
44
+ parent_set.to_tree
45
+ end
46
+ end
47
+ end
data/lib/sheng.rb ADDED
@@ -0,0 +1,21 @@
1
+
2
+ require 'active_support/inflector'
3
+ require 'active_support/core_ext/hash'
4
+ require 'sheng/support'
5
+ require 'sheng/version'
6
+ require 'sheng/data_set'
7
+ require 'sheng/docx'
8
+ require 'sheng/wml_file'
9
+ require 'sheng/merge_field_set'
10
+ require 'sheng/merge_field'
11
+ require 'sheng/sequence'
12
+ require 'sheng/conditional_block'
13
+ require 'sheng/check_box'
14
+
15
+ require 'zip'
16
+ require 'nokogiri'
17
+ require 'fileutils'
18
+ require 'json'
19
+
20
+ module Sheng
21
+ end
data/sheng.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sheng/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sheng"
8
+ spec.version = Sheng::VERSION
9
+ spec.authors = ["Ravi Gadad", "Maher Hawash"]
10
+ spec.email = ["ravi@renewfund.com"]
11
+ spec.description = "A Ruby gem for data merging Word documents."
12
+ spec.summary = "A Ruby gem for data merging Word documents, using native MergeFields as placeholders in templates, and a Ruby hash as the data set for substitution."
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+ spec.add_development_dependency "equivalent-xml", ">= 0.6"
25
+ spec.add_development_dependency "pry"
26
+ spec.add_development_dependency "simplecov"
27
+
28
+ spec.add_dependency "nokogiri", "~> 1.6"
29
+ spec.add_dependency "rubyzip", "~> 1.1.1"
30
+ spec.add_dependency "activesupport", "~> 4.2"
31
+ end
@@ -0,0 +1,61 @@
1
+ {
2
+ "account_identifier": "XYZ-0999223c",
3
+ "first_name": "Bobby",
4
+ "last_name": "McGee",
5
+ "a_long_paragraph": "Pede erat feugiat ante, auctor facilisis dui augue non turpis. Suspendisse mattis metus et justo. Aliquam erat volutpat. Suspendisse potenti. Nam hendrerit lorem commodo metus laoreet ullamcorper. Proin vel nunc a felis sollicitudin pretium. Maecenas in metus at mi mollis posuere. Quisque ac quam sed massa adipiscing rutrum. Vestibulum ipsum. Phasellus porta sapien. Maecenas venenatis tellus vel tellus.\n\n Aliquam aliquam dolor at justo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi pretium purus a magna. Nullam dui tellus, blandit eu, facilisis non, pharetra consectetuer, leo. Maecenas sit amet ante sagittis magna imperdiet pulvinar. Vestibulum a lacus at.",
6
+ "check_me": "true",
7
+ "leave_me_unchecked": "false",
8
+ "embedded": {
9
+ "first_level": "shallow",
10
+ "two_levels": {
11
+ "second_level": "deep"
12
+ }
13
+ },
14
+ "meals": [
15
+ {
16
+ "meal": "sHrImP",
17
+ "drink": "tea",
18
+ "dessert": "kanafa",
19
+ "appetizer": "lettuce"
20
+ },
21
+ {
22
+ "meal": "fish",
23
+ "drink": "coffee",
24
+ "dessert": "baklava",
25
+ "appetizer": "cheese cakes are really yummy"
26
+ }
27
+ ],
28
+ "owners": [
29
+ {
30
+ "first_name": "Bob",
31
+ "last_name": "Jones"
32
+ },
33
+ {
34
+ "first_name": "Sally",
35
+ "last_name": "Fields"
36
+ }
37
+ ],
38
+ "frogs": [
39
+ {
40
+ "first_name": "Bill",
41
+ "last_name": "Jones"
42
+ },
43
+ {
44
+ "first_name": "Sam",
45
+ "last_name": "Fields"
46
+ }
47
+ ],
48
+ "animals": [
49
+ { "color": "blue"}
50
+ ],
51
+ "birds": [
52
+ { "wingspan": "amazing"}
53
+ ],
54
+ "exceptions": [],
55
+ "grocery_list": [
56
+ { "quantity": 4, "product": "bananas" },
57
+ { "quantity": "3 cups", "product": "sugar" }
58
+ ],
59
+ "invitees": ["Brad", "Ulisha", "Marcionette"],
60
+ "potluck_dishes": ["Salad", "Croutons", "Dressing", "Radishes"]
61
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "account_identifier": "XYZ-0999223c",
3
+ "a_long_paragraph": "Pede erat feugiat ante, auctor facilisis dui augue non turpis. Suspendisse mattis metus et justo. Aliquam erat volutpat. Suspendisse potenti. Nam hendrerit lorem commodo metus laoreet ullamcorper. Proin vel nunc a felis sollicitudin pretium. Maecenas in metus at mi mollis posuere. Quisque ac quam sed massa adipiscing rutrum. Vestibulum ipsum. Phasellus porta sapien. Maecenas venenatis tellus vel tellus.\n\n Aliquam aliquam dolor at justo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi pretium purus a magna. Nullam dui tellus, blandit eu, facilisis non, pharetra consectetuer, leo. Maecenas sit amet ante sagittis magna imperdiet pulvinar. Vestibulum a lacus at.",
4
+ "check_me": "true",
5
+ "leave_me_unchecked": "false",
6
+ "embedded": {
7
+ "first_level": "shallow",
8
+ "two_levels": {
9
+ "second_level": "deep"
10
+ }
11
+ },
12
+ "meals": [
13
+ {
14
+ "meal": "sHrImP",
15
+ "drink": "tea",
16
+ "dessert": "kanafa",
17
+ "appetizer": "lettuce"
18
+ },
19
+ {
20
+ "meal": "fish",
21
+ "drink": "coffee",
22
+ "dessert": "baklava",
23
+ "appetizer": "cheese cakes are really yummy"
24
+ }
25
+ ],
26
+ "owners": [
27
+ {
28
+ "first_name": "Bob",
29
+ "last_name": "Jones"
30
+ },
31
+ {
32
+ "first_name": "Sally",
33
+ "last_name": "Fields"
34
+ }
35
+ ],
36
+ "frogs": [
37
+ {
38
+ "first_name": "Bill",
39
+ "last_name": "Jones"
40
+ },
41
+ {
42
+ "first_name": "Sam",
43
+ "last_name": "Fields"
44
+ }
45
+ ],
46
+ "grocery_list": [
47
+ { "quantity": 4, "product": "bananas" },
48
+ { "quantity": "3 cups", "product": "sugar" }
49
+ ],
50
+ "invitees": ["Brad", "Ulisha", "Marcionette"],
51
+ "potluck_dishes": ["Salad", "Croutons", "Dressing", "Radishes"]
52
+ }
@@ -0,0 +1,13 @@
1
+ ---
2
+ - :type: sequence
3
+ :key: start:library.books
4
+ :nodes:
5
+ - :type: merge_field
6
+ :key: title
7
+ - :type: sequence
8
+ :key: start:pages
9
+ :nodes:
10
+ - :type: merge_field
11
+ :key: size
12
+ - :type: merge_field
13
+ :key: scent
@@ -0,0 +1,16 @@
1
+ ---
2
+ - :type: merge_field
3
+ :key: person.first_name
4
+ - :type: merge_field
5
+ :key: person.last_name | upcase
6
+ - :type: sequence
7
+ :key: start:person.socks
8
+ :nodes:
9
+ - :type: merge_field
10
+ :key: color
11
+ - :type: merge_field
12
+ :key: size
13
+ - :type: check_box
14
+ :key: veggies.green.spinach
15
+ - :type: merge_field
16
+ :key: person.first_name
@@ -0,0 +1,11 @@
1
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
2
+ <w:ffData>
3
+ <w:name w:val="goats"/>
4
+ <w:enabled/>
5
+ <w:calcOnExit w:val="0"/>
6
+ <w:checkBox>
7
+ <w:sizeAuto/>
8
+ <w:default w:val="0"/>
9
+ </w:checkBox>
10
+ </w:ffData>
11
+ </w:document>
@@ -0,0 +1,105 @@
1
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
2
+ <w:r>
3
+ <w:t>What we gots?</w:t>
4
+ </w:r>
5
+ <w:p>
6
+ <w:r>
7
+ <w:fldChar w:fldCharType="begin"/>
8
+ </w:r>
9
+ <w:r>
10
+ <w:instrText xml:space="preserve">MERGEFIELD if:alicorns \* MERGEFORMAT </w:instrText>
11
+ </w:r>
12
+ <w:r>
13
+ <w:fldChar w:fldCharType="separate"/>
14
+ </w:r>
15
+ <w:r>
16
+ <w:rPr>
17
+ <w:b/>
18
+ <w:i/>
19
+ <w:noProof/>
20
+ </w:rPr>
21
+ <w:t>«if:alicorns»</w:t>
22
+ </w:r>
23
+ <w:r>
24
+ <w:rPr>
25
+ <w:noProof/>
26
+ </w:rPr>
27
+ <w:fldChar w:fldCharType="end"/>
28
+ </w:r>
29
+ </w:p>
30
+ <w:p>
31
+ <w:r>
32
+ <w:fldChar w:fldCharType="begin"/>
33
+ </w:r>
34
+ <w:r>
35
+ <w:instrText xml:space="preserve">MERGEFIELD unless:pumpkins \* MERGEFORMAT </w:instrText>
36
+ </w:r>
37
+ <w:r>
38
+ <w:fldChar w:fldCharType="separate"/>
39
+ </w:r>
40
+ <w:r>
41
+ <w:rPr>
42
+ <w:b/>
43
+ <w:i/>
44
+ <w:noProof/>
45
+ </w:rPr>
46
+ <w:t>«unless:pumpkins»</w:t>
47
+ </w:r>
48
+ <w:r>
49
+ <w:rPr>
50
+ <w:noProof/>
51
+ </w:rPr>
52
+ <w:fldChar w:fldCharType="end"/>
53
+ </w:r>
54
+ </w:p>
55
+ <w:p>
56
+ <w:r>
57
+ <w:fldChar w:fldCharType="begin"/>
58
+ </w:r>
59
+ <w:r>
60
+ <w:instrText xml:space="preserve">MERGEFIELD end_if:alicorns \* MERGEFORMAT </w:instrText>
61
+ </w:r>
62
+ <w:r>
63
+ <w:fldChar w:fldCharType="separate"/>
64
+ </w:r>
65
+ <w:r>
66
+ <w:rPr>
67
+ <w:b/>
68
+ <w:i/>
69
+ <w:noProof/>
70
+ </w:rPr>
71
+ <w:t>«end_if:alicorns»</w:t>
72
+ </w:r>
73
+ <w:r>
74
+ <w:rPr>
75
+ <w:noProof/>
76
+ </w:rPr>
77
+ <w:fldChar w:fldCharType="end"/>
78
+ </w:r>
79
+ </w:p>
80
+ <w:p>
81
+ <w:r>
82
+ <w:fldChar w:fldCharType="begin"/>
83
+ </w:r>
84
+ <w:r>
85
+ <w:instrText xml:space="preserve">MERGEFIELD end_unless:pumpkins \* MERGEFORMAT </w:instrText>
86
+ </w:r>
87
+ <w:r>
88
+ <w:fldChar w:fldCharType="separate"/>
89
+ </w:r>
90
+ <w:r>
91
+ <w:rPr>
92
+ <w:b/>
93
+ <w:i/>
94
+ <w:noProof/>
95
+ </w:rPr>
96
+ <w:t>«end_unless:pumpkins»</w:t>
97
+ </w:r>
98
+ <w:r>
99
+ <w:rPr>
100
+ <w:noProof/>
101
+ </w:rPr>
102
+ <w:fldChar w:fldCharType="end"/>
103
+ </w:r>
104
+ </w:p>
105
+ </w:document>
@@ -0,0 +1,35 @@
1
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
2
+ <w:p>
3
+ <w:r>
4
+ <w:fldChar w:fldCharType="begin"/>
5
+ </w:r>
6
+ <w:r>
7
+ <w:instrText xml:space="preserve">MERGEFIELD if:alicorns \* MERGEFORMAT </w:instrText>
8
+ </w:r>
9
+ <w:r>
10
+ <w:fldChar w:fldCharType="separate"/>
11
+ </w:r>
12
+ <w:r>
13
+ <w:rPr>
14
+ <w:b/>
15
+ <w:i/>
16
+ <w:noProof/>
17
+ </w:rPr>
18
+ <w:t>«if:alicorns»</w:t>
19
+ </w:r>
20
+ <w:r>
21
+ <w:rPr>
22
+ <w:noProof/>
23
+ </w:rPr>
24
+ <w:fldChar w:fldCharType="end"/>
25
+ </w:r>
26
+ </w:p>
27
+ <w:r>
28
+ <w:rPr>
29
+ <w:b/>
30
+ <w:i/>
31
+ <w:noProof/>
32
+ </w:rPr>
33
+ <w:t xml:space="preserve">Oh phew, alicorns. They are </w:t>
34
+ </w:r>
35
+ </w:document>
@@ -0,0 +1,84 @@
1
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
2
+ <w:r>
3
+ <w:t>What we gots?</w:t>
4
+ </w:r>
5
+ <w:p>
6
+ <w:r>
7
+ <w:fldChar w:fldCharType="begin"/>
8
+ </w:r>
9
+ <w:r>
10
+ <w:instrText xml:space="preserve">MERGEFIELD if:alicorns \* MERGEFORMAT </w:instrText>
11
+ </w:r>
12
+ <w:r>
13
+ <w:fldChar w:fldCharType="separate"/>
14
+ </w:r>
15
+ <w:r>
16
+ <w:rPr>
17
+ <w:b/>
18
+ <w:i/>
19
+ <w:noProof/>
20
+ </w:rPr>
21
+ <w:t>«if:alicorns»</w:t>
22
+ </w:r>
23
+ <w:r>
24
+ <w:rPr>
25
+ <w:noProof/>
26
+ </w:rPr>
27
+ <w:fldChar w:fldCharType="end"/>
28
+ </w:r>
29
+ </w:p>
30
+ <w:r>
31
+ <w:rPr>
32
+ <w:b/>
33
+ <w:i/>
34
+ <w:noProof/>
35
+ </w:rPr>
36
+ <w:t xml:space="preserve">Oh phew, alicorns. They are </w:t>
37
+ </w:r>
38
+ <w:r>
39
+ <w:fldChar w:fldCharType="begin"/>
40
+ </w:r>
41
+ <w:r>
42
+ <w:instrText xml:space="preserve">MERGEFIELD alicorns \* MERGEFORMAT </w:instrText>
43
+ </w:r>
44
+ <w:r>
45
+ <w:fldChar w:fldCharType="separate"/>
46
+ </w:r>
47
+ <w:r>
48
+ <w:rPr>
49
+ <w:noProof/>
50
+ </w:rPr>
51
+ <w:t>«alicorns»</w:t>
52
+ </w:r>
53
+ <w:r w:rsidR="00FD21FA">
54
+ <w:rPr>
55
+ <w:noProof/>
56
+ </w:rPr>
57
+ <w:fldChar w:fldCharType="end"/>
58
+ </w:r>
59
+ <w:p>
60
+ <w:r>
61
+ <w:fldChar w:fldCharType="begin"/>
62
+ </w:r>
63
+ <w:r>
64
+ <w:instrText xml:space="preserve">MERGEFIELD end_if:alicorns \* MERGEFORMAT </w:instrText>
65
+ </w:r>
66
+ <w:r>
67
+ <w:fldChar w:fldCharType="separate"/>
68
+ </w:r>
69
+ <w:r>
70
+ <w:rPr>
71
+ <w:b/>
72
+ <w:i/>
73
+ <w:noProof/>
74
+ </w:rPr>
75
+ <w:t>«end_if:alicorns»</w:t>
76
+ </w:r>
77
+ <w:r>
78
+ <w:rPr>
79
+ <w:noProof/>
80
+ </w:rPr>
81
+ <w:fldChar w:fldCharType="end"/>
82
+ </w:r>
83
+ </w:p>
84
+ </w:document>
@@ -0,0 +1,59 @@
1
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
2
+ <w:p>
3
+ <w:r>
4
+ <w:t xml:space="preserve">Let me tell you a story. </w:t>
5
+ </w:r>
6
+ <w:r>
7
+ <w:fldChar w:fldCharType="begin"/>
8
+ </w:r>
9
+ <w:r>
10
+ <w:instrText xml:space="preserve">MERGEFIELD if:alicorns \* MERGEFORMAT </w:instrText>
11
+ </w:r>
12
+ <w:r>
13
+ <w:fldChar w:fldCharType="separate"/>
14
+ </w:r>
15
+ <w:r>
16
+ <w:rPr>
17
+ <w:b/>
18
+ <w:i/>
19
+ <w:noProof/>
20
+ </w:rPr>
21
+ <w:t>«if:alicorns»</w:t>
22
+ </w:r>
23
+ <w:r>
24
+ <w:rPr>
25
+ <w:noProof/>
26
+ </w:rPr>
27
+ <w:fldChar w:fldCharType="end"/>
28
+ </w:r>
29
+ <w:r>
30
+ <w:t xml:space="preserve">It will have alicorns in it. </w:t>
31
+ </w:r>
32
+ <w:r>
33
+ <w:fldChar w:fldCharType="begin"/>
34
+ </w:r>
35
+ <w:r>
36
+ <w:instrText xml:space="preserve">MERGEFIELD end_if:alicorns \* MERGEFORMAT </w:instrText>
37
+ </w:r>
38
+ <w:r>
39
+ <w:fldChar w:fldCharType="separate"/>
40
+ </w:r>
41
+ <w:r>
42
+ <w:rPr>
43
+ <w:b/>
44
+ <w:i/>
45
+ <w:noProof/>
46
+ </w:rPr>
47
+ <w:t>«end_if:alicorns»</w:t>
48
+ </w:r>
49
+ <w:r>
50
+ <w:rPr>
51
+ <w:noProof/>
52
+ </w:rPr>
53
+ <w:fldChar w:fldCharType="end"/>
54
+ </w:r>
55
+ <w:r>
56
+ <w:t>Isn't that exciting?</w:t>
57
+ </w:r>
58
+ </w:p>
59
+ </w:document>
@@ -0,0 +1,51 @@
1
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
2
+ <w:r>
3
+ <w:t>What we don't gots?</w:t>
4
+ </w:r>
5
+ <w:p>
6
+ <w:r>
7
+ <w:fldChar w:fldCharType="begin"/>
8
+ </w:r>
9
+ <w:r>
10
+ <w:instrText xml:space="preserve">MERGEFIELD unless:alicorns \* MERGEFORMAT </w:instrText>
11
+ </w:r>
12
+ <w:r>
13
+ <w:fldChar w:fldCharType="separate"/>
14
+ </w:r>
15
+ <w:r>
16
+ <w:t>«unless:alicorns»</w:t>
17
+ </w:r>
18
+ <w:r>
19
+ <w:rPr>
20
+ <w:noProof/>
21
+ </w:rPr>
22
+ <w:fldChar w:fldCharType="end"/>
23
+ </w:r>
24
+ </w:p>
25
+ <w:r>
26
+ <w:rPr>
27
+ <w:i/>
28
+ </w:rPr>
29
+ <w:t>No alicorns? SADFACES</w:t>
30
+ </w:r>
31
+ <w:p>
32
+ <w:r>
33
+ <w:fldChar w:fldCharType="begin"/>
34
+ </w:r>
35
+ <w:r>
36
+ <w:instrText xml:space="preserve">MERGEFIELD end_unless:alicorns \* MERGEFORMAT </w:instrText>
37
+ </w:r>
38
+ <w:r>
39
+ <w:fldChar w:fldCharType="separate"/>
40
+ </w:r>
41
+ <w:r>
42
+ <w:t>«end_unless:alicorns»</w:t>
43
+ </w:r>
44
+ <w:r>
45
+ <w:rPr>
46
+ <w:noProof/>
47
+ </w:rPr>
48
+ <w:fldChar w:fldCharType="end"/>
49
+ </w:r>
50
+ </w:p>
51
+ </w:document>