sablon 0.0.2 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1f2bdc7b8b84da3ad1a1893b515d23530fa6f597
4
- data.tar.gz: c872738213cbc5ebd926a9287512c40393a27fe2
3
+ metadata.gz: ac6584d3c9681b51c131bb10ae1f76fc0b1b5538
4
+ data.tar.gz: 80475970e6f321ef36650bf593f4e36e08a29101
5
5
  SHA512:
6
- metadata.gz: b12594e4647d2787ed4b8a2020ac44f668d2834f53cf8a16df4ff384fe52587386b8af8004cfdcb2c0da89d7c64481fb33363d1a59b43235cbb19f2b65f3bfa1
7
- data.tar.gz: 5a4ea402a07886f1009d24917ec850f7adef2d248511e2d5e93272794d0d49ff632af0554a2cd4cfcd1ddda7535db6f081e117d00b9d333f7e859b0abcaa5076
6
+ metadata.gz: 16e48b0a357ae6449daad1dbf7d26329e4616f103fa53c568ecb01bfd7b36a5830a70a773e83c4c2504c906bcfaddf9689926dbbe0b3d5f830edc8634d4c0a31
7
+ data.tar.gz: d56a4d4fcbeec941f44e0dd1f3dc96731a383c808cf3fc571a6cad71a6b13a98f057eba4a190215debe8c02d2e16bf93c48384fe8a815a2f0c5f614c3cf817d7
data/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # Sablon
2
2
 
3
- [![Build Status](https://travis-ci.org/senny/sablon.svg?branch=master)](https://travis-ci.org/senny/sablon)
3
+ [![Gem Version](https://badge.fury.io/rb/sablon.svg)](http://badge.fury.io/rb/sablon) [![Build Status](https://travis-ci.org/senny/sablon.svg?branch=master)](https://travis-ci.org/senny/sablon)
4
4
 
5
5
  Is a document template processor for Word `docx` files. It leverages Word's
6
6
  built-in formatting and layouting capabilities to make it easy to create your
7
7
  templates.
8
8
 
9
+ *Note: Sablon is still in early development. If you encounter any issues along the way please report.*
10
+
9
11
  ## Installation
10
12
 
11
13
  Add this line to your application's Gemfile:
@@ -8,6 +8,9 @@ require 'zip'
8
8
  require 'nokogiri'
9
9
 
10
10
  module Sablon
11
+ class TemplateError < ArgumentError; end
12
+ class ContextError < ArgumentError; end
13
+
11
14
  def self.template(path)
12
15
  Template.new(path)
13
16
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  module Sablon
2
3
  module Statement
3
4
  class Insertion < Struct.new(:expr, :field)
@@ -8,7 +9,10 @@ module Sablon
8
9
 
9
10
  class Loop < Struct.new(:list_expr, :iterator_name, :block)
10
11
  def evaluate(context)
11
- content = list_expr.evaluate(context).flat_map do |item|
12
+ value = list_expr.evaluate(context)
13
+ raise ContextError, "The expression #{list_expr.inspect} should evaluate to an enumerable but was: #{value.inspect}" unless value.is_a? Enumerable
14
+
15
+ content = value.flat_map do |item|
12
16
  iteration_context = context.merge(iterator_name => item)
13
17
  block.process(iteration_context)
14
18
  end
@@ -42,12 +46,20 @@ module Sablon
42
46
  def evaluate(context)
43
47
  context[name]
44
48
  end
49
+
50
+ def inspect
51
+ "«#{name}»"
52
+ end
45
53
  end
46
54
 
47
55
  class SimpleMethodCall < Struct.new(:receiver, :method)
48
56
  def evaluate(context)
49
57
  receiver.evaluate(context).public_send method
50
58
  end
59
+
60
+ def inspect
61
+ "«#{receiver.name}.#{method}»"
62
+ end
51
63
  end
52
64
 
53
65
  def self.parse(expression)
@@ -1,8 +1,10 @@
1
+ # -*- coding: utf-8 -*-
1
2
  module Sablon
2
3
  class Processor
3
4
  def self.process(xml_node, context, properties = {})
4
5
  processor = new(parser)
5
- processor.manipulate xml_node, context
6
+ stringified_context = Hash[context.map {|k, v| [k.to_s, v] }]
7
+ processor.manipulate xml_node, stringified_context
6
8
  processor.write_properties xml_node, properties if properties.any?
7
9
  xml_node
8
10
  end
@@ -141,7 +143,7 @@ module Sablon
141
143
  if end_field
142
144
  Block.enclosed_by start_field, end_field
143
145
  else
144
- raise "no end field for #{start_field.expression}. Was looking for #{end_expression}"
146
+ raise TemplateError, "Could not find end field for «#{start_field.expression}». Was looking for «#{end_expression}»"
145
147
  end
146
148
  end
147
149
  end
@@ -1,3 +1,3 @@
1
1
  module Sablon
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -2,14 +2,29 @@
2
2
  require "test_helper"
3
3
 
4
4
  class ExpressionTest < Sablon::TestCase
5
- def test_variable_expression
5
+ end
6
+
7
+ class VariableExpressionTest < Sablon::TestCase
8
+ def test_lookup_the_variable_in_the_context
6
9
  expr = Sablon::Expression.parse("first_name")
7
10
  assert_equal "Jane", expr.evaluate({"first_name" => "Jane", "last_name" => "Doe"})
8
11
  end
9
12
 
10
- def test_simple_method_call
13
+ def test_inspect
14
+ expr = Sablon::Expression.parse("first_name")
15
+ assert_equal "«first_name»", expr.inspect
16
+ end
17
+ end
18
+
19
+ class SimpleMethodCallTest < Sablon::TestCase
20
+ def test_calls_method_on_context_variable
11
21
  user = OpenStruct.new(first_name: "Jack")
12
22
  expr = Sablon::Expression.parse("user.first_name")
13
23
  assert_equal "Jack", expr.evaluate({"user" => user})
14
24
  end
25
+
26
+ def test_inspect
27
+ expr = Sablon::Expression.parse("user.first_name")
28
+ assert_equal "«user.first_name»", expr.inspect
29
+ end
15
30
  end
@@ -0,0 +1,22 @@
1
+ <w:r><w:t xml:space="preserve">Hello! My Name is </w:t></w:r>
2
+ <w:r w:rsidR="00BE47B1" w:rsidRPr="00BE47B1">
3
+ <w:rPr><w:b/></w:rPr>
4
+ <w:fldChar w:fldCharType="begin"/>
5
+ </w:r>
6
+ <w:r w:rsidR="00BE47B1" w:rsidRPr="00BE47B1">
7
+ <w:rPr><w:b/></w:rPr>
8
+ <w:instrText xml:space="preserve"> MERGEFIELD =last_name \* MERGEFORMAT </w:instrText>
9
+ </w:r>
10
+ <w:r w:rsidR="00BE47B1" w:rsidRPr="00BE47B1">
11
+ <w:rPr><w:b/></w:rPr>
12
+ <w:fldChar w:fldCharType="separate"/>
13
+ </w:r>
14
+ <w:r w:rsidR="004B49F0">
15
+ <w:rPr><w:b/><w:noProof/></w:rPr>
16
+ <w:t>«=last_name»</w:t>
17
+ </w:r>
18
+ <w:r w:rsidR="00BE47B1" w:rsidRPr="00BE47B1">
19
+ <w:rPr><w:b/></w:rPr>
20
+ <w:fldChar w:fldCharType="end"/>
21
+ </w:r>
22
+ <w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r>
@@ -0,0 +1,26 @@
1
+ <w:r><w:t xml:space="preserve">Anthony</w:t></w:r>
2
+ <w:p>
3
+ <w:fldSimple w:instr=" MERGEFIELD middle_name:if \* MERGEFORMAT ">
4
+ <w:r>
5
+ <w:rPr><w:noProof/></w:rPr>
6
+ <w:t>«middle_name:if»</w:t>
7
+ </w:r>
8
+ </w:fldSimple>
9
+ </w:p>
10
+ <w:p>
11
+ <w:fldSimple w:instr=" MERGEFIELD =middle_name \* MERGEFORMAT ">
12
+ <w:r>
13
+ <w:rPr><w:noProof/></w:rPr>
14
+ <w:t>«=middle_name»</w:t>
15
+ </w:r>
16
+ </w:fldSimple>
17
+ </w:p>
18
+ <w:p>
19
+ <w:fldSimple w:instr=" MERGEFIELD middle_name:endIf \* MERGEFORMAT ">
20
+ <w:r>
21
+ <w:rPr><w:noProof/></w:rPr>
22
+ <w:t>«middle_name:endIf»</w:t>
23
+ </w:r>
24
+ </w:fldSimple>
25
+ </w:p>
26
+ <w:r><w:t xml:space="preserve">Hall</w:t></w:r>
@@ -0,0 +1,19 @@
1
+ <w:p>
2
+ <w:fldSimple w:instr=" MERGEFIELD body:if(empty?) \* MERGEFORMAT ">
3
+ <w:r>
4
+ <w:rPr><w:noProof/></w:rPr>
5
+ <w:t>«body:if(empty?)»</w:t>
6
+ </w:r>
7
+ </w:fldSimple>
8
+ </w:p>
9
+ <w:p>
10
+ <w:t>some content</w:t>
11
+ </w:p>
12
+ <w:p>
13
+ <w:fldSimple w:instr=" MERGEFIELD body:endIf \* MERGEFORMAT ">
14
+ <w:r>
15
+ <w:rPr><w:noProof/></w:rPr>
16
+ <w:t>«body:endIf»</w:t>
17
+ </w:r>
18
+ </w:fldSimple>
19
+ </w:p>
@@ -0,0 +1,18 @@
1
+ <w:r><w:t xml:space="preserve">Anthony</w:t></w:r>
2
+ <w:p>
3
+ <w:fldSimple w:instr=" MERGEFIELD middle_name:if \* MERGEFORMAT ">
4
+ <w:r>
5
+ <w:rPr><w:noProof/></w:rPr>
6
+ <w:t>«middle_name:if»</w:t>
7
+ </w:r>
8
+ </w:fldSimple>
9
+ </w:p>
10
+ <w:p>
11
+ <w:fldSimple w:instr=" MERGEFIELD =middle_name \* MERGEFORMAT ">
12
+ <w:r>
13
+ <w:rPr><w:noProof/></w:rPr>
14
+ <w:t>«=middle_name»</w:t>
15
+ </w:r>
16
+ </w:fldSimple>
17
+ </w:p>
18
+ <w:r><w:t xml:space="preserve">Hall</w:t></w:r>
@@ -0,0 +1,26 @@
1
+ <w:r>
2
+ <w:t xml:space="preserve">Hello! My Name is </w:t>
3
+ </w:r>
4
+ <w:r w:rsidR="003C4780">
5
+ <w:fldChar w:fldCharType="begin" />
6
+ </w:r>
7
+ <w:r w:rsidR="003C4780">
8
+ <w:instrText xml:space="preserve"> MERGEFIELD </w:instrText>
9
+ </w:r>
10
+ <w:r w:rsidR="003A4504">
11
+ <w:instrText>=</w:instrText>
12
+ </w:r>
13
+ <w:r w:rsidR="003C4780">
14
+ <w:instrText xml:space="preserve">first_name \* MERGEFORMAT </w:instrText>
15
+ </w:r>
16
+ <w:r w:rsidR="003C4780">
17
+ <w:fldChar w:fldCharType="separate" />
18
+ </w:r>
19
+ <w:r w:rsidR="00441382">
20
+ <w:rPr><w:noProof /></w:rPr>
21
+ <w:t>«=person.first_name»</w:t>
22
+ </w:r>
23
+ <w:r w:rsidR="003C4780">
24
+ <w:fldChar w:fldCharType="end" />
25
+ </w:r>
26
+ <w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r>
@@ -0,0 +1,46 @@
1
+ <w:p w14:paraId="6CB29D92" w14:textId="164B70F4" w:rsidR="007F5CDE" w:rsidRDefault="007F5CDE" w:rsidP="007F5CDE">
2
+ <w:pPr>
3
+ <w:pStyle w:val="ListParagraph" />
4
+ <w:numPr>
5
+ <w:ilvl w:val="0" />
6
+ <w:numId w:val="1" />
7
+ </w:numPr>
8
+ </w:pPr>
9
+ <w:fldSimple w:instr=" MERGEFIELD technologies:each(technology) \* MERGEFORMAT ">
10
+ <w:r>
11
+ <w:rPr><w:noProof /></w:rPr>
12
+ <w:t>«technologies:each(technology)»</w:t>
13
+ </w:r>
14
+ </w:fldSimple>
15
+ </w:p>
16
+ <w:p w14:paraId="1081E316" w14:textId="3EAB5FDC" w:rsidR="00380EE8" w:rsidRDefault="00380EE8" w:rsidP="007F5CDE">
17
+ <w:pPr>
18
+ <w:pStyle w:val="ListParagraph" />
19
+ <w:numPr>
20
+ <w:ilvl w:val="0" />
21
+ <w:numId w:val="1" />
22
+ </w:numPr>
23
+ </w:pPr>
24
+ <w:r>
25
+ <w:fldChar w:fldCharType="begin" />
26
+ </w:r>
27
+ <w:r>
28
+ <w:instrText xml:space="preserve"> </w:instrText>
29
+ </w:r>
30
+ <w:r w:rsidR="009F01DA">
31
+ <w:instrText>MERGEFIELD =technology</w:instrText>
32
+ </w:r>
33
+ <w:r>
34
+ <w:instrText xml:space="preserve"> \* MERGEFORMAT </w:instrText>
35
+ </w:r>
36
+ <w:r>
37
+ <w:fldChar w:fldCharType="separate" />
38
+ </w:r>
39
+ <w:r w:rsidR="009F01DA">
40
+ <w:rPr><w:noProof /></w:rPr>
41
+ <w:t>«=technology»</w:t>
42
+ </w:r>
43
+ <w:r>
44
+ <w:fldChar w:fldCharType="end" />
45
+ </w:r>
46
+ </w:p>
@@ -0,0 +1,61 @@
1
+ <w:p w14:paraId="6CB29D92" w14:textId="164B70F4" w:rsidR="007F5CDE" w:rsidRDefault="007F5CDE" w:rsidP="007F5CDE">
2
+ <w:pPr>
3
+ <w:pStyle w:val="ListParagraph" />
4
+ <w:numPr>
5
+ <w:ilvl w:val="0" />
6
+ <w:numId w:val="1" />
7
+ </w:numPr>
8
+ </w:pPr>
9
+ <w:fldSimple w:instr=" MERGEFIELD technologies:each(technology) \* MERGEFORMAT ">
10
+ <w:r>
11
+ <w:rPr><w:noProof /></w:rPr>
12
+ <w:t>«technologies:each(technology)»</w:t>
13
+ </w:r>
14
+ </w:fldSimple>
15
+ </w:p>
16
+ <w:p w14:paraId="1081E316" w14:textId="3EAB5FDC" w:rsidR="00380EE8" w:rsidRDefault="00380EE8" w:rsidP="007F5CDE">
17
+ <w:pPr>
18
+ <w:pStyle w:val="ListParagraph" />
19
+ <w:numPr>
20
+ <w:ilvl w:val="0" />
21
+ <w:numId w:val="1" />
22
+ </w:numPr>
23
+ </w:pPr>
24
+ <w:r>
25
+ <w:fldChar w:fldCharType="begin" />
26
+ </w:r>
27
+ <w:r>
28
+ <w:instrText xml:space="preserve"> </w:instrText>
29
+ </w:r>
30
+ <w:r w:rsidR="009F01DA">
31
+ <w:instrText>MERGEFIELD =technology</w:instrText>
32
+ </w:r>
33
+ <w:r>
34
+ <w:instrText xml:space="preserve"> \* MERGEFORMAT </w:instrText>
35
+ </w:r>
36
+ <w:r>
37
+ <w:fldChar w:fldCharType="separate" />
38
+ </w:r>
39
+ <w:r w:rsidR="009F01DA">
40
+ <w:rPr><w:noProof /></w:rPr>
41
+ <w:t>«=technology»</w:t>
42
+ </w:r>
43
+ <w:r>
44
+ <w:fldChar w:fldCharType="end" />
45
+ </w:r>
46
+ </w:p>
47
+ <w:p w14:paraId="7F936853" w14:textId="078377AD" w:rsidR="00380EE8" w:rsidRPr="007F5CDE" w:rsidRDefault="00380EE8" w:rsidP="007F5CDE">
48
+ <w:pPr>
49
+ <w:pStyle w:val="ListParagraph" />
50
+ <w:numPr>
51
+ <w:ilvl w:val="0" />
52
+ <w:numId w:val="1" />
53
+ </w:numPr>
54
+ </w:pPr>
55
+ <w:fldSimple w:instr=" MERGEFIELD technologies:endEach \* MERGEFORMAT ">
56
+ <w:r>
57
+ <w:rPr><w:noProof /></w:rPr>
58
+ <w:t>«technologies:endEach»</w:t>
59
+ </w:r>
60
+ </w:fldSimple>
61
+ </w:p>
@@ -0,0 +1,33 @@
1
+ <w:tbl>
2
+ <w:tblGrid>
3
+ <w:gridCol w:w="2202"/>
4
+ </w:tblGrid>
5
+ <w:tr w:rsidR="00757DAD">
6
+ <w:tc>
7
+ <w:p>
8
+ <w:fldSimple w:instr=" MERGEFIELD technologies:each(technology) \* MERGEFORMAT ">
9
+ <w:r w:rsidR="004B49F0">
10
+ <w:rPr><w:noProof/></w:rPr>
11
+ <w:t>«technologies:each(technology)»</w:t>
12
+ </w:r>
13
+ </w:fldSimple>
14
+ </w:p>
15
+ <w:p>
16
+ <w:fldSimple w:instr=" MERGEFIELD =technology \* MERGEFORMAT ">
17
+ <w:r w:rsidR="004B49F0">
18
+ <w:rPr><w:noProof/></w:rPr>
19
+ <w:t>«=technology»</w:t>
20
+ </w:r>
21
+ </w:fldSimple>
22
+ </w:p>
23
+ <w:p>
24
+ <w:fldSimple w:instr=" MERGEFIELD technologies:endEach \* MERGEFORMAT ">
25
+ <w:r w:rsidR="004B49F0">
26
+ <w:rPr><w:noProof/></w:rPr>
27
+ <w:t>«technologies:endEach»</w:t>
28
+ </w:r>
29
+ </w:fldSimple>
30
+ </w:p>
31
+ </w:tc>
32
+ </w:tr>
33
+ </w:tbl>
@@ -0,0 +1,8 @@
1
+ <w:r><w:t xml:space="preserve">Hello! My Name is </w:t></w:r>
2
+ <w:fldSimple w:instr=" MERGEFIELD =first_name \* MERGEFORMAT ">
3
+ <w:r w:rsidR="004B49F0">
4
+ <w:rPr><w:noProof/></w:rPr>
5
+ <w:t>«=first_name»</w:t>
6
+ </w:r>
7
+ </w:fldSimple>
8
+ <w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r>
@@ -0,0 +1,12 @@
1
+ <w:fldSimple w:instr=" MERGEFIELD =first_name \* MERGEFORMAT ">
2
+ <w:r w:rsidR="004B49F0">
3
+ <w:rPr><w:noProof/></w:rPr>
4
+ <w:t>«=first_name»</w:t>
5
+ </w:r>
6
+ </w:fldSimple>
7
+ <w:fldSimple w:instr=" MERGEFIELD =last_name \* MERGEFORMAT ">
8
+ <w:r w:rsidR="004B49F0">
9
+ <w:rPr><w:noProof/></w:rPr>
10
+ <w:t>«=last_name»</w:t>
11
+ </w:r>
12
+ </w:fldSimple>
@@ -0,0 +1,124 @@
1
+ <w:tbl>
2
+ <w:tr w:rsidR="00F23752" w14:paraId="3FF89DEC" w14:textId="77777777" w:rsidTr="00213ACD">
3
+ <w:tc>
4
+ <w:tcPr>
5
+ <w:tcW w:w="2235" w:type="dxa" />
6
+ <w:shd w:val="clear" w:color="auto" w:fill="auto" />
7
+ </w:tcPr>
8
+ <w:p w14:paraId="7630A6C6" w14:textId="699D0C71" w:rsidR="00F23752" w:rsidRDefault="00F23752" w:rsidP="003F16E3">
9
+ <w:fldSimple w:instr=" MERGEFIELD foods:each(food) \* MERGEFORMAT ">
10
+ <w:r w:rsidR="00213ACD">
11
+ <w:rPr><w:noProof /></w:rPr>
12
+ <w:t>«foods:each(food)»</w:t>
13
+ </w:r>
14
+ </w:fldSimple>
15
+ </w:p>
16
+ </w:tc>
17
+ <w:tc>
18
+ <w:tcPr>
19
+ <w:tcW w:w="6287" w:type="dxa" />
20
+ <w:shd w:val="clear" w:color="auto" w:fill="auto" />
21
+ </w:tcPr>
22
+ <w:p w14:paraId="437AFC74" w14:textId="77777777" w:rsidR="00F23752" w:rsidRDefault="00F23752" w:rsidP="003F16E3" />
23
+ </w:tc>
24
+ </w:tr>
25
+ <w:tr w:rsidR="00F23752" w14:paraId="320AE02B" w14:textId="77777777" w:rsidTr="00213ACD">
26
+ <w:tc>
27
+ <w:tcPr>
28
+ <w:tcW w:w="2235" w:type="dxa" />
29
+ <w:shd w:val="clear" w:color="auto" w:fill="8DB3E2" w:themeFill="text2" w:themeFillTint="66" />
30
+ </w:tcPr>
31
+ <w:p w14:paraId="3FCF3855" w14:textId="38FA7F3B" w:rsidR="00F23752" w:rsidRDefault="00F23752" w:rsidP="00F23752">
32
+ <w:fldSimple w:instr=" MERGEFIELD =food.index \* MERGEFORMAT ">
33
+ <w:r w:rsidR="00213ACD">
34
+ <w:rPr><w:noProof /></w:rPr>
35
+ <w:t>«=food.index»</w:t>
36
+ </w:r>
37
+ </w:fldSimple>
38
+ </w:p>
39
+ </w:tc>
40
+ <w:tc>
41
+ <w:tcPr>
42
+ <w:tcW w:w="6287" w:type="dxa" />
43
+ <w:shd w:val="clear" w:color="auto" w:fill="8DB3E2" w:themeFill="text2" w:themeFillTint="66" />
44
+ </w:tcPr>
45
+ <w:p w14:paraId="0BB0E74E" w14:textId="4FA0D282" w:rsidR="00F23752" w:rsidRPr="00F576DA" w:rsidRDefault="00F23752" w:rsidP="00F23752">
46
+ <w:r w:rsidRPr="00F576DA">
47
+ <w:fldChar w:fldCharType="begin" />
48
+ </w:r>
49
+ <w:r w:rsidRPr="00F576DA">
50
+ <w:instrText xml:space="preserve"> MERGEFIELD =</w:instrText>
51
+ </w:r>
52
+ <w:r>
53
+ <w:instrText>food</w:instrText>
54
+ </w:r>
55
+ <w:r w:rsidRPr="00F576DA">
56
+ <w:instrText xml:space="preserve">.label \* MERGEFORMAT </w:instrText>
57
+ </w:r>
58
+ <w:r w:rsidRPr="00F576DA">
59
+ <w:fldChar w:fldCharType="separate" />
60
+ </w:r>
61
+ <w:r w:rsidR="00213ACD">
62
+ <w:rPr>
63
+ <w:rFonts w:ascii="Comic Sans MS" w:hAnsi="Comic Sans MS" />
64
+ <w:noProof />
65
+ </w:rPr>
66
+ <w:t>«=food.label»</w:t>
67
+ </w:r>
68
+ <w:r w:rsidRPr="00F576DA">
69
+ <w:fldChar w:fldCharType="end" />
70
+ </w:r>
71
+ </w:p>
72
+ </w:tc>
73
+ </w:tr>
74
+ <w:tr w:rsidR="00213ACD" w14:paraId="1EA188ED" w14:textId="77777777" w:rsidTr="00213ACD">
75
+ <w:tc>
76
+ <w:tcPr>
77
+ <w:tcW w:w="8522" w:type="dxa" />
78
+ <w:gridSpan w:val="2" />
79
+ <w:shd w:val="clear" w:color="auto" w:fill="auto" />
80
+ </w:tcPr>
81
+ <w:p w14:paraId="3E9FF163" w14:textId="0F37CDFB" w:rsidR="00213ACD" w:rsidRDefault="00213ACD" w:rsidP="003F16E3">
82
+ <w:fldSimple w:instr=" MERGEFIELD =food.body \* MERGEFORMAT ">
83
+ <w:r>
84
+ <w:rPr><w:noProof /></w:rPr>
85
+ <w:t>«=food.body»</w:t>
86
+ </w:r>
87
+ </w:fldSimple>
88
+ </w:p>
89
+ </w:tc>
90
+ </w:tr>
91
+ <w:tr w:rsidR="00213ACD" w14:paraId="34315A41" w14:textId="77777777" w:rsidTr="00213ACD">
92
+ <w:tc>
93
+ <w:tcPr>
94
+ <w:tcW w:w="2235" w:type="dxa" />
95
+ <w:shd w:val="clear" w:color="auto" w:fill="auto" />
96
+ </w:tcPr>
97
+ <w:p w14:paraId="1CA83F76" w14:textId="2622C490" w:rsidR="00213ACD" w:rsidRDefault="00213ACD" w:rsidP="003F16E3">
98
+ <w:r>
99
+ <w:fldChar w:fldCharType="begin" />
100
+ </w:r>
101
+ <w:r>
102
+ <w:instrText xml:space="preserve"> MERGEFIELD foods:endEach \* MERGEFORMAT </w:instrText>
103
+ </w:r>
104
+ <w:r>
105
+ <w:fldChar w:fldCharType="separate" />
106
+ </w:r>
107
+ <w:r>
108
+ <w:rPr><w:noProof /></w:rPr>
109
+ <w:t>«foods:endEach»</w:t>
110
+ </w:r>
111
+ <w:r>
112
+ <w:fldChar w:fldCharType="end" />
113
+ </w:r>
114
+ </w:p>
115
+ </w:tc>
116
+ <w:tc>
117
+ <w:tcPr>
118
+ <w:tcW w:w="6287" w:type="dxa" />
119
+ <w:shd w:val="clear" w:color="auto" w:fill="auto" />
120
+ </w:tcPr>
121
+ <w:p w14:paraId="7D976602" w14:textId="77777777" w:rsidR="00213ACD" w:rsidRDefault="00213ACD" w:rsidP="003F16E3" />
122
+ </w:tc>
123
+ </w:tr>
124
+ </w:tbl>