metanorma-standoc 1.10.3 → 1.10.5

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