asciidoctor-iso 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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)