sheng 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20f74c4e33aa2c6d02047cba5d9939aae549a4d6
4
- data.tar.gz: 9e5f6b49e52c00e894d799fb9e000d7fb070efad
3
+ metadata.gz: ea5e2737e44d4a27d5d268bdfcefe21e1a3ff51b
4
+ data.tar.gz: 3245c5ef173eb186beaf1fb78acd487bfd42e04e
5
5
  SHA512:
6
- metadata.gz: 98a4c1d780fb682610f7745dee718bad9b9d2ada521e8ac92f62b86e36ade25cc87f125a47fc2e701228d997b06d6d468eceda32e77d08a6554ddb9026f7875c
7
- data.tar.gz: 4540354d8578d52ca6d26a9f4b186ec1eeaa051c74857ec13b189bb642673cf554d88c8f95b88f2c08efd55d8df73783c718e732ab700934b72d5ea07c2a1b33
6
+ metadata.gz: bd6309f22f7c16ddb93dc94d79fe8dbe4cb34c7ec4eb835883fe8afb1127271f8380c70dc79c262ff8da3f7c8d3bb442bd3e6f9b22fcbc3496b17ae4366f532c
7
+ data.tar.gz: 513affc5751aa7de19dc060c13e99974605d9e30afc57ae1711b8666fcd23294493d1c7790e8df6968fba145bd574d520d11a437e9e185ec3c3d1bcce15bc780
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.1.1
1
+ 2.1.
Binary file
@@ -223,6 +223,20 @@ Filters can also be chained, and will be applied in which they appear (from left
223
223
 
224
224
  «a_basic_integer|downcase»
225
225
 
226
+ ## Basic Arithmetic Operations
227
+
228
+ You can perform basic arithmetic operations within a mergefield, using either hardcoded numeric values or variable names. The operators allowed are + (addition), - (subtraction), * (multiplication), and / (division). The usual order of precedence applies with these operators, and you can use parenthesis to control that precedence.
229
+
230
+ ### Examples:
231
+
232
+ «25 * 6»
233
+
234
+ «8.3 + 5.232»
235
+
236
+ «(2.1 + 5) * 18»
237
+
238
+ «(hair.length * 2) + head.height»
239
+
226
240
  # Checkboxes
227
241
 
228
242
  To create a checkbox:
@@ -1,8 +1,14 @@
1
+ require "dentaku"
2
+
1
3
  module Sheng
2
4
  class MergeField
3
- AllowedFilters = [:upcase, :downcase, :capitalize, :titleize, :reverse]
4
- InstructionTextRegex = /^\s*MERGEFIELD(.*)\\\* MERGEFORMAT\s*$/
5
- KeyRegex = /^(start:|end:|if:|end_if:|unless:|end_unless:)?\s*([^\|\s]+)\s*\|?(.*)?/
5
+ MATH_TOKENS = %w[+ - / * ( )]
6
+ REGEXES = {
7
+ instruction_text: /^\s*MERGEFIELD(.*)\\\* MERGEFORMAT\s*$/,
8
+ key_string: /^(?<prefix>start:|end:|if:|end_if:|unless:|end_unless:)?\s*(?<key>[^\|]+)\s*\|?(?<filters>.*)?/,
9
+ numeric_string: /^[-+]?[0-9]*\.?[0-9]+$/
10
+ }
11
+ ALLOWED_FILTERS = [:upcase, :downcase, :capitalize, :titleize, :reverse]
6
12
 
7
13
  class NotAMergeFieldError < StandardError; end
8
14
 
@@ -31,16 +37,16 @@ module Sheng
31
37
  end
32
38
 
33
39
  def key
34
- raw_key.gsub(KeyRegex, '\2')
40
+ raw_key.match(REGEXES[:key_string])[:key].strip
35
41
  end
36
42
 
37
43
  def filters
38
- match = raw_key.match(KeyRegex)
39
- match.captures[2].split("|").map(&:strip)
44
+ match = raw_key.match(REGEXES[:key_string])
45
+ match[:filters].split("|").map(&:strip)
40
46
  end
41
47
 
42
48
  def raw_key
43
- @raw_key ||= mergefield_instruction_text.gsub(InstructionTextRegex, '\1').strip
49
+ @raw_key ||= mergefield_instruction_text.gsub(REGEXES[:instruction_text], '\1').strip
44
50
  end
45
51
 
46
52
  def mergefield_instruction_text
@@ -84,7 +90,7 @@ module Sheng
84
90
 
85
91
  def block_prefix
86
92
  @potential_prefix ||= begin
87
- potential_prefix = raw_key.match(KeyRegex).captures[0]
93
+ potential_prefix = raw_key.match(REGEXES[:key_string])[:prefix]
88
94
  potential_prefix && potential_prefix.gsub(/\:$/, '')
89
95
  end
90
96
  end
@@ -185,10 +191,55 @@ module Sheng
185
191
  xml.remove
186
192
  end
187
193
 
194
+ def key_parts
195
+ @key_parts ||= key.gsub(".", "_DOTSEPARATOR_").
196
+ split(/\b|\s/).
197
+ map(&:strip).
198
+ reject(&:empty?).
199
+ map { |token|
200
+ token.gsub("_DOTSEPARATOR_", ".")
201
+ }
202
+ end
203
+
204
+ def required_variables
205
+ key_parts.reject { |token|
206
+ REGEXES[:numeric_string].match(token) || MATH_TOKENS.include?(token)
207
+ }
208
+ end
209
+
210
+ def required_hash(placeholder: nil)
211
+ required_variables.inject({}) { |assembled, variable|
212
+ parts = variable.split(/\./)
213
+ last_key = parts.pop
214
+ hash = parts.reverse.inject(last_key => placeholder) do |memo, key|
215
+ memo = { key => memo }; memo
216
+ end
217
+ Sheng::Support.merge_required_hashes(assembled, hash)
218
+ }
219
+ end
220
+
221
+ def key_has_math?
222
+ !(MATH_TOKENS & key_parts).empty?
223
+ end
224
+
225
+ def get_value(data_set)
226
+ interpolated_string = key_parts.map { |token|
227
+ if REGEXES[:numeric_string].match(token) || MATH_TOKENS.include?(token)
228
+ token
229
+ else
230
+ data_set.fetch(token)
231
+ end
232
+ }.join(" ")
233
+
234
+ return interpolated_string unless key_has_math?
235
+
236
+ Dentaku::Calculator.new.evaluate!(interpolated_string)
237
+ end
238
+
188
239
  def interpolate(data_set)
189
- value = data_set.fetch(key)
240
+ value = get_value(data_set)
190
241
  replace_mergefield(filter_value(value))
191
- rescue DataSet::KeyNotFound
242
+ rescue DataSet::KeyNotFound, Dentaku::UnboundVariableError
192
243
  # Ignore this error; we'll collect all uninterpolated fields later and
193
244
  # raise a new exception, so we can list all the fields in an error
194
245
  # message.
@@ -197,7 +248,7 @@ module Sheng
197
248
 
198
249
  def filter_value(value)
199
250
  filters.inject(value) { |val, filter|
200
- if AllowedFilters.include?(filter.to_sym) && val.respond_to?(filter.to_sym)
251
+ if ALLOWED_FILTERS.include?(filter.to_sym) && val.respond_to?(filter.to_sym)
201
252
  val.send(filter)
202
253
  else
203
254
  val
@@ -36,6 +36,8 @@ module Sheng
36
36
  nodes.inject({}) do |node_list, node|
37
37
  hsh = if node.is_a?(ConditionalBlock)
38
38
  node.required_hash(placeholder)
39
+ elsif node.is_a?(MergeField)
40
+ node.required_hash(placeholder: placeholder)
39
41
  else
40
42
  value = node.is_a?(Block) ? [node.required_hash(placeholder)].compact : placeholder
41
43
  key_parts = node.key.split(/\./)
data/lib/sheng/support.rb CHANGED
@@ -47,7 +47,7 @@ module Sheng
47
47
  label << label_part.text
48
48
  end
49
49
  end
50
- unless label.match(MergeField::InstructionTextRegex)
50
+ unless label.match(MergeField::REGEXES[:instruction_text])
51
51
  raise MergeField::NotAMergeFieldError.new(label)
52
52
  end
53
53
  label
data/lib/sheng/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sheng
2
- VERSION = "0.3.4"
2
+ VERSION = "0.4.0"
3
3
  end
data/sheng.gemspec CHANGED
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "nokogiri", "~> 1.6"
29
29
  spec.add_dependency "rubyzip", "~> 1.1.1"
30
30
  spec.add_dependency "activesupport", "~> 4.0"
31
+ spec.add_dependency "dentaku", "~> 2.0"
31
32
  end
@@ -10,6 +10,10 @@
10
10
  :key: color
11
11
  - :type: merge_field
12
12
  :key: size
13
+ - :type: merge_field
14
+ :key: dimensions.width * dimensions.height
15
+ - :type: merge_field
16
+ :key: (dimensions.width * 2) + (dimensions.height * 2)
13
17
  - :type: check_box
14
18
  :key: veggies.green.spinach
15
19
  - :type: merge_field
@@ -0,0 +1,14 @@
1
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
2
+ <w:p>
3
+ <w:fldSimple w:instr=" MERGEFIELD baskets.count * (3 + origami) \* MERGEFORMAT ">
4
+ <w:r>
5
+ <w:rPr>
6
+ <w:b/>
7
+ <w:i/>
8
+ <w:noProof/>
9
+ </w:rPr>
10
+ <w:t>«baskets.count * (3 + origami)»</w:t>
11
+ </w:r>
12
+ </w:fldSimple>
13
+ </w:p>
14
+ </w:document>
@@ -54,6 +54,32 @@
54
54
  </w:r>
55
55
  </w:fldSimple>
56
56
  </w:p>
57
+ <w:p>
58
+ <w:r>
59
+ <w:t xml:space="preserve">Sock Area: </w:t>
60
+ </w:r>
61
+ <w:fldSimple w:instr=" MERGEFIELD dimensions.width * dimensions.height \* MERGEFORMAT ">
62
+ <w:r>
63
+ <w:rPr>
64
+ <w:noProof/>
65
+ </w:rPr>
66
+ <w:t>«dimensions.width * dimensions.height»</w:t>
67
+ </w:r>
68
+ </w:fldSimple>
69
+ </w:p>
70
+ <w:p>
71
+ <w:r>
72
+ <w:t xml:space="preserve">Sock Circumference: </w:t>
73
+ </w:r>
74
+ <w:fldSimple w:instr=" MERGEFIELD (dimensions.width * 2) + (dimensions.height * 2) \* MERGEFORMAT ">
75
+ <w:r>
76
+ <w:rPr>
77
+ <w:noProof/>
78
+ </w:rPr>
79
+ <w:t>«(dimensions.width * 2) + (dimensions.height * 2)»</w:t>
80
+ </w:r>
81
+ </w:fldSimple>
82
+ </w:p>
57
83
  <w:p>
58
84
  <w:fldSimple w:instr=" MERGEFIELD end:person.socks \* MERGEFORMAT ">
59
85
  <w:r w:rsidR="00455C8A">
@@ -0,0 +1,12 @@
1
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
2
+ <w:p>
3
+ <w:r>
4
+ <w:rPr>
5
+ <w:b/>
6
+ <w:i/>
7
+ <w:noProof/>
8
+ </w:rPr>
9
+ <w:t>22</w:t>
10
+ </w:r>
11
+ </w:p>
12
+ </w:document>
@@ -36,6 +36,28 @@
36
36
  <w:t>Stumungous</w:t>
37
37
  </w:r>
38
38
  </w:p>
39
+ <w:p>
40
+ <w:r>
41
+ <w:t xml:space="preserve">Sock Area: </w:t>
42
+ </w:r>
43
+ <w:r>
44
+ <w:rPr>
45
+ <w:noProof/>
46
+ </w:rPr>
47
+ <w:t>70</w:t>
48
+ </w:r>
49
+ </w:p>
50
+ <w:p>
51
+ <w:r>
52
+ <w:t xml:space="preserve">Sock Circumference: </w:t>
53
+ </w:r>
54
+ <w:r>
55
+ <w:rPr>
56
+ <w:noProof/>
57
+ </w:rPr>
58
+ <w:t>38</w:t>
59
+ </w:r>
60
+ </w:p>
39
61
  <w:p>
40
62
  <w:r>
41
63
  <w:rPr>
@@ -52,6 +74,28 @@
52
74
  <w:t>Teensy</w:t>
53
75
  </w:r>
54
76
  </w:p>
77
+ <w:p>
78
+ <w:r>
79
+ <w:t xml:space="preserve">Sock Area: </w:t>
80
+ </w:r>
81
+ <w:r>
82
+ <w:rPr>
83
+ <w:noProof/>
84
+ </w:rPr>
85
+ <w:t>364</w:t>
86
+ </w:r>
87
+ </w:p>
88
+ <w:p>
89
+ <w:r>
90
+ <w:t xml:space="preserve">Sock Circumference: </w:t>
91
+ </w:r>
92
+ <w:r>
93
+ <w:rPr>
94
+ <w:noProof/>
95
+ </w:rPr>
96
+ <w:t>82</w:t>
97
+ </w:r>
98
+ </w:p>
55
99
  <w:ffData>
56
100
  <w:name w:val="veggies.green.spinach"/>
57
101
  <w:enabled/>
@@ -28,8 +28,8 @@ describe Sheng::MergeFieldSet do
28
28
  :first_name => 'Brad',
29
29
  :last_name => 'Tucklemoof',
30
30
  :socks => [
31
- { :color => 'Green', :size => 'Stumungous' },
32
- { :color => 'Whitish', :size => 'Teensy' }
31
+ { :color => 'Green', :size => 'Stumungous', :dimensions => { :width => 14, :height => 5 } },
32
+ { :color => 'Whitish', :size => 'Teensy', :dimensions => { :width => 28, :height => 13 } }
33
33
  ]
34
34
  },
35
35
  :veggies => { :green => { :spinach => true } }
@@ -117,15 +117,49 @@ describe Sheng::MergeFieldSet do
117
117
  describe '#required_hash' do
118
118
  it 'returns skeleton hash demonstrating required data for interpolation' do
119
119
  expect(subject.required_hash).to eq({
120
- "person" => { "first_name" => nil, "last_name" => nil, "socks" => [{"color"=>nil, "size"=>nil}] },
121
- "veggies"=> { "green" => { "spinach" => nil } }
120
+ "person" => {
121
+ "first_name" => nil,
122
+ "last_name" => nil,
123
+ "socks" => [
124
+ {
125
+ "color" => nil,
126
+ "size" => nil,
127
+ "dimensions" => {
128
+ "width" => nil,
129
+ "height" => nil
130
+ }
131
+ }
132
+ ]
133
+ },
134
+ "veggies"=> {
135
+ "green" => {
136
+ "spinach" => nil
137
+ }
138
+ }
122
139
  })
123
140
  end
124
141
 
125
142
  it 'uses given value as placeholder for mergefields/checkboxes' do
126
143
  expect(subject.required_hash(:foo)).to eq({
127
- "person" => { "first_name" => :foo, "last_name" => :foo, "socks" => [{"color"=>:foo, "size"=>:foo}] },
128
- "veggies"=> { "green" => { "spinach" => :foo } }
144
+ "person" => {
145
+ "first_name" => :foo,
146
+ "last_name" => :foo,
147
+ "socks" => [
148
+ {
149
+ "color" => :foo,
150
+ "size" => :foo,
151
+ "dimensions" => {
152
+ "width" => :foo,
153
+ "height" => :foo
154
+ }
155
+ }
156
+ ]
157
+ },
158
+ "veggies"=> {
159
+ "green" => {
160
+ "spinach" => :foo
161
+ }
162
+ }
129
163
  })
130
164
  end
131
165
 
@@ -27,6 +27,25 @@ describe Sheng::MergeField do
27
27
  end
28
28
  end
29
29
 
30
+ describe "mergefield with math operations" do
31
+ let(:fragment) { xml_fragment('input/merge_field/math_merge_field') }
32
+ let(:element) { fragment.xpath("//w:fldSimple[contains(@w:instr, 'MERGEFIELD')]").first }
33
+
34
+ describe '#interpolate' do
35
+ it 'interpolates values from dataset into mergefield' do
36
+ dataset = Sheng::DataSet.new({
37
+ :baskets => {
38
+ :count => 2
39
+ },
40
+ :origami => 8
41
+ })
42
+
43
+ subject.interpolate(dataset)
44
+ expect(subject.xml_document).to be_equivalent_to xml_fragment('output/merge_field/math_merge_field')
45
+ end
46
+ end
47
+ end
48
+
30
49
  describe "new style merge field" do
31
50
  let(:fragment) { xml_fragment('input/merge_field/new_merge_field') }
32
51
  let(:element) { fragment.xpath("//w:fldChar[contains(@w:fldCharType, 'begin')]").first }
@@ -124,16 +143,70 @@ describe Sheng::MergeField do
124
143
  end
125
144
  end
126
145
 
127
- describe '#interpolate' do
128
- it 'interpolates filtered values from dataset into mergefield' do
129
- dataset = Sheng::DataSet.new({
130
- :ocean => { :fishy => "scrumblefish" }
146
+ describe "#get_value" do
147
+ let(:dataset) {
148
+ Sheng::DataSet.new({
149
+ :ocean => { :fishy => "scrumblefish" },
150
+ :numbers => { :first => 23, :second => 8 }
131
151
  })
152
+ }
153
+
154
+ it "returns value from dataset when given simple lookup" do
155
+ allow(subject).to receive(:key).and_return("ocean.fishy")
156
+ expect(subject.get_value(dataset)).to eq("scrumblefish")
157
+ end
158
+
159
+ it "performs math operations on values from dataset" do
160
+ allow(subject).to receive(:key).and_return("(numbers.first * numbers.second) + 5")
161
+ expect(subject.get_value(dataset)).to eq(189)
162
+ end
163
+
164
+ it "performs math operations with no dataset lookup" do
165
+ allow(subject).to receive(:key).and_return("2 + (3*5)")
166
+ expect(subject.get_value(dataset)).to eq(17)
167
+ end
168
+
169
+ it "raises exception if key not found in simple lookup" do
170
+ allow(subject).to receive(:key).and_return("oliver.twist")
171
+ expect {
172
+ subject.get_value(dataset)
173
+ }.to raise_error(Sheng::DataSet::KeyNotFound)
174
+ end
175
+
176
+ it "raises exception if key not found in math formula" do
177
+ allow(subject).to receive(:key).and_return("oliver.twist * 15")
178
+ expect {
179
+ subject.get_value(dataset)
180
+ }.to raise_error(Sheng::DataSet::KeyNotFound)
181
+ end
182
+
183
+ it "raises exception if interpolated math formula includes invalid symbols" do
184
+ allow(subject).to receive(:key).and_return("ocean.fishy * 15")
185
+ expect {
186
+ subject.get_value(dataset)
187
+ }.to raise_error(Dentaku::UnboundVariableError)
188
+ end
189
+ end
132
190
 
191
+ describe '#interpolate' do
192
+ it 'interpolates filtered values from dataset into mergefield' do
193
+ allow(subject).to receive(:get_value).with(:a_dataset).and_return("scrumblefish")
133
194
  allow(subject).to receive(:filter_value).with("scrumblefish").and_return("l33tphish")
134
- subject.interpolate(dataset)
195
+ subject.interpolate(:a_dataset)
135
196
  expect(subject.xml_document).to be_equivalent_to xml_fragment('output/merge_field/merge_field')
136
197
  end
198
+
199
+ it "does not replace and returns nil if any keys not found" do
200
+ allow(subject).to receive(:get_value).with(:a_dataset).and_raise(Sheng::DataSet::KeyNotFound)
201
+ expect(subject).to receive(:replace_mergefield).never
202
+ expect(subject.interpolate(:a_dataset)).to be_nil
203
+ end
204
+
205
+ it "does not replace and returns nil if calculation error encountered" do
206
+ allow(subject).to receive(:get_value).with(:a_dataset).and_raise(Dentaku::UnboundVariableError.new([]))
207
+ expect(subject).to receive(:replace_mergefield).never
208
+ expect(subject.interpolate(:a_dataset)).to be_nil
209
+ end
137
210
  end
138
211
 
139
212
  describe "#xml" do
@@ -148,6 +221,20 @@ describe Sheng::MergeField do
148
221
  end
149
222
  end
150
223
 
224
+ describe "#required_variables" do
225
+ it "returns key parts that are not operators or numeric" do
226
+ allow(subject).to receive(:key).and_return("cat.toes * 15 + (yawns / 2.0)")
227
+ expect(subject.required_variables).to eq(["cat.toes", "yawns"])
228
+ end
229
+ end
230
+
231
+ describe "#key_parts" do
232
+ it "returns key split on all word boundaries except dot separators" do
233
+ allow(subject).to receive(:key).and_return("cat.toes * 15 + (yawns / 2.0)")
234
+ expect(subject.key_parts).to eq(["cat.toes", "*", "15", "+", "(", "yawns", "/", "2.0", ")"])
235
+ end
236
+ end
237
+
151
238
  describe '#key' do
152
239
  it 'returns the raw key with start/end metadata stripped off' do
153
240
  allow(subject).to receive(:raw_key).and_return('start:whipple.dooter')
@@ -160,6 +247,11 @@ describe Sheng::MergeField do
160
247
  allow(subject).to receive(:raw_key).and_return("whumpies | cook | dress(frock)")
161
248
  expect(subject.key).to eq 'whumpies'
162
249
  end
250
+
251
+ it 'returns key even if it contains math operations' do
252
+ allow(subject).to receive(:raw_key).and_return("whumpies * 3 | cook | dress(frock)")
253
+ expect(subject.key).to eq 'whumpies * 3'
254
+ end
163
255
  end
164
256
 
165
257
  describe "#filters" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sheng
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ravi Gadad
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-05-21 00:00:00.000000000 Z
12
+ date: 2016-01-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -137,6 +137,20 @@ dependencies:
137
137
  - - "~>"
138
138
  - !ruby/object:Gem::Version
139
139
  version: '4.0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: dentaku
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '2.0'
147
+ type: :runtime
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '2.0'
140
154
  description: A Ruby gem for data merging Word documents.
141
155
  email:
142
156
  - ravi@renewfund.com
@@ -194,6 +208,7 @@ files:
194
208
  - spec/fixtures/xml_fragments/input/merge_field/bad/not_a_real_mergefield_old.xml
195
209
  - spec/fixtures/xml_fragments/input/merge_field/bad/unclosed_merge_field.xml
196
210
  - spec/fixtures/xml_fragments/input/merge_field/inline_merge_field.xml
211
+ - spec/fixtures/xml_fragments/input/merge_field/math_merge_field.xml
197
212
  - spec/fixtures/xml_fragments/input/merge_field/merge_field.xml
198
213
  - spec/fixtures/xml_fragments/input/merge_field/new_merge_field.xml
199
214
  - spec/fixtures/xml_fragments/input/merge_field/split_merge_field.xml
@@ -224,6 +239,7 @@ files:
224
239
  - spec/fixtures/xml_fragments/output/conditional_block/unless_does_not_exist.xml
225
240
  - spec/fixtures/xml_fragments/output/conditional_block/unless_exists.xml
226
241
  - spec/fixtures/xml_fragments/output/merge_field/inline_merge_field.xml
242
+ - spec/fixtures/xml_fragments/output/merge_field/math_merge_field.xml
227
243
  - spec/fixtures/xml_fragments/output/merge_field/merge_field.xml
228
244
  - spec/fixtures/xml_fragments/output/merge_field/split_merge_field.xml
229
245
  - spec/fixtures/xml_fragments/output/merge_field_set/complex_nesting_and_reuse.xml
@@ -270,7 +286,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
286
  version: '0'
271
287
  requirements: []
272
288
  rubyforge_project:
273
- rubygems_version: 2.2.2
289
+ rubygems_version: 2.2.5
274
290
  signing_key:
275
291
  specification_version: 4
276
292
  summary: A Ruby gem for data merging Word documents, using native MergeFields as placeholders
@@ -301,6 +317,7 @@ test_files:
301
317
  - spec/fixtures/xml_fragments/input/merge_field/bad/not_a_real_mergefield_old.xml
302
318
  - spec/fixtures/xml_fragments/input/merge_field/bad/unclosed_merge_field.xml
303
319
  - spec/fixtures/xml_fragments/input/merge_field/inline_merge_field.xml
320
+ - spec/fixtures/xml_fragments/input/merge_field/math_merge_field.xml
304
321
  - spec/fixtures/xml_fragments/input/merge_field/merge_field.xml
305
322
  - spec/fixtures/xml_fragments/input/merge_field/new_merge_field.xml
306
323
  - spec/fixtures/xml_fragments/input/merge_field/split_merge_field.xml
@@ -331,6 +348,7 @@ test_files:
331
348
  - spec/fixtures/xml_fragments/output/conditional_block/unless_does_not_exist.xml
332
349
  - spec/fixtures/xml_fragments/output/conditional_block/unless_exists.xml
333
350
  - spec/fixtures/xml_fragments/output/merge_field/inline_merge_field.xml
351
+ - spec/fixtures/xml_fragments/output/merge_field/math_merge_field.xml
334
352
  - spec/fixtures/xml_fragments/output/merge_field/merge_field.xml
335
353
  - spec/fixtures/xml_fragments/output/merge_field/split_merge_field.xml
336
354
  - spec/fixtures/xml_fragments/output/merge_field_set/complex_nesting_and_reuse.xml