asciidoctor-iso 0.6.1 → 0.7.0

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile.lock +12 -10
  5. data/README.adoc +113 -16
  6. data/bin/rspec +18 -0
  7. data/lib/asciidoctor/iso/base.rb +30 -28
  8. data/lib/asciidoctor/iso/blocks.rb +33 -33
  9. data/lib/asciidoctor/iso/cleanup.rb +79 -33
  10. data/lib/asciidoctor/iso/cleanup_block.rb +71 -18
  11. data/lib/asciidoctor/iso/cleanup_ref.rb +35 -30
  12. data/lib/asciidoctor/iso/converter.rb +0 -3
  13. data/lib/asciidoctor/iso/front.rb +29 -16
  14. data/lib/asciidoctor/iso/html/isodoc.css +34 -0
  15. data/lib/asciidoctor/iso/html/wordstyle.css +138 -6
  16. data/lib/asciidoctor/iso/inline.rb +10 -22
  17. data/lib/asciidoctor/iso/isodoc.rng +66 -16
  18. data/lib/asciidoctor/iso/isostandard.rng +129 -15
  19. data/lib/asciidoctor/iso/lists.rb +49 -42
  20. data/lib/asciidoctor/iso/macros.rb +12 -8
  21. data/lib/asciidoctor/iso/section.rb +53 -37
  22. data/lib/asciidoctor/iso/table.rb +9 -1
  23. data/lib/asciidoctor/iso/utils.rb +18 -13
  24. data/lib/asciidoctor/iso/validate.rb +100 -24
  25. data/lib/asciidoctor/iso/validate_requirements.rb +106 -0
  26. data/lib/asciidoctor/iso/validate_section.rb +85 -65
  27. data/lib/asciidoctor/iso/validate_style.rb +68 -115
  28. data/lib/asciidoctor/iso/version.rb +1 -1
  29. data/spec/asciidoctor-iso/base_spec.rb +193 -0
  30. data/spec/asciidoctor-iso/blocks_spec.rb +426 -0
  31. data/spec/asciidoctor-iso/cleanup_spec.rb +687 -0
  32. data/spec/asciidoctor-iso/inline_spec.rb +159 -0
  33. data/spec/asciidoctor-iso/lists_spec.rb +189 -0
  34. data/spec/asciidoctor-iso/macros_spec.rb +20 -0
  35. data/spec/asciidoctor-iso/refs_spec.rb +194 -0
  36. data/spec/asciidoctor-iso/section_spec.rb +301 -0
  37. data/spec/asciidoctor-iso/table_spec.rb +307 -0
  38. data/spec/asciidoctor-iso/validate_spec.rb +749 -0
  39. data/spec/examples/english.yaml +69 -0
  40. data/spec/examples/rice.adoc +30 -28
  41. data/spec/examples/rice.doc +3035 -2865
  42. data/spec/examples/rice.html +281 -234
  43. data/spec/examples/rice.preview.html +30 -20
  44. data/spec/examples/rice.xml +250 -282
  45. data/spec/spec_helper.rb +87 -0
  46. metadata +17 -2
@@ -119,6 +119,9 @@
119
119
  <optional>
120
120
  <ref name="copyright"/>
121
121
  </optional>
122
+ <zeroOrMore>
123
+ <ref name="docrelation"/>
124
+ </zeroOrMore>
122
125
  <optional>
123
126
  <ref name="editorialgroup"/>
124
127
  </optional>
@@ -169,6 +172,9 @@
169
172
  <ref name="status"/>
170
173
  </optional>
171
174
  <ref name="copyright"/>
175
+ <zeroOrMore>
176
+ <ref name="docrelation"/>
177
+ </zeroOrMore>
172
178
  <ref name="editorialgroup"/>
173
179
  </define>
174
180
  <define name="bdate">
@@ -231,11 +237,45 @@
231
237
  <element name="sections">
232
238
  <ref name="clause"/>
233
239
  <ref name="terms"/>
240
+ <optional>
241
+ <ref name="symbols-abbrevs"/>
242
+ </optional>
234
243
  <oneOrMore>
235
244
  <ref name="clause"/>
236
245
  </oneOrMore>
237
246
  </element>
238
247
  </define>
248
+ <define name="Content-Section">
249
+ <optional>
250
+ <attribute name="id">
251
+ <data type="ID"/>
252
+ </attribute>
253
+ </optional>
254
+ <optional>
255
+ <attribute name="obligation">
256
+ <choice>
257
+ <value>normative</value>
258
+ <value>informative</value>
259
+ </choice>
260
+ </attribute>
261
+ </optional>
262
+ <optional>
263
+ <ref name="section-title"/>
264
+ </optional>
265
+ <choice>
266
+ <group>
267
+ <oneOrMore>
268
+ <ref name="BasicBlock"/>
269
+ </oneOrMore>
270
+ <zeroOrMore>
271
+ <ref name="note"/>
272
+ </zeroOrMore>
273
+ </group>
274
+ <oneOrMore>
275
+ <ref name="content-subsection"/>
276
+ </oneOrMore>
277
+ </choice>
278
+ </define>
239
279
  <define name="references">
240
280
  <element name="references">
241
281
  <optional>
@@ -243,6 +283,14 @@
243
283
  <data type="ID"/>
244
284
  </attribute>
245
285
  </optional>
286
+ <optional>
287
+ <attribute name="obligation">
288
+ <choice>
289
+ <value>normative</value>
290
+ <value>informative</value>
291
+ </choice>
292
+ </attribute>
293
+ </optional>
246
294
  <optional>
247
295
  <ref name="section-title"/>
248
296
  </optional>
@@ -254,6 +302,24 @@
254
302
  </zeroOrMore>
255
303
  </element>
256
304
  </define>
305
+ <define name="symbols-abbrevs">
306
+ <element name="symbols-abbrevs">
307
+ <optional>
308
+ <attribute name="id">
309
+ <data type="ID"/>
310
+ </attribute>
311
+ </optional>
312
+ <optional>
313
+ <attribute name="obligation">
314
+ <choice>
315
+ <value>normative</value>
316
+ <value>informative</value>
317
+ </choice>
318
+ </attribute>
319
+ </optional>
320
+ <ref name="dl"/>
321
+ </element>
322
+ </define>
257
323
  <define name="terms">
258
324
  <element name="terms">
259
325
  <optional>
@@ -261,23 +327,32 @@
261
327
  <data type="ID"/>
262
328
  </attribute>
263
329
  </optional>
330
+ <optional>
331
+ <attribute name="obligation">
332
+ <choice>
333
+ <value>normative</value>
334
+ <value>informative</value>
335
+ </choice>
336
+ </attribute>
337
+ </optional>
264
338
  <optional>
265
339
  <ref name="section-title"/>
266
340
  </optional>
267
341
  <zeroOrMore>
268
- <!-- boilerplate -->
269
- <ref name="paragraph-with-footnote"/>
342
+ <ref name="termdocsource"/>
270
343
  </zeroOrMore>
271
- <optional>
272
- <ref name="ul"/>
273
- </optional>
274
344
  <choice>
275
345
  <oneOrMore>
276
346
  <ref name="term"/>
277
347
  </oneOrMore>
278
- <optional>
279
- <ref name="terms"/>
280
- </optional>
348
+ <group>
349
+ <zeroOrMore>
350
+ <ref name="terms"/>
351
+ </zeroOrMore>
352
+ <optional>
353
+ <ref name="symbols-abbrevs"/>
354
+ </optional>
355
+ </group>
281
356
  </choice>
282
357
  </element>
283
358
  </define>
@@ -334,7 +409,7 @@
334
409
  </attribute>
335
410
  </optional>
336
411
  <optional>
337
- <attribute name="subtype">
412
+ <attribute name="obligation">
338
413
  <choice>
339
414
  <value>normative</value>
340
415
  <value>informative</value>
@@ -370,7 +445,7 @@
370
445
  <choice>
371
446
  <ref name="image"/>
372
447
  <oneOrMore>
373
- <ref name="figure"/>
448
+ <ref name="subfigure"/>
374
449
  </oneOrMore>
375
450
  </choice>
376
451
  <zeroOrMore>
@@ -395,11 +470,13 @@
395
470
  </define>
396
471
  <define name="dd">
397
472
  <element name="dd">
398
- <!--
399
- ( paragraph-with-footnote | table | note | formula | admonition | ol | ul | dl | quote | sourcecode | review | example )*
400
- exclude figures?
401
- -->
402
- <ref name="BasicBlock"/>
473
+ <zeroOrMore>
474
+ <!--
475
+ ( paragraph-with-footnote | table | note | formula | admonition | ol | ul | dl | quote | sourcecode | review | example )*
476
+ exclude figures?
477
+ -->
478
+ <ref name="BasicBlock"/>
479
+ </zeroOrMore>
403
480
  </element>
404
481
  </define>
405
482
  <define name="admonition">
@@ -528,6 +605,14 @@
528
605
  <data type="boolean"/>
529
606
  </attribute>
530
607
  </optional>
608
+ <optional>
609
+ <attribute name="obligation">
610
+ <choice>
611
+ <value>normative</value>
612
+ <value>informative</value>
613
+ </choice>
614
+ </attribute>
615
+ </optional>
531
616
  <optional>
532
617
  <ref name="section-title"/>
533
618
  </optional>
@@ -647,6 +732,11 @@
647
732
  <data type="int"/>
648
733
  </attribute>
649
734
  </optional>
735
+ <optional>
736
+ <attribute name="subpart">
737
+ <data type="int"/>
738
+ </attribute>
739
+ </optional>
650
740
  <data type="int"/>
651
741
  </element>
652
742
  </define>
@@ -713,6 +803,14 @@
713
803
  <data type="boolean"/>
714
804
  </attribute>
715
805
  </optional>
806
+ <optional>
807
+ <attribute name="obligation">
808
+ <choice>
809
+ <value>normative</value>
810
+ <value>informative</value>
811
+ </choice>
812
+ </attribute>
813
+ </optional>
716
814
  <optional>
717
815
  <ref name="section-title"/>
718
816
  </optional>
@@ -728,4 +826,20 @@
728
826
  </zeroOrMore>
729
827
  </element>
730
828
  </define>
829
+ <define name="subfigure">
830
+ <element name="figure">
831
+ <attribute name="id">
832
+ <data type="ID"/>
833
+ </attribute>
834
+ <optional>
835
+ <ref name="tname"/>
836
+ </optional>
837
+ <ref name="image"/>
838
+ </element>
839
+ </define>
840
+ <define name="termdocsource">
841
+ <element name="source">
842
+ <ref name="erefType"/>
843
+ </element>
844
+ </define>
731
845
  </grammar>
@@ -6,14 +6,10 @@ module Asciidoctor
6
6
  xml_ul.li do |xml_li|
7
7
  style(item, item.text)
8
8
  if item.blocks?
9
- xml_li.p **id_attr(item) do |t|
10
- t << item.text
11
- end
9
+ xml_li.p(**id_attr(item)) { |t| t << item.text }
12
10
  xml_li << item.content
13
11
  else
14
- xml_li.p **id_attr(item) do |p|
15
- p << item.text
16
- end
12
+ xml_li.p(**id_attr(item)) { |p| p << item.text }
17
13
  end
18
14
  end
19
15
  end
@@ -30,58 +26,62 @@ module Asciidoctor
30
26
  end.join("\n")
31
27
  end
32
28
 
33
- def iso_publisher(t)
29
+ def iso_publisher(t, code)
34
30
  t.contributor do |c|
35
- c.role **{ type: "publisher" }
31
+ c.role **{ type: "publisher" }
36
32
  c.organization do |aff|
37
- aff.name "ISO"
33
+ aff.name code.gsub(%r{[/ \t].*$}, "")
38
34
  end
39
35
  end
40
36
  end
41
37
 
38
+ def plaintxt
39
+ { format: "text/plain" }
40
+ end
41
+
42
+ def ref_attributes(m)
43
+ { id: m[:anchor], type: "standard" }
44
+ end
45
+
42
46
  def isorefmatches(xml, m)
43
- ref_attributes = { id: m[:anchor], type: "standard" }
44
- xml.bibitem **attr_code(ref_attributes) do |t|
45
- t.title **{ format: "text/plain" } { |i| i << ref_normalise(m[:text]) }
47
+ xml.bibitem **attr_code(ref_attributes(m)) do |t|
48
+ t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
46
49
  t.docidentifier m[:code]
47
- t.date m[:year], { type: "published" } if m[:year]
48
- iso_publisher(t)
50
+ t.date(m[:year], type: "published") if m[:year]
51
+ iso_publisher(t, m[:code])
49
52
  end
50
53
  end
51
54
 
52
55
  def isorefmatches2(xml, m)
53
- ref_attributes = { id: m[:anchor], type: "standard" }
54
- xml.bibitem **attr_code(ref_attributes) do |t|
55
- t.title **{ format: "text/plain" } { |i| i << ref_normalise(m[:text]) }
56
+ xml.bibitem **attr_code(ref_attributes(m)) do |t|
57
+ t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
56
58
  t.docidentifier m[:code]
57
- t.date "--", { type: "published" }
58
- iso_publisher(t)
59
- t.note **{ format: "text/plain" } { |p| p << "ISO DATE: #{m[:fn]}" }
59
+ t.date "--", type: "published"
60
+ iso_publisher(t, m[:code])
61
+ t.note(**plaintxt) { |p| p << "ISO DATE: #{m[:fn]}" }
60
62
  end
61
63
  end
62
64
 
63
65
  def isorefmatches3(xml, m)
64
- ref_attributes = { id: m[:anchor], type: "standard" }
65
- xml.bibitem **attr_code(ref_attributes) do |t|
66
- t.title **{ format: "text/plain" } { |i| i << ref_normalise(m[:text]) }
66
+ xml.bibitem **attr_code(ref_attributes(m)) do |t|
67
+ t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
67
68
  t.docidentifier "#{m[:code]}:All Parts"
68
- t.date m[:year], { type: "published" } if m[:year]
69
- iso_publisher(t)
69
+ t.date(m[:year], type: "published") if m[:year]
70
+ iso_publisher(t, m[:code])
70
71
  end
71
72
  end
72
73
 
74
+ # TODO: alternative where only title is available
73
75
  def refitem(xml, item, node)
74
- m = NON_ISO_REF.match item
75
- if m.nil? then Utils::warning(node, "no anchor on reference", item)
76
- else
77
- xml.bibitem **attr_code(id: m[:anchor]) do |t|
78
- t.formattedref **{ format: "application/x-isodoc+xml" } do |i|
79
- i << ref_normalise_no_format(m[:text])
80
- end
81
- code = m[:code]
82
- code = "[#{code}]" if /^\d+$?/.match? code
83
- t.docidentifier code
76
+ unless m = NON_ISO_REF.match(item)
77
+ Utils::warning(node, "no anchor on reference", item)
78
+ return
79
+ end
80
+ xml.bibitem **attr_code(id: m[:anchor]) do |t|
81
+ t.formattedref **{ format: "application/x-isodoc+xml" } do |i|
82
+ i << ref_normalise_no_format(m[:text])
84
83
  end
84
+ t.docidentifier(/^\d+$/.match?(m[:code]) ? "[#{m[:code]}]" : m[:code])
85
85
  end
86
86
  end
87
87
 
@@ -107,17 +107,25 @@ module Asciidoctor
107
107
  <fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?(?<text>.*)$}xm
108
108
 
109
109
  ISO_REF_ALL_PARTS = %r{^<ref\sid="(?<anchor>[^"]+)">
110
- \[(?<code>(ISO|IEC)[^0-9]*\s[0-9]+)\s\(all\sparts\)\]</ref>(<p>)?,?\s?
111
- (?<text>.*)(</p>)?$}xm
110
+ \[(?<code>(ISO|IEC)[^0-9]*\s[0-9]+)(:(?<year>[0-9]+))?\s
111
+ \(all\sparts\)\]</ref>,?\s
112
+ (?<text>.*)$}xm
112
113
 
113
114
  NON_ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
114
115
  \[(?<code>[^\]]+)\]</ref>,?\s
115
116
  (?<text>.*)$}xm
116
117
 
117
- def reference1(node, item, xml, normative)
118
+ NORM_ISO_WARN = "non-ISO/IEC reference not expected as normative".freeze
119
+
120
+ def reference1_matches(item)
118
121
  matched = ISO_REF.match item
119
122
  matched2 = ISO_REF_NO_YEAR.match item
120
123
  matched3 = ISO_REF_ALL_PARTS.match item
124
+ [matched, matched2, matched3]
125
+ end
126
+
127
+ def reference1(node, item, xml, normative)
128
+ matched, matched2, matched3 = reference1_matches(item)
121
129
  if matched3.nil? && matched2.nil? && matched.nil?
122
130
  refitem(xml, item, node)
123
131
  elsif !matched.nil? then isorefmatches(xml, matched)
@@ -125,8 +133,7 @@ module Asciidoctor
125
133
  elsif !matched3.nil? then isorefmatches3(xml, matched3)
126
134
  end
127
135
  if matched3.nil? && matched2.nil? && matched.nil? && normative
128
- w = "non-ISO/IEC reference not expected as normative"
129
- Utils::warning(node, w, item)
136
+ Utils::warning(node, NORM_ISO_WARN, item)
130
137
  end
131
138
  end
132
139
 
@@ -143,7 +150,7 @@ module Asciidoctor
143
150
  return "roman" if style == "lowerroman"
144
151
  return "roman_upper" if style == "upperroman"
145
152
  return "alphabet_upper" if style == "upperalpha"
146
- return style
153
+ style
147
154
  end
148
155
 
149
156
  def olist(node)
@@ -191,7 +198,7 @@ module Asciidoctor
191
198
  def colist(node)
192
199
  noko do |xml|
193
200
  node.items.each_with_index do |item, i|
194
- xml_ul.annotation **attr_code(id: i + 1) do |xml_li|
201
+ xml.annotation **attr_code(id: i + 1) do |xml_li|
195
202
  style(item, item.text)
196
203
  xml_li.p { |p| p << item.text }
197
204
  end
@@ -1,4 +1,4 @@
1
- require 'asciidoctor/extensions'
1
+ require "asciidoctor/extensions"
2
2
  module Asciidoctor
3
3
  module ISO
4
4
  class AltTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
@@ -7,19 +7,22 @@ module Asciidoctor
7
7
  parse_content_as :text
8
8
  using_format :short
9
9
 
10
- def process parent, target, attrs
11
- %{<admitted>#{Asciidoctor::Inline.new(parent, :quoted, attrs['text']).convert}</admitted>}
10
+ def process(parent, _target, attrs)
11
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
12
+ %{<admitted>#{out}</admitted>}
12
13
  end
13
14
  end
14
15
 
15
- class DeprecatedTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
16
+ class DeprecatedTermInlineMacro <
17
+ Asciidoctor::Extensions::InlineMacroProcessor
16
18
  use_dsl
17
19
  named :deprecated
18
20
  parse_content_as :text
19
21
  using_format :short
20
22
 
21
- def process parent, target, attrs
22
- %{<deprecates>#{attrs["text"]}</deprecates>}
23
+ def process(parent, _target, attrs)
24
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
25
+ %{<deprecates>#{out}</deprecates>}
23
26
  end
24
27
  end
25
28
 
@@ -29,8 +32,9 @@ module Asciidoctor
29
32
  parse_content_as :text
30
33
  using_format :short
31
34
 
32
- def process parent, target, attrs
33
- %{<domain>#{attrs["text"]}</domain>}
35
+ def process(parent, _target, attrs)
36
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
37
+ %{<domain>#{out}</domain>}
34
38
  end
35
39
  end
36
40
  end
@@ -4,15 +4,10 @@ require "uri"
4
4
  module Asciidoctor
5
5
  module ISO
6
6
  module Section
7
- @scope = false
8
7
  @biblio = false
9
8
  @term_def = false
10
9
  @norm_ref = false
11
10
 
12
- def in_scope
13
- @scope
14
- end
15
-
16
11
  def in_biblio
17
12
  @biblio
18
13
  end
@@ -25,31 +20,33 @@ module Asciidoctor
25
20
  @norm_ref
26
21
  end
27
22
 
23
+ def sectiontype(node)
24
+ node&.attr("heading")&.downcase || node.title.downcase
25
+ end
26
+
28
27
  def section(node)
29
28
  a = { id: Utils::anchor_or_uuid(node) }
30
29
  noko do |xml|
31
- case node.title.downcase
30
+ case sectiontype(node)
32
31
  when "introduction" then
33
- if node.level == 1
34
- introduction_parse(a, xml, node)
32
+ if node.level == 1 then introduction_parse(a, xml, node)
35
33
  else
36
34
  clause_parse(a, xml, node)
37
35
  end
38
36
  when "patent notice" then patent_notice_parse(xml, node)
39
37
  when "scope" then scope_parse(a, xml, node)
40
38
  when "normative references" then norm_ref_parse(a, xml, node)
41
- when "terms and definitions"
42
- term_def_parse(a, xml, node, node.title.downcase)
43
- when "terms, definitions, symbols and abbreviations"
44
- term_def_parse(a, xml, node, node.title.downcase)
45
- when "symbols and abbreviated terms"
39
+ when "terms and definitions",
40
+ "terms, definitions, symbols and abbreviated terms"
41
+ @term_def = true
42
+ term_def_parse(a, xml, node, true)
43
+ @term_def = false
44
+ when "symbols and abbreviated terms"
46
45
  symbols_parse(a, xml, node)
47
46
  when "bibliography" then bibliography_parse(a, xml, node)
48
47
  else
49
- if @term_def
50
- term_def_subclause_parse(a, xml, node)
51
- elsif @biblio
52
- bibliography_parse(a, xml, node)
48
+ if @term_def then term_def_subclause_parse(a, xml, node)
49
+ elsif @biblio then bibliography_parse(a, xml, node)
53
50
  elsif node.attr("style") == "appendix" && node.level == 1
54
51
  annex_parse(a, xml, node)
55
52
  else
@@ -59,12 +56,24 @@ module Asciidoctor
59
56
  end.join("\n")
60
57
  end
61
58
 
59
+ def set_obligation(attrs, node)
60
+ attrs[:obligation] = if node.attributes.has_key?("obligation")
61
+ node.attr("obligation")
62
+ elsif node.parent.attributes.has_key?("obligation")
63
+ node.parent.attr("obligation")
64
+ else
65
+ "normative"
66
+ end
67
+ end
68
+
69
+ SCOPE_WARN = "Scope contains subsections: should be succint".freeze
70
+
71
+ # Not testing max depth of sections: Asciidoctor already limits
72
+ # it to 5 levels of nesting
62
73
  def clause_parse(attrs, xml, node)
63
- attrs["inline-header".to_sym] = true if node.option? "inline-header"
64
- w = "Scope contains subsections: should be succint"
65
- style_warning(node, w, nil) if @scope
66
- # Not testing max depth of sections: Asciidoctor already limits
67
- # it to 5 levels of nesting
74
+ attrs["inline-header".to_sym] = node.option? "inline-header"
75
+ set_obligation(attrs, node)
76
+ style_warning(node, SCOPE_WARN, nil) if @scope
68
77
  sect = node.level == 1 ? "clause" : "subsection"
69
78
  xml.send sect, **attr_code(attrs) do |xml_section|
70
79
  xml_section.title { |n| n << node.title } unless node.title.nil?
@@ -73,11 +82,8 @@ module Asciidoctor
73
82
  end
74
83
 
75
84
  def annex_parse(attrs, xml, node)
76
- attrs["inline-header".to_sym] = true if node.option? "inline-header"
77
- attrs[:subtype] = "informative"
78
- if node.attributes.has_key?("subtype")
79
- attrs[:subtype] = node.attr("subtype")
80
- end
85
+ attrs["inline-header".to_sym] = node.option? "inline-header"
86
+ set_obligation(attrs, node)
81
87
  xml.annex **attr_code(attrs) do |xml_section|
82
88
  xml_section.title { |name| name << node.title }
83
89
  xml_section << node.content
@@ -101,24 +107,34 @@ module Asciidoctor
101
107
  end
102
108
 
103
109
  def term_def_subclause_parse(attrs, xml, node)
110
+ # subclause contains subclauses
111
+ sub = node.find_by(context: :section) { |s| s.level == node.level + 1 }
112
+ sub.empty? || (return term_def_parse(attrs, xml, node, false))
113
+ node.title.casecmp("symbols and abbreviated terms").zero? &&
114
+ (return symbols_parse(attrs, xml, node))
104
115
  xml.term **attr_code(attrs) do |xml_section|
105
116
  xml_section.preferred { |name| name << node.title }
106
117
  xml_section << node.content
107
118
  end
108
119
  end
109
120
 
110
- def term_def_parse(attrs, xml, node, title)
111
- @term_def = true
112
- xml.terms **attr_code(attrs) do |xml_section|
113
- if title == "terms, definitions, symbols and abbreviations"
114
- title = "Terms, Definitions, Symbols and Abbreviations"
115
- else
116
- title = "Terms and Definitions"
121
+ def term_def_title(toplevel, node)
122
+ return node.title unless toplevel
123
+ sub = node.find_by(context: :section) do |s|
124
+ s.title.casecmp("symbols and abbreviated terms").zero?
125
+ end
126
+ return "Terms and Definitions" if sub.empty?
127
+ "Terms, Definitions, Symbols and Abbreviated Terms"
128
+ end
129
+
130
+ def term_def_parse(attrs, xml, node, toplevel)
131
+ xml.terms **attr_code(attrs) do |section|
132
+ section.title { |t| t << term_def_title(toplevel, node) }
133
+ (s = node.attr("source")) && s.split(/,/).each do |s1|
134
+ section.source(nil, **attr_code(target: s1, type: "inline"))
117
135
  end
118
- xml_section.title { |t| t << title }
119
- xml_section << node.content
136
+ section << node.content
120
137
  end
121
- @term_def = false
122
138
  end
123
139
 
124
140
  def norm_ref_parse(attrs, xml, node)