metanorma-standoc 1.10.8 → 1.11.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/lib/asciidoctor/standoc/base.rb +5 -4
  4. data/lib/asciidoctor/standoc/cleanup.rb +20 -11
  5. data/lib/asciidoctor/standoc/cleanup_inline.rb +20 -7
  6. data/lib/asciidoctor/standoc/cleanup_maths.rb +5 -6
  7. data/lib/asciidoctor/standoc/cleanup_reqt.rb +2 -21
  8. data/lib/asciidoctor/standoc/cleanup_symbols.rb +48 -0
  9. data/lib/asciidoctor/standoc/cleanup_terms.rb +37 -77
  10. data/lib/asciidoctor/standoc/cleanup_terms_designations.rb +162 -0
  11. data/lib/asciidoctor/standoc/converter.rb +2 -0
  12. data/lib/asciidoctor/standoc/inline.rb +7 -5
  13. data/lib/asciidoctor/standoc/isodoc.rng +218 -27
  14. data/lib/asciidoctor/standoc/macros_plantuml.rb +29 -14
  15. data/lib/asciidoctor/standoc/macros_terms.rb +49 -5
  16. data/lib/asciidoctor/standoc/ref_sect.rb +24 -17
  17. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +50 -11
  18. data/lib/asciidoctor/standoc/terms.rb +12 -2
  19. data/lib/asciidoctor/standoc/utils.rb +36 -23
  20. data/lib/asciidoctor/standoc/validate.rb +24 -15
  21. data/lib/metanorma/standoc/version.rb +1 -1
  22. data/metanorma-standoc.gemspec +1 -1
  23. data/spec/asciidoctor/base_spec.rb +4 -3
  24. data/spec/asciidoctor/blocks_spec.rb +149 -21
  25. data/spec/asciidoctor/cleanup_sections_spec.rb +7 -7
  26. data/spec/asciidoctor/cleanup_spec.rb +21 -195
  27. data/spec/asciidoctor/cleanup_terms_spec.rb +990 -0
  28. data/spec/asciidoctor/inline_spec.rb +2 -2
  29. data/spec/asciidoctor/macros_plantuml_spec.rb +36 -1
  30. data/spec/asciidoctor/macros_spec.rb +189 -112
  31. data/spec/asciidoctor/refs_spec.rb +2 -24
  32. data/spec/asciidoctor/section_spec.rb +18 -18
  33. data/spec/asciidoctor/validate_spec.rb +59 -2
  34. data/spec/spec_helper.rb +1 -0
  35. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +46 -46
  36. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
  37. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  38. data/spec/vcr_cassettes/isobib_get_123_1.yml +26 -26
  39. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +32 -32
  40. data/spec/vcr_cassettes/isobib_get_123_2001.yml +11 -11
  41. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  42. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  43. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -65
  44. metadata +8 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2cc836755aed6cfff989fdcbc9cf8123ccfda29418247d93fdd75ba71660cee7
4
- data.tar.gz: d1c051429283a6e4153a6a3453b839786561c0975c2acda0586cb0ca787ae26a
3
+ metadata.gz: 4c272a7b64955264d820737284d46d47a03d7baaf56d0a365396a5a2cb5455ac
4
+ data.tar.gz: b04e30dd2633c21853ff81aaa14ddff65ddca564e4878a1914507ba7f4d43294
5
5
  SHA512:
6
- metadata.gz: 1e17a3351bf46679b587a82498d5f58d97e43743bd2e6906c929aa8dcbb8ca29fdd6e38acb82252375b40e5fff520f7d6a001b023c9c79681ad61fea949c0799
7
- data.tar.gz: 01dd1e74b7990b44c526616611155067c0725b0b0bcaeebe9d728c341d26acdab64c2c5be7519b22b94fd641015aec504c333c3b3da8cf6067c19999c20ab0ff
6
+ metadata.gz: 00117f839c229ac456a92d59ea8d7d17fbdb2dc680098126fc77c67696ae1c84cd70e3785a3b9e15c055588678a8d4a27fa1d2069431b38fa83c25fe20885d1d
7
+ data.tar.gz: 78bf3e8ef72cc04f40c3a98cfbf29e14176f04ff1cbade1f299c9a3c284e303d481574f7f1b07ba7fa8cd769a32f6d05b745f550c43ea648c0d354ef3ae8d5ad
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
- require 'isodoc/gem_tasks'
3
+ require "isodoc/gem_tasks"
4
4
 
5
5
  IsoDoc::GemTasks.install
6
6
  RSpec::Core::RakeTask.new(:spec)
@@ -14,6 +14,7 @@ module Asciidoctor
14
14
  module Base
15
15
  XML_ROOT_TAG = "standard-document".freeze
16
16
  XML_NAMESPACE = "https://www.metanorma.org/ns/standoc".freeze
17
+ FONTS_MANIFEST = "fonts-manifest".freeze
17
18
 
18
19
  def xml_root_tag
19
20
  self.class::XML_ROOT_TAG
@@ -38,7 +39,7 @@ module Asciidoctor
38
39
  scripts: node.attr("scripts"),
39
40
  scripts_override: node.attr("scripts-override"),
40
41
  scripts_pdf: node.attr("scripts-pdf"),
41
- datauriimage: node.attr("data-uri-image"),
42
+ datauriimage: node.attr("data-uri-image") != "false",
42
43
  htmltoclevels: node.attr("htmltoclevels") || node.attr("toclevels"),
43
44
  doctoclevels: node.attr("doctoclevels") || node.attr("toclevels"),
44
45
  break_up_urls_in_tables: node.attr("break-up-urls-in-tables"),
@@ -85,9 +86,9 @@ module Asciidoctor
85
86
  aligncrosselements: node.attr("align-cross-elements"),
86
87
  }
87
88
 
88
- if font_manifest_file = node.attr("mn2pdf-font-manifest-file")
89
+ if fonts_manifest = node.attr(FONTS_MANIFEST)
89
90
  attrs[IsoDoc::XslfoPdfConvert::MN2PDF_OPTIONS] = {
90
- IsoDoc::XslfoPdfConvert::MN2PDF_FONT_MANIFEST => font_manifest_file,
91
+ IsoDoc::XslfoPdfConvert::MN2PDF_FONT_MANIFEST => fonts_manifest,
91
92
  }
92
93
  end
93
94
 
@@ -127,7 +128,7 @@ module Asciidoctor
127
128
  @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
128
129
  @bibdb = nil
129
130
  @seen_headers = []
130
- @datauriimage = node.attr("data-uri-image")
131
+ @datauriimage = node.attr("data-uri-image") != "false"
131
132
  @boilerplateauthority = node.attr("boilerplate-authority")
132
133
  @sourcecode_markup_start = node.attr("sourcecode-markup-start") || "{{{"
133
134
  @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
@@ -9,6 +9,7 @@ require_relative "./cleanup_ref_dl"
9
9
  require_relative "./cleanup_boilerplate"
10
10
  require_relative "./cleanup_section"
11
11
  require_relative "./cleanup_terms"
12
+ require_relative "./cleanup_symbols"
12
13
  require_relative "./cleanup_xref"
13
14
  require_relative "./cleanup_inline"
14
15
  require_relative "./cleanup_amend"
@@ -41,6 +42,7 @@ module Asciidoctor
41
42
  symbols_cleanup(xmldoc)
42
43
  xref_cleanup(xmldoc)
43
44
  concept_cleanup(xmldoc)
45
+ related_cleanup(xmldoc)
44
46
  origin_cleanup(xmldoc)
45
47
  bookmark_cleanup(xmldoc)
46
48
  termdef_cleanup(xmldoc)
@@ -73,7 +75,8 @@ module Asciidoctor
73
75
  %w{status language script version author name callout phone email
74
76
  street city state country postcode identifier referenceFrom surname
75
77
  referenceTo docidentifier docnumber prefix initial addition forename
76
- title draft secretariat title-main title-intro title-part}.freeze
78
+ title draft secretariat title-main title-intro title-part
79
+ verbaldefinition nonverbalrepresentation}.freeze
77
80
 
78
81
  # it seems Nokogiri::XML is treating the content of <script> as cdata,
79
82
  # because of its use in HTML. Bad nokogiri. Undoing that, since we use
@@ -83,7 +86,9 @@ module Asciidoctor
83
86
  end
84
87
 
85
88
  def empty_element_cleanup(xmldoc)
86
- xmldoc.xpath("//" + TEXT_ELEMS.join(" | //")).each do |x|
89
+ xmldoc.xpath("//#{TEXT_ELEMS.join(' | //')}").each do |x|
90
+ next if x.name == "name" && x.parent.name == "expression"
91
+
87
92
  x.remove if x.children.empty?
88
93
  end
89
94
  end
@@ -108,19 +113,23 @@ module Asciidoctor
108
113
  n.name != "variant" && (!n.text? || !n.text.gsub(/\s/, "").empty?)
109
114
  end
110
115
 
111
- c.xpath("./variant").each do |n|
112
- if n.at_xpath("preceding-sibling::node()"\
113
- "[not(self::text()[not(normalize-space())])][1]"\
114
- "[self::variantwrap]")
115
- n.previous_element << n
116
- else
117
- n.replace("<variantwrap/>").first << n
118
- end
119
- end
116
+ variant_cleanup1(c)
120
117
  end
121
118
  xmldoc.xpath("//variantwrap").each { |n| n.name = "variant" }
122
119
  end
123
120
 
121
+ def variant_cleanup1(elem)
122
+ elem.xpath("./variant").each do |n|
123
+ if n.at_xpath("preceding-sibling::node()"\
124
+ "[not(self::text()[not(normalize-space())])][1]"\
125
+ "[self::variantwrap]")
126
+ n.previous_element << n
127
+ else
128
+ n.replace("<variantwrap/>").first << n
129
+ end
130
+ end
131
+ end
132
+
124
133
  def variant_space_cleanup(xmldoc)
125
134
  xmldoc.xpath("//*[variant]").each do |c|
126
135
  if c&.next&.text? && c&.next&.next&.name == "variant"
@@ -60,13 +60,26 @@ module Asciidoctor
60
60
  xmldoc.xpath("//concept[not(termxref)]").each do |x|
61
61
  term = x.at("./refterm")
62
62
  term&.remove if term&.text&.empty?
63
- x.children.remove if x&.children&.text&.strip&.empty?
64
- key_extract_locality(x)
65
- if /:/.match?(x["key"]) then concept_termbase_cleanup(x)
66
- elsif refid? x["key"] then concept_eref_cleanup(x)
67
- else concept_xref_cleanup(x)
68
- end
69
- x.delete("key")
63
+ concept_cleanup1(x)
64
+ end
65
+ end
66
+
67
+ def concept_cleanup1(elem)
68
+ elem.children.remove if elem&.children&.text&.strip&.empty?
69
+ key_extract_locality(elem)
70
+ if /:/.match?(elem["key"]) then concept_termbase_cleanup(elem)
71
+ elsif refid? elem["key"] then concept_eref_cleanup(elem)
72
+ else concept_xref_cleanup(elem)
73
+ end
74
+ elem.delete("key")
75
+ end
76
+
77
+ def related_cleanup(xmldoc)
78
+ xmldoc.xpath("//related[not(termxref)]").each do |x|
79
+ term = x.at("./refterm")
80
+ term.replace("<preferred>#{term_expr(term.children.to_xml)}"\
81
+ "</preferred>")
82
+ concept_cleanup1(x)
70
83
  end
71
84
  end
72
85
 
@@ -69,13 +69,12 @@ module Asciidoctor
69
69
  return false if char.length > 1
70
70
 
71
71
  if /\p{Greek}/.match?(char)
72
- /\p{Lower}/.match(char) && !mathml_mi_italics[:lowergreek] ||
73
- /\p{Upper}/.match(char) && !mathml_mi_italics[:uppergreek]
72
+ (/\p{Lower}/.match(char) && !mathml_mi_italics[:lowergreek]) ||
73
+ (/\p{Upper}/.match(char) && !mathml_mi_italics[:uppergreek])
74
74
  elsif /\p{Latin}/.match?(char)
75
- /\p{Lower}/.match(char) && !mathml_mi_italics[:lowerroman] ||
76
- /\p{Upper}/.match(char) && !mathml_mi_italics[:upperroman]
77
- else
78
- false
75
+ (/\p{Lower}/.match(char) && !mathml_mi_italics[:lowerroman]) ||
76
+ (/\p{Upper}/.match(char) && !mathml_mi_italics[:upperroman])
77
+ else false
79
78
  end
80
79
  end
81
80
 
@@ -86,33 +86,14 @@ module Asciidoctor
86
86
  ins = reqt.children.first
87
87
  end
88
88
  %w(obligation model type).each do |a|
89
- reqt_dl_to_attrs(reqt, dlist, a)
89
+ dl_to_attrs(reqt, dlist, a)
90
90
  end
91
91
  requirement_metadata1_tags.each do |a|
92
- ins = reqt_dl_to_elems(ins, reqt, dlist, a)
92
+ ins = dl_to_elems(ins, reqt, dlist, a)
93
93
  end
94
94
  reqt_dl_to_classif(ins, reqt, dlist)
95
95
  end
96
96
 
97
- def reqt_dl_to_attrs(reqt, dlist, name)
98
- e = dlist.at("./dt[text()='#{name}']") or return
99
- val = e.at("./following::dd/p") || e.at("./following::dd") or return
100
- reqt[name] = val.text
101
- end
102
-
103
- def reqt_dl_to_elems(ins, reqt, dlist, name)
104
- if a = reqt.at("./#{name}[last()]")
105
- ins = a
106
- end
107
- dlist.xpath("./dt[text()='#{name}']").each do |e|
108
- val = e.at("./following::dd/p") || e.at("./following::dd")
109
- val.name = name
110
- ins.next = val
111
- ins = ins.next
112
- end
113
- ins
114
- end
115
-
116
97
  def reqt_dl_to_classif(ins, reqt, dlist)
117
98
  if a = reqt.at("./classification[last()]") then ins = a end
118
99
  dlist.xpath("./dt[text()='classification']").each do |e|
@@ -0,0 +1,48 @@
1
+ module Asciidoctor
2
+ module Standoc
3
+ module Cleanup
4
+ # Indices sort after letter but before any following
5
+ # letter (x, x_m, x_1, xa); we use colon to force that sort order.
6
+ # Numbers sort *after* letters; we use thorn to force that sort order.
7
+ def symbol_key(sym)
8
+ key = sym.dup
9
+ key.traverse do |n|
10
+ n.name == "math" and
11
+ n.replace(grkletters(MathML2AsciiMath.m2a(n.to_xml)))
12
+ end
13
+ ret = Nokogiri::XML(key.to_xml)
14
+ HTMLEntities.new.decode(ret.text.downcase)
15
+ .gsub(/[\[\]{}<>()]/, "").gsub(/\s/m, "")
16
+ .gsub(/[[:punct:]]|[_^]/, ":\\0").gsub(/`/, "")
17
+ .gsub(/[0-9]+/, "þ\\0")
18
+ end
19
+
20
+ def grkletters(text)
21
+ text.gsub(/\b(alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|
22
+ lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|
23
+ psi|omega)\b/xi, "&\\1;")
24
+ end
25
+
26
+ def extract_symbols_list(dlist)
27
+ dl_out = []
28
+ dlist.xpath("./dt | ./dd").each do |dtd|
29
+ if dtd.name == "dt"
30
+ dl_out << { dt: dtd.remove, key: symbol_key(dtd) }
31
+ else
32
+ dl_out.last[:dd] = dtd.remove
33
+ end
34
+ end
35
+ dl_out
36
+ end
37
+
38
+ def symbols_cleanup(docxml)
39
+ docxml.xpath("//definitions/dl").each do |dl|
40
+ dl_out = extract_symbols_list(dl)
41
+ dl_out.sort! { |a, b| a[:key] <=> b[:key] || a[:dt] <=> b[:dt] }
42
+ dl.children = dl_out.map { |d| d[:dt].to_s + d[:dd].to_s }.join("\n")
43
+ end
44
+ docxml
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,19 +1,9 @@
1
1
  require_relative "term_lookup_cleanup"
2
+ require_relative "cleanup_terms_designations"
2
3
 
3
4
  module Asciidoctor
4
5
  module Standoc
5
6
  module Cleanup
6
- def termdef_stem_cleanup(xmldoc)
7
- xmldoc.xpath("//term/p/stem").each do |a|
8
- if a.parent.elements.size == 1 # para contains just a stem expression
9
- t = Nokogiri::XML::Element.new("admitted", xmldoc)
10
- parent = a.parent
11
- t.children = a.remove
12
- parent.replace(t)
13
- end
14
- end
15
- end
16
-
17
7
  def termdomain_cleanup(xmldoc)
18
8
  xmldoc.xpath("//p/domain").each do |a|
19
9
  prev = a.parent.previous
@@ -22,43 +12,53 @@ module Asciidoctor
22
12
  end
23
13
 
24
14
  def termdomain1_cleanup(xmldoc)
25
- xmldoc.xpath("//domain").each do |d|
26
- defn = d.at("../definition") and
27
- defn.previous = d.remove
15
+ xmldoc.xpath("//term").each do |t|
16
+ d = t.xpath("./domain | ./subject | ./usageinfo").last or next
17
+ defn = d.at("../definition") and defn.previous = d.remove
28
18
  end
29
19
  end
30
20
 
31
21
  def termdefinition_cleanup(xmldoc)
22
+ generate_termdefinitions(xmldoc)
23
+ split_termdefinitions(xmldoc)
24
+ end
25
+
26
+ def generate_termdefinitions(xmldoc)
32
27
  xmldoc.xpath("//term[not(definition)]").each do |d|
33
- first_child = d.at("./p | ./figure | ./formula") || next
28
+ first_child = d.at("./p | ./figure | ./formula | ./table") || next
34
29
  t = Nokogiri::XML::Element.new("definition", xmldoc)
35
30
  first_child.replace(t)
36
31
  t << first_child.remove
37
- d.xpath("./p | ./figure | ./formula").each { |n| t << n.remove }
32
+ d.xpath("./p | ./figure | ./formula | ./table").each { |n| t << n.remove }
38
33
  end
39
34
  end
40
35
 
41
- def termdef_unnest_cleanup(xmldoc)
42
- # release termdef tags from surrounding paras
43
- nodes = xmldoc.xpath("//p/admitted | //p/deprecates")
44
- while !nodes.empty?
45
- nodes[0].parent.replace(nodes[0].parent.children)
46
- nodes = xmldoc.xpath("//p/admitted | //p/deprecates")
36
+ def split_termdefinitions(xmldoc)
37
+ xmldoc.xpath("//definition").each do |d|
38
+ n = d.children.first.add_previous_sibling("<nonverbalrepresentation/>").first
39
+ v = d.children.first.add_previous_sibling("<verbaldefinition/>").first
40
+ nonverb = false
41
+ d.elements.each do |e|
42
+ case e.name
43
+ when "nonverbalrepresentation", "verbaldefinition" then next
44
+ when "figure", "table", "formula"
45
+ n << e.remove
46
+ nonverb = true
47
+ when "termsource"
48
+ (nonverb ? n : v) << e.remove
49
+ else v << e.remove
50
+ end
51
+ end
47
52
  end
48
53
  end
49
54
 
50
- def termdef_subclause_cleanup(xmldoc)
51
- xmldoc.xpath("//terms[terms]").each { |t| t.name = "clause" }
52
- end
53
-
54
55
  def termdocsource_cleanup(xmldoc)
55
56
  f = xmldoc.at("//preface | //sections")
56
- xmldoc.xpath("//termdocsource").each do |s|
57
- f.previous = s.remove
58
- end
57
+ xmldoc.xpath("//termdocsource").each { |s| f.previous = s.remove }
59
58
  end
60
59
 
61
60
  def term_children_cleanup(xmldoc)
61
+ xmldoc.xpath("//terms[terms]").each { |t| t.name = "clause" }
62
62
  xmldoc.xpath("//term").each do |t|
63
63
  %w(termnote termexample termsource).each do |w|
64
64
  t.xpath("./#{w}").each { |n| t << n.remove }
@@ -75,69 +75,29 @@ module Asciidoctor
75
75
  end
76
76
 
77
77
  def termnote_example_cleanup(xmldoc)
78
- xmldoc.xpath("//termnote[not(ancestor::term)]").each do |x|
79
- x.name = "note"
78
+ %w(note example).each do |w|
79
+ xmldoc.xpath("//term#{w}[not(ancestor::term)]").each do |x|
80
+ x.name = w
80
81
  end
81
- xmldoc.xpath("//termexample[not(ancestor::term)]").each do |x|
82
- x.name = "example"
83
82
  end
84
83
  end
85
84
 
86
85
  def termdef_cleanup(xmldoc)
86
+ termdef_unnest_cleanup(xmldoc)
87
87
  Asciidoctor::Standoc::TermLookupCleanup.new(xmldoc, @log).call
88
+ term_nonverbal_designations(xmldoc)
89
+ term_dl_to_metadata(xmldoc)
90
+ term_termsource_to_designation(xmldoc)
91
+ term_designation_reorder(xmldoc)
88
92
  termdef_from_termbase(xmldoc)
89
- termdef_unnest_cleanup(xmldoc)
90
93
  termdef_stem_cleanup(xmldoc)
91
94
  termdomain_cleanup(xmldoc)
92
95
  termdefinition_cleanup(xmldoc)
93
96
  termdomain1_cleanup(xmldoc)
94
97
  termnote_example_cleanup(xmldoc)
95
- termdef_subclause_cleanup(xmldoc)
96
98
  term_children_cleanup(xmldoc)
97
99
  termdocsource_cleanup(xmldoc)
98
100
  end
99
-
100
- # Indices sort after letter but before any following
101
- # letter (x, x_m, x_1, xa); we use colon to force that sort order.
102
- # Numbers sort *after* letters; we use thorn to force that sort order.
103
- def symbol_key(sym)
104
- key = sym.dup
105
- key.traverse do |n|
106
- next unless n.name == "math"
107
-
108
- n.replace(grkletters(MathML2AsciiMath.m2a(n.to_xml)))
109
- end
110
- ret = Nokogiri::XML(key.to_xml)
111
- HTMLEntities.new.decode(ret.text.downcase)
112
- .gsub(/[\[\]{}<>()]/, "").gsub(/\s/m, "")
113
- .gsub(/[[:punct:]]|[_^]/, ":\\0").gsub(/`/, "")
114
- .gsub(/[0-9]+/, "þ\\0")
115
- end
116
-
117
- def grkletters(x)
118
- x.gsub(/\b(alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega)\b/i, "&\\1;")
119
- end
120
-
121
- def extract_symbols_list(dlist)
122
- dl_out = []
123
- dlist.xpath("./dt | ./dd").each do |dtd|
124
- if dtd.name == "dt"
125
- dl_out << { dt: dtd.remove, key: symbol_key(dtd) }
126
- else
127
- dl_out.last[:dd] = dtd.remove
128
- end
129
- end
130
- dl_out
131
- end
132
-
133
- def symbols_cleanup(docxml)
134
- docxml.xpath("//definitions/dl").each do |dl|
135
- dl_out = extract_symbols_list(dl)
136
- dl_out.sort! { |a, b| a[:key] <=> b[:key] || a[:dt] <=> b[:dt] }
137
- dl.children = dl_out.map { |d| d[:dt].to_s + d[:dd].to_s }.join("\n")
138
- end
139
- docxml
140
- end
141
101
  end
142
102
  end
143
103
  end
@@ -0,0 +1,162 @@
1
+ module Asciidoctor
2
+ module Standoc
3
+ module Cleanup
4
+ def termdef_stem_cleanup(xmldoc)
5
+ xmldoc.xpath("//term/p/stem").each do |a|
6
+ if a.parent.elements.size == 1 # para contains just a stem expression
7
+ parent = a.parent
8
+ parent.replace("<admitted>#{term_expr(a.to_xml)}</admitted>")
9
+ end
10
+ end
11
+ xmldoc.xpath("//term//expression/name[stem]").each do |n|
12
+ n.parent.name = "letter-symbol"
13
+ end
14
+ end
15
+
16
+ # release termdef tags from surrounding paras
17
+ def termdef_unnest_cleanup(xmldoc)
18
+ desgn = "//p/admitted | //p/deprecates | //p/preferred | //p//related"
19
+ nodes = xmldoc.xpath(desgn)
20
+ while !nodes.empty?
21
+ nodes[0].parent.replace(nodes[0].parent.children)
22
+ nodes = xmldoc.xpath(desgn)
23
+ end
24
+ end
25
+
26
+ def term_dl_to_metadata(xmldoc)
27
+ xmldoc.xpath("//term[dl[@metadata = 'true']]").each do |t|
28
+ t.xpath("./dl[@metadata = 'true']").each do |dl|
29
+ prev = dl_to_designation(dl) or next
30
+ term_dl_to_designation_metadata(prev, dl)
31
+ term_dl_to_term_metadata(prev, dl)
32
+ term_dl_to_expression_metadata(prev, dl)
33
+ dl.remove
34
+ end
35
+ end
36
+ end
37
+
38
+ def term_dl_to_term_metadata(prev, dlist)
39
+ return unless prev.name == "preferred" &&
40
+ prev.at("./preceding-sibling::preferred").nil?
41
+
42
+ ins = term_element_insert_point(prev)
43
+ %w(domain subject usageinfo).each do |a|
44
+ ins = dl_to_elems(ins, prev.parent, dlist, a)
45
+ end
46
+ end
47
+
48
+ def term_dl_to_designation_metadata(prev, dlist)
49
+ %w(absent geographicArea).each { |a| dl_to_attrs(related2pref(prev), dlist, a) }
50
+ end
51
+
52
+ def term_element_insert_point(prev)
53
+ ins = prev
54
+ while %w(preferred admitted deprecates related domain dl)
55
+ .include? ins&.next_element&.name
56
+ ins = ins.next_element
57
+ end
58
+ ins
59
+ end
60
+
61
+ def term_dl_to_expression_metadata(prev, dlist)
62
+ %w(language script type isInternational).each do |a|
63
+ dl_to_attrs(prev, dlist, a)
64
+ end
65
+ %w(abbreviationType pronunciation).reverse.each do |a|
66
+ dl_to_elems(prev.at("./expression/name"), prev, dlist, a)
67
+ end
68
+ g = dlist.at("./dt[text()='grammar']/following::dd//dl") and
69
+ term_dl_to_expression_grammar(prev, g)
70
+ term_to_letter_symbol(prev, dlist)
71
+ end
72
+
73
+ def term_dl_to_expression_grammar(prev, dlist)
74
+ prev.at(".//expression") or return
75
+ prev.at(".//expression") << "<grammar><sentinel/></grammar>"
76
+ %w(gender isPreposition isParticiple isAdjective isAdverb isNoun
77
+ grammarValue).reverse.each do |a|
78
+ dl_to_elems(prev.at(".//expression/grammar/*"), prev.elements.last,
79
+ dlist, a)
80
+ end
81
+ term_dl_to_designation_gender(prev)
82
+ end
83
+
84
+ def term_dl_to_designation_gender(prev)
85
+ gender = prev.at(".//expression/grammar/gender")
86
+ /,/.match?(gender&.text) and
87
+ gender.replace(gender.text.split(/,\s*/)
88
+ .map { |x| "<gender>#{x}</gender>" }.join)
89
+ prev.at(".//expression/grammar/sentinel").remove
90
+ end
91
+
92
+ def term_to_letter_symbol(prev, dlist)
93
+ ls = dlist.at("./dt[text()='letter-symbol']/following::dd/p")
94
+ return unless ls&.text == "true"
95
+
96
+ prev.at(".//expression").name = "letter-symbol"
97
+ end
98
+
99
+ def dl_to_designation(dlist)
100
+ prev = dlist.previous_element
101
+ unless %w(preferred admitted deprecates related).include? prev&.name
102
+ @log.add("AsciiDoc Input", dlist, "Metadata definition list does "\
103
+ "not follow a term designation")
104
+ return nil
105
+ end
106
+ prev
107
+ end
108
+
109
+ def term_nonverbal_designations(xmldoc)
110
+ xmldoc.xpath("//term/preferred | //term/admitted | //term/deprecates")
111
+ .each do |d|
112
+ d.text.strip.empty? or next
113
+ n = d.next_element
114
+ if %w(formula figure).include?(n&.name)
115
+ term_nonverbal_designations1(d, n)
116
+ else d.at("./expression/name") or
117
+ d.children = term_expr("")
118
+ end
119
+ end
120
+ end
121
+
122
+ def term_nonverbal_designations1(desgn, elem)
123
+ desgn = related2pref(desgn)
124
+ if elem.name == "figure"
125
+ elem.at("./name").remove
126
+ desgn.children =
127
+ "<graphical-symbol>#{elem.remove.to_xml}</graphical-symbol>"
128
+ else
129
+ desgn.children = term_expr(elem.at("./stem").to_xml)
130
+ elem.remove
131
+ end
132
+ end
133
+
134
+ def term_termsource_to_designation(xmldoc)
135
+ xmldoc.xpath("//term/termsource").each do |t|
136
+ p = t.previous_element
137
+ while %w(domain subject usageinfo).include? p&.name
138
+ p = p.previous_element
139
+ end
140
+ %w(preferred admitted deprecates related).include?(p&.name) or
141
+ next
142
+ related2pref(p) << t.remove
143
+ end
144
+ end
145
+
146
+ def term_designation_reorder(xmldoc)
147
+ xmldoc.xpath("//term").each do |t|
148
+ %w(preferred admitted deprecates related)
149
+ .each_with_object([]) do |tag, m|
150
+ t.xpath("./#{tag}").each { |x| m << x.remove }
151
+ end.reverse.each do |x|
152
+ t.children.first.previous = x
153
+ end
154
+ end
155
+ end
156
+
157
+ def related2pref(elem)
158
+ elem.name == "related" ? elem = elem.at("./preferred") : elem
159
+ end
160
+ end
161
+ end
162
+ end
@@ -28,8 +28,10 @@ module Asciidoctor
28
28
  preprocessor Metanorma::Plugin::Lutaml::LutamlPreprocessor
29
29
  preprocessor Metanorma::Plugin::Lutaml::LutamlUmlAttributesTablePreprocessor
30
30
  preprocessor Metanorma::Plugin::Lutaml::LutamlUmlDatamodelDescriptionPreprocessor
31
+ inline_macro Asciidoctor::Standoc::PreferredTermInlineMacro
31
32
  inline_macro Asciidoctor::Standoc::AltTermInlineMacro
32
33
  inline_macro Asciidoctor::Standoc::DeprecatedTermInlineMacro
34
+ inline_macro Asciidoctor::Standoc::RelatedTermInlineMacro
33
35
  inline_macro Asciidoctor::Standoc::DomainTermInlineMacro
34
36
  inline_macro Asciidoctor::Standoc::InheritInlineMacro
35
37
  inline_macro Asciidoctor::Standoc::HTML5RubyMacro
@@ -170,8 +170,10 @@ module Asciidoctor
170
170
  else
171
171
  case node.role
172
172
  # the following three are legacy, they are now handled by macros
173
- when "alt" then xml.admitted { |a| a << node.text }
174
- when "deprecated" then xml.deprecates { |a| a << node.text }
173
+ when "alt"
174
+ term_designation(xml, node, "admitted", node.text)
175
+ when "deprecated"
176
+ term_designation(xml, node, "deprecates", node.text)
175
177
  when "domain" then xml.domain { |a| a << node.text }
176
178
 
177
179
  when "strike" then xml.strike { |s| s << node.text }
@@ -209,7 +211,7 @@ module Asciidoctor
209
211
  def inline_image(node)
210
212
  noko do |xml|
211
213
  xml.image **image_attributes(node)
212
- end.join("")
214
+ end.join
213
215
  end
214
216
 
215
217
  def inline_indexterm(node)
@@ -218,8 +220,8 @@ module Asciidoctor
218
220
  terms = (node.attr("terms") || [node.text]).map { |x| xml_encode(x) }
219
221
  xml.index do |i|
220
222
  i.primary { |x| x << terms[0] }
221
- a = terms.dig(1) and i.secondary { |x| x << a }
222
- a = terms.dig(2) and i.tertiary { |x| x << a }
223
+ a = terms[1] and i.secondary { |x| x << a }
224
+ a = terms[2] and i.tertiary { |x| x << a }
223
225
  end
224
226
  end.join
225
227
  end