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,201 @@
1
+ describe Sheng::Sequence do
2
+ let(:fragment) { xml_fragment('input/sequence/sequence') }
3
+ let(:element) { fragment.xpath("//w:fldSimple[contains(@w:instr, 'start:')]").first }
4
+ let(:merge_field) { Sheng::MergeField.new(element) }
5
+ subject { described_class.new(merge_field) }
6
+
7
+ describe "#raw_key" do
8
+ it "returns key from start_field" do
9
+ expect(subject.raw_key).to eq(merge_field.raw_key)
10
+ end
11
+ end
12
+
13
+ describe '#interpolate' do
14
+ context "with an array of objects" do
15
+ it 'duplicates template and replaces mergefields for each array member' do
16
+ dataset = Sheng::DataSet.new({
17
+ :library => {
18
+ :books => [
19
+ { :title => 'A Radish Summer', :scent => 'totally rad' },
20
+ { :title => 'Elephants Are Not Your Friend', :scent => 'stinky' }
21
+ ]
22
+ }
23
+ })
24
+
25
+ subject.interpolate(dataset)
26
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/sequence')
27
+ end
28
+
29
+ it 'does nothing if key not found in dataset' do
30
+ dataset = Sheng::DataSet.new({})
31
+
32
+ subject.interpolate(dataset)
33
+ expect(subject.xml_document).to be_equivalent_to fragment
34
+ end
35
+ end
36
+
37
+ context "with an array of primitives" do
38
+ context "with default iteration variable" do
39
+ let(:fragment) { xml_fragment('input/sequence/array_sequence') }
40
+
41
+ it "substitutes default variable with array elements" do
42
+ dataset = Sheng::DataSet.new({
43
+ :my_dog => {
44
+ :favorite_toys => ["rooster", "wallet", "foot"]
45
+ }
46
+ })
47
+
48
+ subject.interpolate(dataset)
49
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/array_sequence')
50
+ end
51
+ end
52
+
53
+ context "with overridden iteration variable" do
54
+ let(:fragment) { xml_fragment('input/sequence/overridden_iterator_array_sequence') }
55
+
56
+ it "substitutes given variable" do
57
+ dataset = Sheng::DataSet.new({
58
+ :perps => ["Hamburglar", "Tony the Tiger"]
59
+ })
60
+
61
+ subject.interpolate(dataset)
62
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/overridden_iterator_array_sequence')
63
+ end
64
+ end
65
+ end
66
+
67
+ context "with an inline sequence" do
68
+ let(:fragment) { xml_fragment('input/sequence/inline_sequence') }
69
+
70
+ it "interpolates and maintains inline structure" do
71
+ dataset = Sheng::DataSet.new({
72
+ :library => {
73
+ :books => [
74
+ { :title => 'A Radish Summer', :scent => 'totally rad' },
75
+ { :title => 'Elephants Are Not Your Friend', :scent => 'stinky' }
76
+ ]
77
+ }
78
+ })
79
+
80
+ subject.interpolate(dataset)
81
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/inline_sequence')
82
+ end
83
+ end
84
+
85
+ context "with a requested comma-separated series" do
86
+ let(:fragment) { xml_fragment('input/sequence/series_with_commas') }
87
+ let(:element) { fragment.xpath("//w:fldChar[contains(@w:fldCharType, 'begin')]").first }
88
+
89
+ it "creates a comma-separated list with commas (including serial comma and conjunction)" do
90
+ dataset = Sheng::DataSet.new({
91
+ :buffoons => [
92
+ { :first_name => "Snookers", :last_name => "Fumpleton" },
93
+ { :first_name => "Francis", :last_name => "Oldgark" },
94
+ { :first_name => "Spanky", :last_name => "McThanks" }
95
+ ]
96
+ })
97
+
98
+ subject.interpolate(dataset)
99
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/series_with_commas')
100
+ end
101
+
102
+ it "does not add a comma before the conjunction in a 2-item list" do
103
+ dataset = Sheng::DataSet.new({
104
+ :buffoons => [
105
+ { :first_name => "Snookers", :last_name => "Fumpleton" },
106
+ { :first_name => "Spanky", :last_name => "McThanks" }
107
+ ]
108
+ })
109
+
110
+ subject.interpolate(dataset)
111
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/series_with_commas_two_items')
112
+ end
113
+
114
+ context "with custom conjunction" do
115
+ let(:fragment) { xml_fragment('input/sequence/series_with_commas', :gsub => { "series_with_commas" => "series_with_commas(und)"}) }
116
+
117
+ it "uses given conjunction instead of default 'and'" do
118
+ dataset = Sheng::DataSet.new({
119
+ :buffoons => [
120
+ { :first_name => "Snookers", :last_name => "Fumpleton" },
121
+ { :first_name => "Francis", :last_name => "Oldgark" },
122
+ { :first_name => "Spanky", :last_name => "McThanks" }
123
+ ]
124
+ })
125
+
126
+ subject.interpolate(dataset)
127
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/series_with_commas', :gsub => { ", and" => ", und"})
128
+ end
129
+ end
130
+ end
131
+
132
+ context "with a sequence with section formatting" do
133
+ let(:fragment) { xml_fragment('input/sequence/sequence_with_section_formatting') }
134
+
135
+ it "copies section formatting from bracket mergefields to generated ends" do
136
+ dataset = Sheng::DataSet.new({
137
+ :countries => ["Tumbiblia", "Rofronco", "Beanipops", "Baab"]
138
+ })
139
+
140
+ subject.interpolate(dataset)
141
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/sequence_with_section_formatting')
142
+ end
143
+ end
144
+
145
+ context "with table-based sequences" do
146
+ let(:fragment) { xml_fragment('input/sequence/sequence_in_table') }
147
+
148
+ it "creates new rows for each collection object" do
149
+ dataset = Sheng::DataSet.new({
150
+ :meals => [
151
+ { :meal => 'Gravel Noodles', :appetizer => 'Asphalt Rollups', :dessert => 'Concrete Cream', :drink => 'Steamed Water' },
152
+ { :meal => 'A Single Olive', :appetizer => 'A Strand of Hair', :dessert => 'Wishes and Hopes', :drink => 'The Memory of Soda' }
153
+ ]
154
+ })
155
+
156
+ subject.interpolate(dataset)
157
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/sequence_in_table')
158
+ end
159
+ end
160
+
161
+ context "with embedded sequences" do
162
+ let(:fragment) { xml_fragment('input/sequence/embedded_sequence') }
163
+
164
+ it "iterates over sub-sequences properly" do
165
+ dataset = Sheng::DataSet.new({
166
+ :library => {
167
+ :books => [
168
+ { :title => 'A Radish Summer', :scent => 'totally rad', :pages => [{ :size => 'huge'}, { :size => 'tiny'}] },
169
+ { :title => 'Elephants Are Not Your Friend', :scent => 'stinky', :pages => [{ :size => 'gigantic'}] }
170
+ ]
171
+ }
172
+ })
173
+
174
+ subject.interpolate(dataset)
175
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/sequence/embedded_sequence')
176
+ end
177
+ end
178
+ end
179
+
180
+ describe '#new' do
181
+ context "with unclosed sequence" do
182
+ let(:fragment) { xml_fragment('input/sequence/bad/unclosed_sequence') }
183
+ it 'raises an exception indicating the missing end tag' do
184
+ dataset = Sheng::DataSet.new({})
185
+ expect {
186
+ subject
187
+ }.to raise_error(described_class::MissingEndTag, "no end tag for start:library.books")
188
+ end
189
+ end
190
+
191
+ context "with badly nested sequence" do
192
+ let(:fragment) { xml_fragment('input/sequence/bad/badly_nested_sequence') }
193
+ it 'raises an exception indicating the nesting issue' do
194
+ dataset = Sheng::DataSet.new({})
195
+ expect {
196
+ subject
197
+ }.to raise_error(described_class::ImproperNesting, "expected end tag for start:birds, got end:animals")
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,38 @@
1
+ describe Sheng::WMLFile do
2
+ describe '#xml' do
3
+ it 'returns initialized xml parsed with nokogiri' do
4
+ allow(Nokogiri).to receive(:XML).with(:the_xml).and_return(:yay_xml)
5
+ subject = described_class.new('yak_soup', :the_xml)
6
+ expect(subject.xml).to eq :yay_xml
7
+ end
8
+ end
9
+
10
+ describe '#parent_set' do
11
+ it "returns mergefield set for entire document" do
12
+ subject = described_class.new('yak_soup', 'whatever')
13
+ allow(subject).to receive(:xml).and_return(:boy_i_love_xml)
14
+ allow(Sheng::MergeFieldSet).to receive(:new).
15
+ with('main', :boy_i_love_xml).
16
+ and_return(:the_mama_of_all_sets)
17
+ expect(subject.parent_set).to eq :the_mama_of_all_sets
18
+ end
19
+ end
20
+
21
+ describe '#to_tree' do
22
+ it "delegates to #parent_set" do
23
+ subject = described_class.new('yak_soup', 'whatever')
24
+ allow(subject).to receive(:parent_set).
25
+ and_return(double(:to_tree => :this_is_cooler_than_a_poem))
26
+ expect(subject.to_tree).to eq :this_is_cooler_than_a_poem
27
+ end
28
+ end
29
+
30
+ describe '#required_hash' do
31
+ it "delegates to #parent_set" do
32
+ subject = described_class.new('yak_soup', 'whatever')
33
+ allow(subject).to receive(:parent_set).
34
+ and_return(double(:required_hash => :brown_and_crispy))
35
+ expect(subject.required_hash).to eq :brown_and_crispy
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'sheng'
5
+ require 'equivalent-xml'
6
+ require 'equivalent-xml/rspec_matchers'
7
+
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+ config.order = 'random'
14
+ config.include PathHelper
15
+ config.include XMLHelper
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'yaml'
2
+
3
+ module PathHelper
4
+ def fixture_directory_path
5
+ Pathname.new(File.dirname(__FILE__)).join('..', '..', 'spec', 'fixtures').expand_path
6
+ end
7
+
8
+ def fixture_path(path)
9
+ fixture_directory_path.join(path)
10
+ end
11
+
12
+ def tree_fixture(type)
13
+ YAML.load_file(fixture_path("trees/#{type}.yml"))
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module XMLHelper
2
+ def xml_fragment(type, gsub: {})
3
+ path = fixture_path("xml_fragments/#{type}.xml")
4
+ xml = File.read(path)
5
+ gsub.each do |key, value|
6
+ xml.gsub!(key, value)
7
+ end
8
+ Nokogiri::XML(xml) { |config| config.noblanks }
9
+ end
10
+
11
+ def fragment_with_checked_box(fragment)
12
+ Nokogiri::XML(fragment.to_s.gsub(/default w:val="."/, 'default w:val="1"'))
13
+ end
14
+
15
+ def fragment_with_unchecked_box(fragment)
16
+ Nokogiri::XML(fragment.to_s.gsub(/default w:val="."/, 'default w:val="0"'))
17
+ end
18
+
19
+ def in_mutable_wml_files(zip_file)
20
+ Zip::File.new(zip_file).entries.each do |file|
21
+ if Sheng::Docx::WMLFileNamePatterns.any? { |regex| file.name.match(regex) }
22
+ Zip::File.open(zip_file) do |zip|
23
+ yield(file.name, zip.read(file))
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,355 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sheng
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.2
5
+ platform: ruby
6
+ authors:
7
+ - Ravi Gadad
8
+ - Maher Hawash
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-05-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.3'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: equivalent-xml
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0.6'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0.6'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: simplecov
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: nokogiri
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '1.6'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.6'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rubyzip
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: 1.1.1
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: 1.1.1
126
+ - !ruby/object:Gem::Dependency
127
+ name: activesupport
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '4.2'
133
+ type: :runtime
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '4.2'
140
+ description: A Ruby gem for data merging Word documents.
141
+ email:
142
+ - ravi@renewfund.com
143
+ executables: []
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitattributes"
148
+ - ".gitignore"
149
+ - ".rspec"
150
+ - ".ruby-version"
151
+ - ".watchr"
152
+ - Gemfile
153
+ - LICENSE.txt
154
+ - README.md
155
+ - Rakefile
156
+ - docs/creating_templates.docx
157
+ - docs/creating_templates.md
158
+ - lib/sheng.rb
159
+ - lib/sheng/block.rb
160
+ - lib/sheng/check_box.rb
161
+ - lib/sheng/conditional_block.rb
162
+ - lib/sheng/data_set.rb
163
+ - lib/sheng/docx.rb
164
+ - lib/sheng/merge_field.rb
165
+ - lib/sheng/merge_field_set.rb
166
+ - lib/sheng/path_helpers.rb
167
+ - lib/sheng/sequence.rb
168
+ - lib/sheng/support.rb
169
+ - lib/sheng/version.rb
170
+ - lib/sheng/wml_file.rb
171
+ - sheng.gemspec
172
+ - spec/fixtures/bad_docx_files/with_field_not_in_dataset.docx
173
+ - spec/fixtures/bad_docx_files/with_missing_sequence_start.docx
174
+ - spec/fixtures/bad_docx_files/with_old_mergefields.docx
175
+ - spec/fixtures/bad_docx_files/with_poorly_nested_sequences.docx
176
+ - spec/fixtures/bad_docx_files/with_unended_sequence.docx
177
+ - spec/fixtures/docx_files/input_document.docx
178
+ - spec/fixtures/docx_files/old_style/input_document.docx
179
+ - spec/fixtures/docx_files/old_style/output_document.docx
180
+ - spec/fixtures/docx_files/output_document.docx
181
+ - spec/fixtures/inputs/complete.json
182
+ - spec/fixtures/inputs/incomplete.json
183
+ - spec/fixtures/trees/embedded_sequence.yml
184
+ - spec/fixtures/trees/merge_field_set.yml
185
+ - spec/fixtures/xml_fragments/input/check_box/check_box.xml
186
+ - spec/fixtures/xml_fragments/input/conditional_block/bad/badly_nested_conditional.xml
187
+ - spec/fixtures/xml_fragments/input/conditional_block/bad/unclosed_conditional.xml
188
+ - spec/fixtures/xml_fragments/input/conditional_block/conditional_block_if.xml
189
+ - spec/fixtures/xml_fragments/input/conditional_block/conditional_block_inline.xml
190
+ - spec/fixtures/xml_fragments/input/conditional_block/conditional_block_unless.xml
191
+ - spec/fixtures/xml_fragments/input/conditional_block/conditional_in_table.xml
192
+ - spec/fixtures/xml_fragments/input/conditional_block/embedded_conditional.xml
193
+ - spec/fixtures/xml_fragments/input/merge_field/bad/not_a_real_mergefield_new.xml
194
+ - spec/fixtures/xml_fragments/input/merge_field/bad/not_a_real_mergefield_old.xml
195
+ - spec/fixtures/xml_fragments/input/merge_field/bad/unclosed_merge_field.xml
196
+ - spec/fixtures/xml_fragments/input/merge_field/inline_merge_field.xml
197
+ - spec/fixtures/xml_fragments/input/merge_field/merge_field.xml
198
+ - spec/fixtures/xml_fragments/input/merge_field/new_merge_field.xml
199
+ - spec/fixtures/xml_fragments/input/merge_field/split_merge_field.xml
200
+ - spec/fixtures/xml_fragments/input/merge_field_set/complex_nesting_and_reuse.xml
201
+ - spec/fixtures/xml_fragments/input/merge_field_set/merge_field_set.xml
202
+ - spec/fixtures/xml_fragments/input/merge_field_set/with_non_mergefield_fields.xml
203
+ - spec/fixtures/xml_fragments/input/sequence/array_sequence.xml
204
+ - spec/fixtures/xml_fragments/input/sequence/bad/badly_nested_sequence.xml
205
+ - spec/fixtures/xml_fragments/input/sequence/bad/unclosed_sequence.xml
206
+ - spec/fixtures/xml_fragments/input/sequence/embedded_sequence.xml
207
+ - spec/fixtures/xml_fragments/input/sequence/inline_sequence.xml
208
+ - spec/fixtures/xml_fragments/input/sequence/overridden_iterator_array_sequence.xml
209
+ - spec/fixtures/xml_fragments/input/sequence/sequence.xml
210
+ - spec/fixtures/xml_fragments/input/sequence/sequence_in_table.xml
211
+ - spec/fixtures/xml_fragments/input/sequence/sequence_with_section_formatting.xml
212
+ - spec/fixtures/xml_fragments/input/sequence/series_with_commas.xml
213
+ - spec/fixtures/xml_fragments/output/check_box/check_box.xml
214
+ - spec/fixtures/xml_fragments/output/conditional_block/conditional_in_table_does_not_exist.xml
215
+ - spec/fixtures/xml_fragments/output/conditional_block/conditional_in_table_exists.xml
216
+ - spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_both.xml
217
+ - spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_inside.xml
218
+ - spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_outside.xml
219
+ - spec/fixtures/xml_fragments/output/conditional_block/if_does_not_exist.xml
220
+ - spec/fixtures/xml_fragments/output/conditional_block/if_exists.xml
221
+ - spec/fixtures/xml_fragments/output/conditional_block/inline_does_not_exist.xml
222
+ - spec/fixtures/xml_fragments/output/conditional_block/inline_exists.xml
223
+ - spec/fixtures/xml_fragments/output/conditional_block/unless_does_not_exist.xml
224
+ - spec/fixtures/xml_fragments/output/conditional_block/unless_exists.xml
225
+ - spec/fixtures/xml_fragments/output/merge_field/inline_merge_field.xml
226
+ - spec/fixtures/xml_fragments/output/merge_field/merge_field.xml
227
+ - spec/fixtures/xml_fragments/output/merge_field/split_merge_field.xml
228
+ - spec/fixtures/xml_fragments/output/merge_field_set/complex_nesting_and_reuse.xml
229
+ - spec/fixtures/xml_fragments/output/merge_field_set/merge_field_set.xml
230
+ - spec/fixtures/xml_fragments/output/merge_field_set/with_non_mergefield_fields.xml
231
+ - spec/fixtures/xml_fragments/output/sequence/array_sequence.xml
232
+ - spec/fixtures/xml_fragments/output/sequence/embedded_sequence.xml
233
+ - spec/fixtures/xml_fragments/output/sequence/inline_sequence.xml
234
+ - spec/fixtures/xml_fragments/output/sequence/overridden_iterator_array_sequence.xml
235
+ - spec/fixtures/xml_fragments/output/sequence/sequence.xml
236
+ - spec/fixtures/xml_fragments/output/sequence/sequence_in_table.xml
237
+ - spec/fixtures/xml_fragments/output/sequence/sequence_with_section_formatting.xml
238
+ - spec/fixtures/xml_fragments/output/sequence/series_with_commas.xml
239
+ - spec/fixtures/xml_fragments/output/sequence/series_with_commas_two_items.xml
240
+ - spec/lib/sheng/check_box_spec.rb
241
+ - spec/lib/sheng/conditional_block_spec.rb
242
+ - spec/lib/sheng/data_set_spec.rb
243
+ - spec/lib/sheng/docx_spec.rb
244
+ - spec/lib/sheng/merge_field_set_spec.rb
245
+ - spec/lib/sheng/merge_field_spec.rb
246
+ - spec/lib/sheng/sequence_spec.rb
247
+ - spec/lib/sheng/wml_file_spec.rb
248
+ - spec/spec_helper.rb
249
+ - spec/support/path_helper.rb
250
+ - spec/support/xml_helper.rb
251
+ homepage: ''
252
+ licenses:
253
+ - MIT
254
+ metadata: {}
255
+ post_install_message:
256
+ rdoc_options: []
257
+ require_paths:
258
+ - lib
259
+ required_ruby_version: !ruby/object:Gem::Requirement
260
+ requirements:
261
+ - - ">="
262
+ - !ruby/object:Gem::Version
263
+ version: '0'
264
+ required_rubygems_version: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: '0'
269
+ requirements: []
270
+ rubyforge_project:
271
+ rubygems_version: 2.2.2
272
+ signing_key:
273
+ specification_version: 4
274
+ summary: A Ruby gem for data merging Word documents, using native MergeFields as placeholders
275
+ in templates, and a Ruby hash as the data set for substitution.
276
+ test_files:
277
+ - spec/fixtures/bad_docx_files/with_field_not_in_dataset.docx
278
+ - spec/fixtures/bad_docx_files/with_missing_sequence_start.docx
279
+ - spec/fixtures/bad_docx_files/with_old_mergefields.docx
280
+ - spec/fixtures/bad_docx_files/with_poorly_nested_sequences.docx
281
+ - spec/fixtures/bad_docx_files/with_unended_sequence.docx
282
+ - spec/fixtures/docx_files/input_document.docx
283
+ - spec/fixtures/docx_files/old_style/input_document.docx
284
+ - spec/fixtures/docx_files/old_style/output_document.docx
285
+ - spec/fixtures/docx_files/output_document.docx
286
+ - spec/fixtures/inputs/complete.json
287
+ - spec/fixtures/inputs/incomplete.json
288
+ - spec/fixtures/trees/embedded_sequence.yml
289
+ - spec/fixtures/trees/merge_field_set.yml
290
+ - spec/fixtures/xml_fragments/input/check_box/check_box.xml
291
+ - spec/fixtures/xml_fragments/input/conditional_block/bad/badly_nested_conditional.xml
292
+ - spec/fixtures/xml_fragments/input/conditional_block/bad/unclosed_conditional.xml
293
+ - spec/fixtures/xml_fragments/input/conditional_block/conditional_block_if.xml
294
+ - spec/fixtures/xml_fragments/input/conditional_block/conditional_block_inline.xml
295
+ - spec/fixtures/xml_fragments/input/conditional_block/conditional_block_unless.xml
296
+ - spec/fixtures/xml_fragments/input/conditional_block/conditional_in_table.xml
297
+ - spec/fixtures/xml_fragments/input/conditional_block/embedded_conditional.xml
298
+ - spec/fixtures/xml_fragments/input/merge_field/bad/not_a_real_mergefield_new.xml
299
+ - spec/fixtures/xml_fragments/input/merge_field/bad/not_a_real_mergefield_old.xml
300
+ - spec/fixtures/xml_fragments/input/merge_field/bad/unclosed_merge_field.xml
301
+ - spec/fixtures/xml_fragments/input/merge_field/inline_merge_field.xml
302
+ - spec/fixtures/xml_fragments/input/merge_field/merge_field.xml
303
+ - spec/fixtures/xml_fragments/input/merge_field/new_merge_field.xml
304
+ - spec/fixtures/xml_fragments/input/merge_field/split_merge_field.xml
305
+ - spec/fixtures/xml_fragments/input/merge_field_set/complex_nesting_and_reuse.xml
306
+ - spec/fixtures/xml_fragments/input/merge_field_set/merge_field_set.xml
307
+ - spec/fixtures/xml_fragments/input/merge_field_set/with_non_mergefield_fields.xml
308
+ - spec/fixtures/xml_fragments/input/sequence/array_sequence.xml
309
+ - spec/fixtures/xml_fragments/input/sequence/bad/badly_nested_sequence.xml
310
+ - spec/fixtures/xml_fragments/input/sequence/bad/unclosed_sequence.xml
311
+ - spec/fixtures/xml_fragments/input/sequence/embedded_sequence.xml
312
+ - spec/fixtures/xml_fragments/input/sequence/inline_sequence.xml
313
+ - spec/fixtures/xml_fragments/input/sequence/overridden_iterator_array_sequence.xml
314
+ - spec/fixtures/xml_fragments/input/sequence/sequence.xml
315
+ - spec/fixtures/xml_fragments/input/sequence/sequence_in_table.xml
316
+ - spec/fixtures/xml_fragments/input/sequence/sequence_with_section_formatting.xml
317
+ - spec/fixtures/xml_fragments/input/sequence/series_with_commas.xml
318
+ - spec/fixtures/xml_fragments/output/check_box/check_box.xml
319
+ - spec/fixtures/xml_fragments/output/conditional_block/conditional_in_table_does_not_exist.xml
320
+ - spec/fixtures/xml_fragments/output/conditional_block/conditional_in_table_exists.xml
321
+ - spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_both.xml
322
+ - spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_inside.xml
323
+ - spec/fixtures/xml_fragments/output/conditional_block/embedded_conditional_outside.xml
324
+ - spec/fixtures/xml_fragments/output/conditional_block/if_does_not_exist.xml
325
+ - spec/fixtures/xml_fragments/output/conditional_block/if_exists.xml
326
+ - spec/fixtures/xml_fragments/output/conditional_block/inline_does_not_exist.xml
327
+ - spec/fixtures/xml_fragments/output/conditional_block/inline_exists.xml
328
+ - spec/fixtures/xml_fragments/output/conditional_block/unless_does_not_exist.xml
329
+ - spec/fixtures/xml_fragments/output/conditional_block/unless_exists.xml
330
+ - spec/fixtures/xml_fragments/output/merge_field/inline_merge_field.xml
331
+ - spec/fixtures/xml_fragments/output/merge_field/merge_field.xml
332
+ - spec/fixtures/xml_fragments/output/merge_field/split_merge_field.xml
333
+ - spec/fixtures/xml_fragments/output/merge_field_set/complex_nesting_and_reuse.xml
334
+ - spec/fixtures/xml_fragments/output/merge_field_set/merge_field_set.xml
335
+ - spec/fixtures/xml_fragments/output/merge_field_set/with_non_mergefield_fields.xml
336
+ - spec/fixtures/xml_fragments/output/sequence/array_sequence.xml
337
+ - spec/fixtures/xml_fragments/output/sequence/embedded_sequence.xml
338
+ - spec/fixtures/xml_fragments/output/sequence/inline_sequence.xml
339
+ - spec/fixtures/xml_fragments/output/sequence/overridden_iterator_array_sequence.xml
340
+ - spec/fixtures/xml_fragments/output/sequence/sequence.xml
341
+ - spec/fixtures/xml_fragments/output/sequence/sequence_in_table.xml
342
+ - spec/fixtures/xml_fragments/output/sequence/sequence_with_section_formatting.xml
343
+ - spec/fixtures/xml_fragments/output/sequence/series_with_commas.xml
344
+ - spec/fixtures/xml_fragments/output/sequence/series_with_commas_two_items.xml
345
+ - spec/lib/sheng/check_box_spec.rb
346
+ - spec/lib/sheng/conditional_block_spec.rb
347
+ - spec/lib/sheng/data_set_spec.rb
348
+ - spec/lib/sheng/docx_spec.rb
349
+ - spec/lib/sheng/merge_field_set_spec.rb
350
+ - spec/lib/sheng/merge_field_spec.rb
351
+ - spec/lib/sheng/sequence_spec.rb
352
+ - spec/lib/sheng/wml_file_spec.rb
353
+ - spec/spec_helper.rb
354
+ - spec/support/path_helper.rb
355
+ - spec/support/xml_helper.rb