metanorma-standoc 1.10.3 → 1.10.5

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asciidoctor/standoc/base.rb +15 -5
  3. data/lib/asciidoctor/standoc/blocks.rb +37 -31
  4. data/lib/asciidoctor/standoc/cleanup.rb +12 -69
  5. data/lib/asciidoctor/standoc/cleanup_block.rb +6 -3
  6. data/lib/asciidoctor/standoc/cleanup_maths.rb +113 -21
  7. data/lib/asciidoctor/standoc/cleanup_reqt.rb +60 -14
  8. data/lib/asciidoctor/standoc/cleanup_section.rb +1 -0
  9. data/lib/asciidoctor/standoc/cleanup_section_names.rb +31 -14
  10. data/lib/asciidoctor/standoc/cleanup_text.rb +70 -0
  11. data/lib/asciidoctor/standoc/converter.rb +2 -0
  12. data/lib/asciidoctor/standoc/isodoc.rng +29 -9
  13. data/lib/asciidoctor/standoc/lists.rb +9 -6
  14. data/lib/asciidoctor/standoc/reqt.rb +39 -27
  15. data/lib/asciidoctor/standoc/reqt.rng +15 -4
  16. data/lib/asciidoctor/standoc/table.rb +22 -20
  17. data/lib/asciidoctor/standoc/validate_section.rb +2 -1
  18. data/lib/isodoc/base.standard.xsl +6003 -0
  19. data/lib/isodoc/pdf_convert.rb +20 -0
  20. data/lib/metanorma/standoc/processor.rb +5 -1
  21. data/lib/metanorma/standoc/version.rb +1 -1
  22. data/lib/metanorma-standoc.rb +1 -0
  23. data/metanorma-standoc.gemspec +1 -1
  24. data/spec/asciidoctor/base_spec.rb +6 -0
  25. data/spec/asciidoctor/blocks_spec.rb +43 -23
  26. data/spec/asciidoctor/cleanup_sections_spec.rb +67 -1
  27. data/spec/asciidoctor/cleanup_spec.rb +148 -21
  28. data/spec/asciidoctor/isobib_cache_spec.rb +8 -8
  29. data/spec/asciidoctor/macros_spec.rb +114 -1
  30. data/spec/asciidoctor/refs_dl_spec.rb +1 -1
  31. data/spec/asciidoctor/refs_spec.rb +218 -442
  32. data/spec/asciidoctor/section_spec.rb +1 -1
  33. data/spec/asciidoctor/validate_spec.rb +4 -0
  34. data/spec/examples/datamodel/address_class_profile.adoc +1 -0
  35. data/spec/examples/datamodel/address_component_profile.adoc +1 -0
  36. data/spec/examples/datamodel/blank_definition_profile.adoc +1 -0
  37. data/spec/examples/datamodel/common_models_diagram.adoc +2 -1
  38. data/spec/examples/datamodel/top_down_diagram.adoc +2 -1
  39. data/spec/fixtures/datamodel_description_sections_tree.xml +326 -0
  40. data/spec/fixtures/test.xmi +9250 -0
  41. data/spec/metanorma/processor_spec.rb +50 -50
  42. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +231 -143
  43. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +152 -0
  44. data/spec/vcr_cassettes/isobib_get_123.yml +51 -35
  45. data/spec/vcr_cassettes/isobib_get_123_1.yml +103 -71
  46. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +112 -80
  47. data/spec/vcr_cassettes/isobib_get_123_2001.yml +51 -35
  48. data/spec/vcr_cassettes/isobib_get_124.yml +51 -35
  49. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  50. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +49 -47
  51. metadata +10 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a43a3db1e4ef2ae43a1b2c7ecd980384cac2ee645668e414c73fd8e53dee3859
4
- data.tar.gz: 6f026c1bd2e1d0c5f2f327cdc345af6635ff1c1454479fd42709b9d18fda5e60
3
+ metadata.gz: dd98ba81df1c144552167e677b04d6152d838de0ea2d539a6bc7bde2a4b7f235
4
+ data.tar.gz: 68d9afff164047bf12f97ac23735cc1d61503172ae8656795393314d127223b6
5
5
  SHA512:
6
- metadata.gz: 7b20738029106d832a852db8eabf340058cdcbf75d8ce16def000478733c3633ad1144ac1aa2f736a637423c19f90491429fbec591987bc2f4af58bb3c8df087
7
- data.tar.gz: 69f3e40acdca71435cda97dbcd33e862ffbacbb4eeaff97e543b971ec2744c72227115013ef2ac3ee88552c64bf413a36c060adf3af58e6ebb86c6b85997b070
6
+ metadata.gz: 611ba153c4160486b0ea51eb1564e09cd81d02f6ca6d5a075e3f38cf321321f2e019ba538341786bd4fe01eac9ef53e71ddc5cc19fdccb4e69189d9e7a720955
7
+ data.tar.gz: 0acb358132209888abe3a276c16abcfdf142570fd271712960e64e02db487df9bb39081a1f4e08da7347777a71240b57b2d8f6dda7d980523981efe5a838495c
@@ -53,6 +53,7 @@ module Asciidoctor
53
53
  htmltoclevels: node.attr("htmltoclevels") || node.attr("toclevels"),
54
54
  doctoclevels: node.attr("doctoclevels") || node.attr("toclevels"),
55
55
  break_up_urls_in_tables: node.attr("break-up-urls-in-tables"),
56
+ suppressasciimathdup: node.attr("suppress-asciimath-dup"),
56
57
  bare: node.attr("bare"),
57
58
  sectionsplit: node.attr("sectionsplit"),
58
59
  }
@@ -62,6 +63,12 @@ module Asciidoctor
62
63
  IsoDoc::HtmlConvert.new(html_extract_attributes(node))
63
64
  end
64
65
 
66
+ def pdf_converter(node)
67
+ return nil if node.attr("no-pdf")
68
+
69
+ IsoDoc::Standoc::PdfConvert.new(doc_extract_attributes(node))
70
+ end
71
+
65
72
  def doc_extract_attributes(node)
66
73
  attrs = {
67
74
  script: node.attr("script"),
@@ -81,6 +88,7 @@ module Asciidoctor
81
88
  htmltoclevels: node.attr("htmltoclevels") || node.attr("toclevels"),
82
89
  doctoclevels: node.attr("doctoclevels") || node.attr("toclevels"),
83
90
  break_up_urls_in_tables: node.attr("break-up-urls-in-tables"),
91
+ suppressasciimathdup: node.attr("suppress-asciimath-dup"),
84
92
  bare: node.attr("bare"),
85
93
  }
86
94
 
@@ -114,11 +122,11 @@ module Asciidoctor
114
122
  node.attr("mn-keep-asciimath") != "false"
115
123
  @fontheader = default_fonts(node)
116
124
  @files_to_delete = []
117
- if node.attr("docfile")
118
- @filename = File.basename(node.attr("docfile"))&.gsub(/\.adoc$/, "")
119
- else
120
- @filename = ""
121
- end
125
+ @filename = if node.attr("docfile")
126
+ File.basename(node.attr("docfile"))&.gsub(/\.adoc$/, "")
127
+ else
128
+ ""
129
+ end
122
130
  @localdir = Metanorma::Utils::localdir(node)
123
131
  @output_dir = outputdir node
124
132
  @no_isobib_cache = node.attr("no-isobib-cache")
@@ -156,6 +164,8 @@ module Asciidoctor
156
164
  nil, false, "#{@filename}.html")
157
165
  doc_converter(node).convert("#{@filename}.presentation.xml",
158
166
  nil, false, "#{@filename}.doc")
167
+ pdf_converter(node)&.convert("#{@filename}.presentation.xml",
168
+ nil, false, "#{@filename}.pdf")
159
169
  end
160
170
 
161
171
  def document(node)
@@ -10,15 +10,17 @@ module Asciidoctor
10
10
  end
11
11
 
12
12
  def id_unnum_attrs(node)
13
- attr_code( id: Metanorma::Utils::anchor_or_uuid(node),
13
+ attr_code(id: Metanorma::Utils::anchor_or_uuid(node),
14
14
  unnumbered: node.option?("unnumbered") ? "true" : nil,
15
15
  number: node.attr("number"),
16
- subsequence: node.attr("subsequence") )
16
+ subsequence: node.attr("subsequence"))
17
17
  end
18
18
 
19
19
  def formula_attrs(node)
20
- attr_code(id_unnum_attrs(node).merge(keep_attrs(node).merge(
21
- inequality: node.option?("inequality") ? "true" : nil)))
20
+ attr_code(id_unnum_attrs(node)
21
+ .merge(keep_attrs(node).merge(
22
+ inequality: node.option?("inequality") ? "true" : nil,
23
+ )))
22
24
  end
23
25
 
24
26
  def keep_attrs(node)
@@ -58,8 +60,8 @@ module Asciidoctor
58
60
  xml.figure **literal_attrs(node) do |f|
59
61
  figure_title(node, f)
60
62
  f.pre node.lines.join("\n"),
61
- **attr_code(id: Metanorma::Utils::anchor_or_uuid,
62
- alt: node.attr("alt"))
63
+ **attr_code(id: Metanorma::Utils::anchor_or_uuid,
64
+ alt: node.attr("alt"))
63
65
  end
64
66
  end
65
67
  end
@@ -95,20 +97,21 @@ module Asciidoctor
95
97
  end
96
98
 
97
99
  def svgmap_attrs(node)
98
- attr_code( { id: node.id,
99
- unnumbered: node.option?("unnumbered") ? "true" : nil,
100
- number: node.attr("number"),
101
- subsequence: node.attr("subsequence") }.
102
- merge(keep_attrs(node)))
100
+ attr_code({ id: node.id,
101
+ unnumbered: node.option?("unnumbered") ? "true" : nil,
102
+ number: node.attr("number"),
103
+ subsequence: node.attr("subsequence") }
104
+ .merge(keep_attrs(node)))
103
105
  end
104
106
 
105
107
  def svgmap_example(node)
106
108
  noko do |xml|
107
109
  xml.svgmap **attr_code(svgmap_attrs(node).merge(
108
- src: node.attr("src"), alt: node.attr("alt"))) do |ex|
109
- figure_title(node, ex)
110
- ex << node.content
111
- end
110
+ src: node.attr("src"), alt: node.attr("alt"),
111
+ )) do |ex|
112
+ figure_title(node, ex)
113
+ ex << node.content
114
+ end
112
115
  end.join("\n")
113
116
  end
114
117
 
@@ -136,9 +139,10 @@ module Asciidoctor
136
139
  end.join("\n")
137
140
  end
138
141
 
139
- def figure_title(node, f)
142
+ def figure_title(node, out)
140
143
  return if node.title.nil?
141
- f.name { |name| name << node.title }
144
+
145
+ out.name { |name| name << node.title }
142
146
  end
143
147
 
144
148
  def figure_attrs(node)
@@ -149,15 +153,17 @@ module Asciidoctor
149
153
  noko do |xml|
150
154
  xml.figure **figure_attrs(node) do |f|
151
155
  figure_title(node, f)
152
- f.image **(image_attributes(node))
156
+ f.image **image_attributes(node)
153
157
  end
154
158
  end
155
159
  end
156
160
 
157
161
  def para_attrs(node)
158
162
  attr_code(keep_attrs(node)
159
- .merge(align: node.attr("align"),
160
- id: Metanorma::Utils::anchor_or_uuid(node)))
163
+ .merge(align: node.attr("align"),
164
+ variant_title: node.role == "variant-title" ? true : nil,
165
+ type: node.attr("type"),
166
+ id: Metanorma::Utils::anchor_or_uuid(node)))
161
167
  end
162
168
 
163
169
  def paragraph(node)
@@ -172,8 +178,8 @@ module Asciidoctor
172
178
 
173
179
  def quote_attrs(node)
174
180
  attr_code(keep_attrs(node)
175
- .merge(align: node.attr("align"),
176
- id: Metanorma::Utils::anchor_or_uuid(node)))
181
+ .merge(align: node.attr("align"),
182
+ id: Metanorma::Utils::anchor_or_uuid(node)))
177
183
  end
178
184
 
179
185
  def quote_attribution(node, out)
@@ -189,7 +195,7 @@ module Asciidoctor
189
195
 
190
196
  def quote(node)
191
197
  noko do |xml|
192
- xml.quote **(quote_attrs(node)) do |q|
198
+ xml.quote **quote_attrs(node) do |q|
193
199
  quote_attribution(node, q)
194
200
  wrap_in_para(node, q)
195
201
  end
@@ -197,18 +203,18 @@ module Asciidoctor
197
203
  end
198
204
 
199
205
  def listing_attrs(node)
200
- attr_code(keep_attrs(node).
201
- merge(lang: node.attr("language"),
202
- id: Metanorma::Utils::anchor_or_uuid(node),
203
- unnumbered: node.option?("unnumbered") ? "true" : nil,
204
- number: node.attr("number"),
205
- filename: node.attr("filename")))
206
+ attr_code(keep_attrs(node)
207
+ .merge(lang: node.attr("language"),
208
+ id: Metanorma::Utils::anchor_or_uuid(node),
209
+ unnumbered: node.option?("unnumbered") ? "true" : nil,
210
+ number: node.attr("number"),
211
+ filename: node.attr("filename")))
206
212
  end
207
213
 
208
214
  # NOTE: html escaping is performed by Nokogiri
209
215
  def listing(node)
210
216
  fragment = ::Nokogiri::XML::Builder.new do |xml|
211
- xml.sourcecode **(listing_attrs(node)) do |s|
217
+ xml.sourcecode **listing_attrs(node) do |s|
212
218
  figure_title(node, s)
213
219
  s << node.content
214
220
  end
@@ -219,7 +225,7 @@ module Asciidoctor
219
225
 
220
226
  def pass(node)
221
227
  noko do |xml|
222
- xml.passthrough **attr_code(formats:
228
+ xml.passthrough **attr_code(formats:
223
229
  node.attr("format") || "metanorma") do |p|
224
230
  p << HTMLEntities.new.encode(node.content, :basic, :hexadecimal)
225
231
  end
@@ -13,19 +13,12 @@ require_relative "./cleanup_amend"
13
13
  require_relative "./cleanup_maths"
14
14
  require_relative "./cleanup_image"
15
15
  require_relative "./cleanup_reqt"
16
+ require_relative "./cleanup_text"
16
17
  require "relaton_iev"
17
18
 
18
19
  module Asciidoctor
19
20
  module Standoc
20
21
  module Cleanup
21
- def textcleanup(result)
22
- text = result.flatten.map { |l| l.sub(/\s*$/, "") } * "\n"
23
- !@keepasciimath and text = asciimath2mathml(text)
24
- text = text.gsub(/\s+<fn /, "<fn ")
25
- text.gsub(%r{<passthrough\s+formats="metanorma">([^<]*)
26
- </passthrough>}mx) { HTMLEntities.new.decode($1) }
27
- end
28
-
29
22
  def cleanup(xmldoc)
30
23
  element_name_cleanup(xmldoc)
31
24
  sections_cleanup(xmldoc)
@@ -72,62 +65,6 @@ module Asciidoctor
72
65
  xmldoc
73
66
  end
74
67
 
75
- IGNORE_DUMBQUOTES = "//pre | //pre//* | //tt | //tt//* | "\
76
- "//sourcecode | //sourcecode//* | //bibdata//* | //stem | "\
77
- "//stem//* | //figure[@class = 'pseudocode'] | "\
78
- "//figure[@class = 'pseudocode']//*".freeze
79
-
80
- def smartquotes_cleanup(xmldoc)
81
- xmldoc.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
82
- if @smartquotes then smartquotes_cleanup1(xmldoc)
83
- else dumbquote_cleanup(xmldoc)
84
- end
85
- end
86
-
87
- def smartquotes_cleanup1(xmldoc)
88
- uninterrupt_quotes_around_xml(xmldoc)
89
- dumb2smart_quotes(xmldoc)
90
- end
91
-
92
- # "abc<tag/>", def => "abc",<tag/> def
93
- def uninterrupt_quotes_around_xml(xmldoc)
94
- xmldoc.xpath("//*[following::text()[1]"\
95
- "[starts-with(., '\"') or starts-with(., \"'\")]]")
96
- .each do |x|
97
- uninterrupt_quotes_around_xml1(x)
98
- end
99
- end
100
-
101
- def uninterrupt_quotes_around_xml1(elem)
102
- prev = elem.at(".//preceding::text()[1]") or return
103
- /\S$/.match?(prev.text) or return
104
- foll = elem.at(".//following::text()[1]")
105
- m = /^(["'][[:punct:]]*)(\s|$)/.match(foll&.text) or return
106
- foll.content = foll.text.sub(/^(["'][[:punct:]]*)/, "")
107
- prev.content = "#{prev.text}#{m[1]}"
108
- end
109
-
110
- def dumb2smart_quotes(xmldoc)
111
- (xmldoc.xpath("//*[child::text()]") - xmldoc.xpath(IGNORE_DUMBQUOTES))
112
- .each do |x|
113
- x.children.each do |n|
114
- next unless n.text?
115
-
116
- /[-'"(<>]|\.\.|\dx/.match(n) or next
117
-
118
- n.replace(Metanorma::Utils::smartformat(n.text))
119
- end
120
- end
121
- end
122
-
123
- def dumbquote_cleanup(xmldoc)
124
- xmldoc.traverse do |n|
125
- next unless n.text?
126
-
127
- n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'")) # .
128
- end
129
- end
130
-
131
68
  def docidentifier_cleanup(xmldoc); end
132
69
 
133
70
  TEXT_ELEMS =
@@ -171,8 +108,8 @@ module Asciidoctor
171
108
 
172
109
  c.xpath("./variant").each do |n|
173
110
  if n.at_xpath("preceding-sibling::node()"\
174
- "[not(self::text()[not(normalize-space())])][1]"\
175
- "[self::variantwrap]")
111
+ "[not(self::text()[not(normalize-space())])][1]"\
112
+ "[self::variantwrap]")
176
113
  n.previous_element << n
177
114
  else
178
115
  n.replace("<variantwrap/>").first << n
@@ -202,11 +139,11 @@ module Asciidoctor
202
139
  end
203
140
 
204
141
  def toc_index(toc, xmldoc)
205
- depths = toc.xpath("./toc-xpath").each_with_object({}) do |x, m|
206
- m[x.text] = x["depth"]
207
- end
142
+ depths = toc_index_depths(toc)
208
143
  depths.keys.each_with_object([]) do |key, arr|
209
144
  xmldoc.xpath(key).each do |x|
145
+ t = x.at("./following-sibling::variant-title[@type = 'toc']") and
146
+ x = t
210
147
  arr << { text: x.children.to_xml, depth: depths[key].to_i,
211
148
  target: x.xpath("(./ancestor-or-self::*/@id)[last()]")[0].text,
212
149
  line: x.line }
@@ -214,6 +151,12 @@ module Asciidoctor
214
151
  end.sort_by { |a| a[:line] }
215
152
  end
216
153
 
154
+ def toc_index_depths(toc)
155
+ toc.xpath("./toc-xpath").each_with_object({}) do |x, m|
156
+ m[x.text] = x["depth"]
157
+ end
158
+ end
159
+
217
160
  def toc_cleanup1(toc, xmldoc)
218
161
  depth = 1
219
162
  ret = ""
@@ -7,8 +7,11 @@ module Asciidoctor
7
7
  def para_cleanup(xmldoc)
8
8
  ["//p[not(ancestor::bibdata)]", "//ol[not(ancestor::bibdata)]",
9
9
  "//ul[not(ancestor::bibdata)]", "//quote[not(ancestor::bibdata)]",
10
- "//note[not(ancestor::bibitem or ancestor::table or ancestor::bibdata)]"
11
- ].each { |w| inject_id(xmldoc, w) }
10
+ "//note[not(ancestor::bibitem or ancestor::table or ancestor::bibdata)]"].each do |w|
11
+ inject_id(
12
+ xmldoc, w
13
+ )
14
+ end
12
15
  end
13
16
 
14
17
  def inject_id(xmldoc, path)
@@ -205,7 +208,7 @@ module Asciidoctor
205
208
  def safe_noko(text, doc)
206
209
  Nokogiri::XML::Text.new(text, doc).to_xml(
207
210
  encoding: "US-ASCII",
208
- save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
211
+ save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION,
209
212
  )
210
213
  end
211
214
 
@@ -29,19 +29,19 @@ module Asciidoctor
29
29
  x.to_xml
30
30
  end
31
31
 
32
- def xml_unescape_mathml(x)
33
- return if x.children.any? { |y| y.element? }
32
+ def xml_unescape_mathml(xml)
33
+ return if xml.children.any? { |y| y.element? }
34
34
 
35
- math = x.text.gsub(/&lt;/, "<").gsub(/&gt;/, ">")
35
+ math = xml.text.gsub(/&lt;/, "<").gsub(/&gt;/, ">")
36
36
  .gsub(/&quot;/, '"').gsub(/&apos;/, "'").gsub(/&amp;/, "&")
37
37
  .gsub(/<[^: \r\n\t\/]+:/, "<").gsub(/<\/[^ \r\n\t:]+:/, "</")
38
- x.children = math
38
+ xml.children = math
39
39
  end
40
40
 
41
41
  MATHML_NS = "http://www.w3.org/1998/Math/MathML".freeze
42
42
 
43
- def mathml_preserve_space(m)
44
- m.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
43
+ def mathml_preserve_space(math)
44
+ math.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
45
45
  x.children = x.children.to_xml
46
46
  .gsub(/^\s/, "&#xA0;").gsub(/\s$/, "&#xA0;")
47
47
  end
@@ -57,23 +57,23 @@ module Asciidoctor
57
57
  end
58
58
 
59
59
  # presuppose multichar mi upright, singlechar mi MathML default italic
60
- def mathml_italicise(x)
61
- x.xpath(".//m:mi[not(ancestor::*[@mathvariant])]",
62
- "m" => MATHML_NS).each do |i|
60
+ def mathml_italicise(xml)
61
+ xml.xpath(".//m:mi[not(ancestor::*[@mathvariant])]",
62
+ "m" => MATHML_NS).each do |i|
63
63
  char = HTMLEntities.new.decode(i.text)
64
64
  i["mathvariant"] = "normal" if mi_italicise?(char)
65
65
  end
66
66
  end
67
67
 
68
- def mi_italicise?(c)
69
- return false if c.length > 1
68
+ def mi_italicise?(char)
69
+ return false if char.length > 1
70
70
 
71
- if /\p{Greek}/.match?(c)
72
- /\p{Lower}/.match(c) && !mathml_mi_italics[:lowergreek] ||
73
- /\p{Upper}/.match(c) && !mathml_mi_italics[:uppergreek]
74
- elsif /\p{Latin}/.match?(c)
75
- /\p{Lower}/.match(c) && !mathml_mi_italics[:lowerroman] ||
76
- /\p{Upper}/.match(c) && !mathml_mi_italics[:upperroman]
71
+ if /\p{Greek}/.match?(char)
72
+ /\p{Lower}/.match(char) && !mathml_mi_italics[:lowergreek] ||
73
+ /\p{Upper}/.match(char) && !mathml_mi_italics[:uppergreek]
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
77
  else
78
78
  false
79
79
  end
@@ -100,14 +100,14 @@ module Asciidoctor
100
100
  end
101
101
  end
102
102
 
103
- def gather_unitsml(unitsml, xmldoc, t)
104
- tags = xmldoc.xpath(".//m:#{t}", "m" => UNITSML_NS)
103
+ def gather_unitsml(unitsml, xmldoc, tag)
104
+ tags = xmldoc.xpath(".//m:#{tag}", "m" => UNITSML_NS)
105
105
  .each_with_object({}) do |x, m|
106
106
  m[x["id"]] = x.remove
107
107
  end
108
108
  return if tags.empty?
109
109
 
110
- set = unitsml.add_child("<#{t}Set/>").first
110
+ set = unitsml.add_child("<#{tag}Set/>").first
111
111
  tags.each_value { |v| set << v }
112
112
  end
113
113
 
@@ -115,14 +115,106 @@ module Asciidoctor
115
115
  { multiplier: :space }
116
116
  end
117
117
 
118
+ def mathvariant_override(inner, outer)
119
+ case outer
120
+ when "bold"
121
+ case inner
122
+ when "normal" then "bold"
123
+ when "italic" then "bold-italic"
124
+ when "fraktur" then "bold-fraktur"
125
+ when "script" then "bold-script"
126
+ when "sans-serif" then "bold-sans-serif"
127
+ when "sans-serif-italic" then "sans-serif-bold-italic"
128
+ else inner
129
+ end
130
+ when "italic"
131
+ case inner
132
+ when "normal" then "italic"
133
+ when "bold" then "bold-italic"
134
+ when "sans-serif" then "sans-serif-italic"
135
+ when "bold-sans-serif" then "sans-serif-bold-italic"
136
+ else inner
137
+ end
138
+ when "bold-italic"
139
+ case inner
140
+ when "normal", "bold", "italic" then "bold-italic"
141
+ when "sans-serif", "bold-sans-serif", "sans-serif-italic"
142
+ "sans-serif-bold-italic"
143
+ else inner
144
+ end
145
+ when "fraktur"
146
+ case inner
147
+ when "normal" then "fraktur"
148
+ when "bold" then "bold-fraktur"
149
+ else inner
150
+ end
151
+ when "bold-fraktur"
152
+ case inner
153
+ when "normal", "fraktur" then "bold-fraktur"
154
+ else inner
155
+ end
156
+ when "script"
157
+ case inner
158
+ when "normal" then "script"
159
+ when "bold" then "bold-script"
160
+ else inner
161
+ end
162
+ when "bold-script"
163
+ case inner
164
+ when "normal", "script" then "bold-script"
165
+ else inner
166
+ end
167
+ when "sans-serif"
168
+ case inner
169
+ when "normal" then "sans-serif"
170
+ when "bold" then "bold-sans-serif"
171
+ when "italic" then "sans-serif-italic"
172
+ when "bold-italic" then "sans-serif-bold-italic"
173
+ else inner
174
+ end
175
+ when "bold-sans-serif"
176
+ case inner
177
+ when "normal", "bold", "sans-serif" then "bold-sans-serif"
178
+ when "italic", "bold-italic", "sans-serif-italic"
179
+ "sans-serif-bold-italic"
180
+ else inner
181
+ end
182
+ when "sans-serif-italic"
183
+ case inner
184
+ when "normal", "italic", "sans-serif" then "sans-serif-italic"
185
+ when "bold", "bold-italic", "sans-serif-bold"
186
+ "sans-serif-bold-italic"
187
+ else inner
188
+ end
189
+ when "sans-serif-bold-italic"
190
+ case inner
191
+ when "normal", "italic", "sans-serif", "sans-serif-italic",
192
+ "bold", "bold-italic", "sans-serif-bold"
193
+ "sans-serif-bold-italic"
194
+ else inner
195
+ end
196
+ else inner
197
+ end
198
+ end
199
+
200
+ def mathml_mathvariant(math)
201
+ math.xpath(".//*[@mathvariant]").each do |outer|
202
+ outer.xpath(".//*[@mathvariant]").each do |inner|
203
+ inner["mathvariant"] =
204
+ mathvariant_override(outer["mathvariant"], inner["mathvariant"])
205
+ end
206
+ end
207
+ end
208
+
118
209
  def mathml_cleanup(xmldoc)
119
210
  unitsml = Asciimath2UnitsML::Conv.new(asciimath2unitsml_options)
120
211
  xmldoc.xpath("//stem[@type = 'MathML']").each do |x|
121
212
  xml_unescape_mathml(x)
122
213
  mathml_namespace(x)
123
214
  mathml_preserve_space(x)
124
- mathml_italicise(x)
125
215
  unitsml.MathML2UnitsML(x)
216
+ mathml_mathvariant(x)
217
+ mathml_italicise(x)
126
218
  end
127
219
  mathml_unitsML(xmldoc)
128
220
  end