isodoc 1.8.1 → 1.8.2

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
  SHA256:
3
- metadata.gz: ec504b3b905ec960bef74398b3789ab5b7eb248dc05a7c3f64590db77d31cac6
4
- data.tar.gz: c2de4c1589a7ff282715f4930a1851393358a64fd407c5a1e3bda02beddc0782
3
+ metadata.gz: 38ce5f3d119cf53361811f16b0ff8ed4108116c02e0816ab5ba31846934c3c29
4
+ data.tar.gz: 5ffb61e6729edb93e5e3ba1916e531bf7e1511bfdbd5fe0e0cd1405590971c4d
5
5
  SHA512:
6
- metadata.gz: 34a1c43f6f34f90aa326ed7ff50ede791eadaf22c05ebf0f4183fb2cb3c708bd4f0512572b638a94e236b807f5a873986c24579fe126eb88ad15ef1e178c64d2
7
- data.tar.gz: 23fbe4f295729ad565ab787903e9c4b49388671766b91477dc3d26302b8499da892f77d6e034ce4f6cc4ba1b0956c8dbb051e94a3a336acdb661d1e6d30e584b
6
+ metadata.gz: e023cfd0d05068daf11e4ccf5c6aab29ff037ec562b65e65f769f7d64c9d4a6c681895dfba5539a2b8a8ee310facba56dad371a21a5f0ced621ebacbf64a8ddf
7
+ data.tar.gz: 6412c5b7f2b11c4eedf1ab840461a703d1342e148ae89607ea30bb7faff05591aa33132dd2a1b660a92a0e3466060ef404cab4564c5a10bd909843293b4c9ad1
data/isodoc.gemspec CHANGED
@@ -43,7 +43,7 @@ Gem::Specification.new do |spec|
43
43
  spec.add_dependency "twitter_cldr", ">= 6.6.0"
44
44
  spec.add_dependency "uuidtools"
45
45
 
46
- spec.add_development_dependency "byebug", "~> 9.1"
46
+ spec.add_development_dependency "debug"
47
47
  spec.add_development_dependency "equivalent-xml", "~> 0.6"
48
48
  spec.add_development_dependency "guard", "~> 2.14"
49
49
  spec.add_development_dependency "guard-rspec", "~> 4.7"
@@ -16,7 +16,7 @@ module IsoDoc
16
16
  xpath.gsub(%r{/([a-zA-z])}, "/xmlns:\\1")
17
17
  .gsub(%r{::([a-zA-z])}, "::xmlns:\\1")
18
18
  .gsub(%r{\[([a-zA-z][a-z0-9A-Z@/]* ?=)}, "[xmlns:\\1")
19
- .gsub(%r{\[([a-zA-z][a-z0-9A-Z@/]*\])}, "[xmlns:\\1")
19
+ .gsub(%r{\[([a-zA-z][a-z0-9A-Z@/]*[/\]])}, "[xmlns:\\1")
20
20
  end
21
21
 
22
22
  def liquid(doc)
@@ -5,7 +5,7 @@ module IsoDoc
5
5
  module Inline
6
6
  def link_parse(node, out)
7
7
  url = node["target"]
8
- node["updatetype"] == "true" and url = suffix_url(url)
8
+ node["update-type"] == "true" and url = suffix_url(url)
9
9
  out.a **attr_code(href: url, title: node["alt"]) do |l|
10
10
  if node.text.empty?
11
11
  l << node["target"].sub(/^mailto:/, "")
@@ -28,11 +28,7 @@ module IsoDoc
28
28
  ref = node.at(ns("./xref | ./eref | ./termref"))
29
29
  ref && opts[:ref] != "false" and r&.next = " "
30
30
  opts[:ital] == "true" and r&.name = "em"
31
- if opts[:linkmention] == "true" && !r.nil? && !ref.nil?
32
- ref2 = ref.clone
33
- r2 = r.clone
34
- r.replace(ref2).children = r2
35
- end
31
+ concept1_linkmention(ref, r, opts)
36
32
  concept1_ref(node, ref, opts)
37
33
  if opts[:ital] == "false"
38
34
  r = node.at(ns(".//renderterm"))
@@ -41,6 +37,14 @@ module IsoDoc
41
37
  node.replace(node.children)
42
38
  end
43
39
 
40
+ def concept1_linkmention(ref, renderterm, opts)
41
+ if opts[:linkmention] == "true" && !renderterm.nil? && !ref.nil?
42
+ ref2 = ref.clone
43
+ r2 = renderterm.clone
44
+ renderterm.replace(ref2).children = r2
45
+ end
46
+ end
47
+
44
48
  def concept1_ref(_node, ref, opts)
45
49
  ref.nil? and return
46
50
  return ref.remove if opts[:ref] == "false"
@@ -78,39 +82,71 @@ module IsoDoc
78
82
  end
79
83
 
80
84
  def designation(docxml)
81
- docxml.xpath(ns("//preferred | //admitted | //deprecates")).each do |p|
82
- designation1(p)
83
- end
84
85
  docxml.xpath(ns("//term")).each do |t|
85
86
  merge_second_preferred(t)
86
87
  end
88
+ docxml.xpath(ns("//preferred | //admitted | //deprecates")).each do |p|
89
+ designation1(p)
90
+ end
87
91
  end
88
92
 
89
93
  def merge_second_preferred(term)
90
94
  pref = nil
91
- term.xpath(ns("./preferred")).each_with_index do |p, i|
95
+ term.xpath(ns("./preferred[expression/name]")).each_with_index do |p, i|
92
96
  if i.zero? then pref = p
93
- else
94
- pref << l10n("; #{p.children.to_xml}")
97
+ elsif merge_preferred_eligible?(pref, p)
98
+ pref.at(ns("./expression/name")) <<
99
+ l10n("; #{p.at(ns('./expression/name')).children.to_xml}")
95
100
  p.remove
96
101
  end
97
102
  end
98
103
  end
99
104
 
105
+ def merge_preferred_eligible?(first, second)
106
+ firstex = first.at(ns("./expression")) || {}
107
+ secondex = second.at(ns("./expression")) || {}
108
+ first["geographic-area"] == second["geographic-area"] &&
109
+ firstex["language"] == secondex["language"] &&
110
+ !first.at(ns("./pronunciation | ./grammar")) &&
111
+ !second.at(ns("./pronunciation | ./grammar"))
112
+ end
113
+
100
114
  def designation1(desgn)
101
115
  s = desgn.at(ns("./termsource"))
102
116
  name = desgn.at(ns("./expression/name | ./letter-symbol/name | "\
103
117
  "./graphical-symbol")) or return
104
118
 
119
+ designation_annotate(desgn, name)
120
+ s and desgn.next = s
121
+ end
122
+
123
+ def designation_annotate(desgn, name)
124
+ designation_boldface(desgn)
125
+ designation_field(desgn, name)
105
126
  g = desgn.at(ns("./expression/grammar")) and
106
- name << " #{designation_grammar(g).join(', ')}"
127
+ name << ", #{designation_grammar(g).join(', ')}"
128
+ designation_localization(desgn, name)
129
+ designation_pronunciation(desgn, name)
107
130
  desgn.children = name.children
108
- s and desgn.next = s
131
+ end
132
+
133
+ def designation_boldface(desgn)
134
+ desgn.name == "preferred" or return
135
+ name = desgn.at(ns("./expression/name | ./letter-symbol/name")) or return
136
+ name.children = "<strong>#{name.children}</strong>"
137
+ end
138
+
139
+ def designation_field(desgn, name)
140
+ f = desgn.xpath(ns("./field-of-application | ./usage-info"))
141
+ &.map { |u| u.children.to_xml }&.join(", ")
142
+ return nil if f&.empty?
143
+
144
+ name << ", &lt;#{f}&gt;"
109
145
  end
110
146
 
111
147
  def designation_grammar(grammar)
112
148
  ret = []
113
- grammar.xpath(ns("./gender")).each do |x|
149
+ grammar.xpath(ns("./gender | ./number")).each do |x|
114
150
  ret << @i18n.grammar_abbrevs[x.text]
115
151
  end
116
152
  %w(isPreposition isParticiple isAdjective isVerb isAdverb isNoun)
@@ -121,20 +157,28 @@ module IsoDoc
121
157
  ret
122
158
  end
123
159
 
124
- def definition1(elem)
125
- nodes = Nokogiri::XML::NodeSet.new(elem.document)
126
- v = elem&.at(ns("./verbaldefinition"))&.children and nodes += v
127
- n = elem&.at(ns("./nonverbalrepresentation"))&.children and nodes += n
128
- elem.children = nodes
129
- end
160
+ def designation_localization(desgn, name)
161
+ loc = [desgn&.at(ns("./expression/@language"))&.text,
162
+ desgn&.at(ns("./expression/@script"))&.text,
163
+ desgn&.at(ns("./@geographic-area"))&.text].compact
164
+ return if loc.empty?
165
+
166
+ name << ", #{loc.join(' ')}"
167
+ end
168
+
169
+ def designation_pronunciation(desgn, name)
170
+ f = desgn.at(ns("./expression/pronunciation")) or return
171
+
172
+ name << ", /#{f.children.to_xml}/"
173
+ end
130
174
 
131
- def termexample(docxml)
175
+ def termexample(docxml)
132
176
  docxml.xpath(ns("//termexample")).each do |f|
133
177
  example1(f)
134
178
  end
135
179
  end
136
180
 
137
- def termnote(docxml)
181
+ def termnote(docxml)
138
182
  docxml.xpath(ns("//termnote")).each do |f|
139
183
  termnote1(f)
140
184
  end
@@ -155,7 +199,7 @@ module IsoDoc
155
199
  def termdefinition1(elem)
156
200
  unwrap_definition(elem)
157
201
  multidef(elem) if elem.xpath(ns("./definition")).size > 1
158
- end
202
+ end
159
203
 
160
204
  def multidef(elem)
161
205
  d = elem.at(ns("./definition"))
@@ -167,13 +211,13 @@ module IsoDoc
167
211
  d.wrap("<definition></definition>")
168
212
  end
169
213
 
170
- def unwrap_definition(elem)
171
- elem.xpath(ns("./definition")).each do |d|
172
- nodes = Nokogiri::XML::NodeSet.new(elem.document)
173
- v = d&.at(ns("./verbaldefinition"))&.children and nodes += v
174
- n = d&.at(ns("./nonverbalrepresentation"))&.children and nodes += n
175
- d.children = nodes
176
- end
214
+ def unwrap_definition(elem)
215
+ elem.xpath(ns("./definition")).each do |d|
216
+ %w(verbal-definition non-verbal-representation).each do |e|
217
+ v = d&.at(ns("./#{e}"))
218
+ v&.replace(v.children)
177
219
  end
220
+ end
221
+ end
178
222
  end
179
223
  end
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.8.1".freeze
2
+ VERSION = "1.8.2".freeze
3
3
  end
@@ -94,6 +94,9 @@ grammar_abbrevs:
94
94
  feminine: مؤ
95
95
  neuter: محايد
96
96
  common: خنثى
97
+ singular: مفرد
98
+ dual: مزدوج
99
+ plural: جمع
97
100
  isPreposition: حرف جر
98
101
  isParticiple: النعت
99
102
  isAdjective: صفة
@@ -98,6 +98,9 @@ grammar_abbrevs:
98
98
  feminine: fem
99
99
  neuter: neutr
100
100
  common: gemein
101
+ singular: Sg
102
+ dual: Dual
103
+ plural: Pl
101
104
  isPreposition: Präp
102
105
  isParticiple: Part
103
106
  isAdjective: Adj
@@ -100,16 +100,19 @@ locality: {
100
100
  formula: Formula
101
101
  }
102
102
  grammar_abbrevs:
103
- masculine: masc
104
- feminine: fem
105
- neuter: neut
103
+ masculine: m
104
+ feminine: f
105
+ neuter: n
106
106
  common: common
107
+ singular: sg
108
+ dual: dual
109
+ pl: pl
107
110
  isPreposition: prep
108
111
  isParticiple: part
109
112
  isAdjective: adj
110
113
  isAdverb: adv
111
- isNoun: n
112
- isVerb: v
114
+ isNoun: noun
115
+ isVerb: verb
113
116
  relatedterms:
114
117
  deprecates: deprecates
115
118
  supersedes: supersedes
@@ -100,6 +100,9 @@ grammar_abbrevs:
100
100
  feminine: fem
101
101
  neuter: neut
102
102
  common: epicen@
103
+ singular: sg
104
+ dual: dual
105
+ plural: pl
103
106
  isPreposition: prep
104
107
  isParticiple: part
105
108
  isAdjective: adj
@@ -97,6 +97,9 @@ grammar_abbrevs:
97
97
  feminine: fem
98
98
  neuter: neut
99
99
  common: épicène
100
+ singular: sg
101
+ dual: duel
102
+ plural: pl
100
103
  isPreposition: prép
101
104
  isParticiple: part
102
105
  isAdjective: adj
@@ -103,6 +103,9 @@ grammar_abbrevs:
103
103
  feminine: жен
104
104
  neuter: ср
105
105
  common: общего рода
106
+ singular: ед
107
+ dual: дв
108
+ plural: мн
106
109
  isPreposition: предл
107
110
  isParticiple: прич
108
111
  isAdjective: прил
@@ -98,6 +98,9 @@ grammar_abbrevs:
98
98
  feminine: 阴性
99
99
  neuter: 中性的
100
100
  common: 通性
101
+ singular: 单数
102
+ dual: 双
103
+ plural: 复数
101
104
  isPreposition: 介词
102
105
  isParticiple: 分词
103
106
  isAdjective: 形容词
@@ -88,7 +88,7 @@ RSpec.describe IsoDoc do
88
88
  <clause id="H" obligation="normative" displayorder="5"><title depth="1">3.<tab/>Terms, definitions, symbols and abbreviated terms</title><terms id="I" obligation="normative">
89
89
  <title depth="2">3.1.<tab/>Normal Terms</title>
90
90
  <term id="J"><name>3.1.1.</name>
91
- <preferred>Term2</preferred>
91
+ <preferred><strong>Term2</strong></preferred>
92
92
  </term>
93
93
  </terms>
94
94
  <definitions id="K"><title>3.2.</title>
@@ -159,7 +159,7 @@ RSpec.describe IsoDoc do
159
159
  <div id="I">
160
160
  <h2>3.1.&#160; Normal Terms</h2>
161
161
  <p class="TermNum" id="J">3.1.1.</p>
162
- <p class="Terms" style="text-align:left;">Term2</p>
162
+ <p class="Terms" style="text-align:left;"><b>Term2</b></p>
163
163
  </div><div id="K"><h2>3.2.</h2>
164
164
  <dl><dt><p>Symbol</p></dt><dd>Definition</dd></dl>
165
165
  </div></div>
@@ -211,7 +211,7 @@ RSpec.describe IsoDoc do
211
211
  end
212
212
 
213
213
  it "defaults to English" do
214
- expect(xmlpp(IsoDoc::PresentationXMLConvert.new({}).convert("test", <<~"INPUT", true).sub(%r{<localized-strings>.*</localized-strings>}m, ""))).to be_equivalent_to xmlpp(<<~"OUTPUT")
214
+ input = <<~INPUT
215
215
  <iso-standard xmlns="http://riboseinc.com/isoxml">
216
216
  <bibdata>
217
217
  <language>tlh</language>
@@ -275,6 +275,7 @@ RSpec.describe IsoDoc do
275
275
  </bibliography>
276
276
  </iso-standard>
277
277
  INPUT
278
+ output = <<~OUTPUT
278
279
  <iso-standard xmlns="http://riboseinc.com/isoxml" type="presentation">
279
280
  <bibdata>
280
281
  <language current="true">tlh</language>
@@ -295,7 +296,7 @@ RSpec.describe IsoDoc do
295
296
  <clause id="H" obligation="normative" displayorder="5"><title depth="1">3.<tab/>Terms, definitions, symbols and abbreviated terms</title><terms id="I" obligation="normative">
296
297
  <title depth="2">3.1.<tab/>Normal Terms</title>
297
298
  <term id="J"><name>3.1.1.</name>
298
- <preferred>Term2</preferred>
299
+ <preferred><strong>Term2</strong></preferred>
299
300
  </term>
300
301
  </terms>
301
302
  <definitions id="K"><title>3.2.</title>
@@ -336,6 +337,10 @@ RSpec.describe IsoDoc do
336
337
  </bibliography>
337
338
  </iso-standard>
338
339
  OUTPUT
340
+ expect(xmlpp(IsoDoc::PresentationXMLConvert.new({})
341
+ .convert("test", input, true)
342
+ .sub(%r{<localized-strings>.*</localized-strings>}m, "")))
343
+ .to be_equivalent_to xmlpp(output)
339
344
  end
340
345
 
341
346
  it "processes French" do
@@ -425,7 +430,7 @@ RSpec.describe IsoDoc do
425
430
  <clause id="H" obligation="normative" displayorder="5"><title depth="1">3.<tab/>Terms, definitions, symbols and abbreviated terms</title><terms id="I" obligation="normative">
426
431
  <title depth="2">3.1.<tab/>Normal Terms</title>
427
432
  <term id="J"><name>3.1.1.</name>
428
- <preferred>Term2</preferred>
433
+ <preferred><strong>Term2</strong></preferred>
429
434
  </term>
430
435
  </terms>
431
436
  <definitions id="K"><title>3.2.</title>
@@ -496,7 +501,7 @@ RSpec.describe IsoDoc do
496
501
  <div id="I">
497
502
  <h2>3.1.&#160; Normal Terms</h2>
498
503
  <p class="TermNum" id="J">3.1.1.</p>
499
- <p class="Terms" style="text-align:left;">Term2</p>
504
+ <p class="Terms" style="text-align:left;"><b>Term2</b></p>
500
505
  </div><div id="K"><h2>3.2.</h2>
501
506
  <dl><dt><p>Symbol</p></dt><dd>Definition</dd></dl>
502
507
  </div></div>
@@ -644,7 +649,7 @@ RSpec.describe IsoDoc do
644
649
  <clause id="H" obligation="normative" displayorder="5"><title depth="1">3.<tab/>Terms, definitions, symbols and abbreviated terms</title><terms id="I" obligation="normative">
645
650
  <title depth="2">3.1.<tab/>Normal Terms</title>
646
651
  <term id="J"><name>3.1.1.</name>
647
- <preferred>Term2</preferred>
652
+ <preferred><strong>Term2</strong></preferred>
648
653
  </term>
649
654
  </terms>
650
655
  <definitions id="K"><title>3.2.</title>
@@ -728,7 +733,7 @@ RSpec.describe IsoDoc do
728
733
  <div id="I">
729
734
  <h2>3.1.&#12288;Normal Terms</h2>
730
735
  <p class="TermNum" id="J">3.1.1.</p>
731
- <p class="Terms" style="text-align:left;">Term2</p>
736
+ <p class="Terms" style="text-align:left;"><b>Term2</b></p>
732
737
  </div><div id="K"><h2>3.2.</h2>
733
738
  <dl><dt><p>Symbol</p></dt><dd>Definition</dd></dl>
734
739
  </div></div>
@@ -896,7 +901,7 @@ RSpec.describe IsoDoc do
896
901
  <clause id="H" obligation="normative" displayorder="5"><title depth="1">3.<tab/>Terms, definitions, symbols and abbreviated terms</title><terms id="I" obligation="normative">
897
902
  <title depth="2">3.1.<tab/>Normal Terms</title>
898
903
  <term id="J"><name>3.1.1.</name>
899
- <preferred>Term2</preferred>
904
+ <preferred><strong>Term2</strong></preferred>
900
905
  </term>
901
906
  </terms>
902
907
  <definitions id="K"><title>3.2.</title>
@@ -1002,7 +1007,7 @@ RSpec.describe IsoDoc do
1002
1007
  <div id='I'>
1003
1008
  <h2>3.1.&#160; Normal Terms</h2>
1004
1009
  <p class='TermNum' id='J'>3.1.1.</p>
1005
- <p class='Terms' style='text-align:left;'>Term2</p>
1010
+ <p class='Terms' style='text-align:left;'><b>Term2</b></p>
1006
1011
  </div>
1007
1012
  <div id='K'>
1008
1013
  <h2>3.2.</h2>
@@ -636,11 +636,10 @@ RSpec.describe IsoDoc do
636
636
  <expression>
637
637
  <name>Second Term</name>
638
638
  </expression>
639
+ <field-of-application>Field</field-of-application>
640
+ <usage-info>Usage Info 1</usage-info>
639
641
  </preferred>
640
- <usageinfo>
641
- <p id='B'>Usage Info 1.</p>
642
- </usageinfo>
643
- <definition><verbaldefinition>Definition 1</verbaldefinition></definition>
642
+ <definition><verbal-definition>Definition 1</verbal-definition></definition>
644
643
  </term>
645
644
  <term id="C">
646
645
  <preferred language='fr' script='Latn' type='prefix'>
@@ -658,49 +657,40 @@ RSpec.describe IsoDoc do
658
657
  </preferred>
659
658
  <xref target='second'/>
660
659
  </related>
661
- <definition><verbaldefinition>Definition 2</verbaldefinition></definition>
660
+ <definition><verbal-definition>Definition 2</verbal-definition></definition>
662
661
  </term>
663
662
  </terms>
664
663
  </sections>
665
664
  </iso-standard>
666
665
  INPUT
667
666
  output = <<~OUTPUT
668
- <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
669
- <sections>
670
- <terms id='A' obligation='normative' displayorder='1'>
671
- <title depth='1'>
672
- 1.
673
- <tab/>
674
- Terms and definitions
675
- </title>
676
- <term id='second'>
677
- <name>1.1.</name>
678
- <preferred>Second Term</preferred>
679
- <usageinfo>
680
- <p id='B'>Usage Info 1.</p>
681
- </usageinfo>
682
- <definition>Definition 1</definition>
683
- </term>
684
- <term id='C'>
685
- <name>1.2.</name>
686
- <preferred language='fr' script='Latn' type='prefix'>First Designation</preferred>
687
- <p>
688
- <strong>CONTRAST:</strong>
689
- <em>
690
- <preferred>Fifth Designation neut</preferred>
691
- </em>
692
- (
693
- <xref target='second'>Clause 1.1</xref>
694
- )
695
- </p>
696
- <definition>Definition 2</definition>
697
- </term>
698
- </terms>
699
- </sections>
700
- </iso-standard>
667
+ <?xml version='1.0'?>
668
+ <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
669
+ <sections>
670
+ <terms id='A' obligation='normative' displayorder='1'>
671
+ <title depth='1'>1.<tab/>Terms and definitions</title>
672
+ <term id='second'>
673
+ <name>1.1.</name>
674
+ <preferred><strong>Second Term</strong>, &lt;Field, Usage Info 1&gt;</preferred>
675
+ <definition>Definition 1</definition>
676
+ </term>
677
+ <term id='C'>
678
+ <name>1.2.</name>
679
+ <preferred language='fr' script='Latn' type='prefix'><strong>First Designation</strong></preferred>
680
+ <p>
681
+ <strong>CONTRAST:</strong>
682
+ <em>
683
+ <preferred><strong>Fifth Designation</strong>, n</preferred>
684
+ </em> (<xref target='second'>Clause 1.1</xref>)
685
+ </p>
686
+ <definition>Definition 2</definition>
687
+ </term>
688
+ </terms>
689
+ </sections>
690
+ </iso-standard>
701
691
  OUTPUT
702
- expect(xmlpp(IsoDoc::PresentationXMLConvert.new({})
703
- .convert("test", input, true))).to be_equivalent_to xmlpp(output)
692
+ expect(xmlpp(IsoDoc::PresentationXMLConvert.new({})
693
+ .convert("test", input, true))).to be_equivalent_to xmlpp(output)
704
694
  end
705
695
 
706
696
  it "processes embedded inline formatting" do
@@ -802,9 +792,9 @@ RSpec.describe IsoDoc do
802
792
  <iso-standard xmlns="http://riboseinc.com/isoxml">
803
793
  <preface><foreword>
804
794
  <p>
805
- <link updatetype="true" target="http://example.com"/>
806
- <link updatetype="true" target="list.adoc">example</link>
807
- <link updatetype="true" target="list" alt="tip">example</link>
795
+ <link update-type="true" target="http://example.com"/>
796
+ <link update-type="true" target="list.adoc">example</link>
797
+ <link update-type="true" target="list" alt="tip">example</link>
808
798
  </p>
809
799
  </foreword></preface>
810
800
  <sections>