metanorma-standoc 1.8.5 → 1.9.1

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +5 -1
  4. data/Gemfile.devel +0 -0
  5. data/lib/asciidoctor/standoc/base.rb +41 -36
  6. data/lib/asciidoctor/standoc/biblio.rng +4 -6
  7. data/lib/asciidoctor/standoc/blocks.rb +27 -12
  8. data/lib/asciidoctor/standoc/blocks_notes.rb +20 -14
  9. data/lib/asciidoctor/standoc/cleanup.rb +32 -78
  10. data/lib/asciidoctor/standoc/cleanup_block.rb +56 -59
  11. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +32 -21
  12. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +1 -0
  13. data/lib/asciidoctor/standoc/cleanup_image.rb +71 -0
  14. data/lib/asciidoctor/standoc/cleanup_maths.rb +37 -28
  15. data/lib/asciidoctor/standoc/cleanup_ref.rb +21 -13
  16. data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +1 -1
  17. data/lib/asciidoctor/standoc/cleanup_reqt.rb +47 -0
  18. data/lib/asciidoctor/standoc/cleanup_section.rb +21 -15
  19. data/lib/asciidoctor/standoc/converter.rb +3 -1
  20. data/lib/asciidoctor/standoc/front.rb +35 -18
  21. data/lib/asciidoctor/standoc/front_contributor.rb +5 -5
  22. data/lib/asciidoctor/standoc/inline.rb +1 -1
  23. data/lib/asciidoctor/standoc/isodoc.rng +130 -1
  24. data/lib/asciidoctor/standoc/lists.rb +4 -2
  25. data/lib/asciidoctor/standoc/macros.rb +40 -13
  26. data/lib/asciidoctor/standoc/ref.rb +87 -112
  27. data/lib/asciidoctor/standoc/ref_date_id.rb +62 -0
  28. data/lib/asciidoctor/standoc/ref_sect.rb +12 -12
  29. data/lib/asciidoctor/standoc/terms.rb +10 -6
  30. data/lib/asciidoctor/standoc/utils.rb +32 -6
  31. data/lib/asciidoctor/standoc/validate.rb +12 -12
  32. data/lib/metanorma/standoc/version.rb +5 -5
  33. data/metanorma-standoc.gemspec +11 -11
  34. data/spec/asciidoctor/base_spec.rb +78 -8
  35. data/spec/asciidoctor/blocks_spec.rb +10 -0
  36. data/spec/asciidoctor/cleanup_sections_spec.rb +14 -14
  37. data/spec/asciidoctor/cleanup_spec.rb +1860 -1874
  38. data/spec/asciidoctor/inline_spec.rb +272 -273
  39. data/spec/asciidoctor/macros_spec.rb +8 -2
  40. data/spec/asciidoctor/refs_spec.rb +135 -7
  41. data/spec/asciidoctor/section_spec.rb +670 -687
  42. data/spec/assets/html-override.css +1 -0
  43. data/spec/assets/word-override.css +1 -0
  44. data/spec/spec_helper.rb +11 -9
  45. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +60 -60
  46. data/spec/vcr_cassettes/isobib_get_123.yml +16 -16
  47. data/spec/vcr_cassettes/isobib_get_123_1.yml +32 -32
  48. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +41 -41
  49. data/spec/vcr_cassettes/isobib_get_123_2001.yml +15 -15
  50. data/spec/vcr_cassettes/isobib_get_124.yml +17 -17
  51. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  52. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +53 -49
  53. metadata +71 -68
  54. data/.rubocop.ribose.yml +0 -66
  55. data/.rubocop.tb.yml +0 -650
  56. data/spec/asciidoctor/macros_lutaml_spec.rb +0 -80
@@ -29,7 +29,7 @@ module Asciidoctor
29
29
  def dl2_table_cleanup(xmldoc)
30
30
  q = "//table/following-sibling::*[1][self::p]"
31
31
  xmldoc.xpath(q).each do |s|
32
- if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
32
+ if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
33
33
  s.next_element["key"] = "true"
34
34
  s.previous_element << s.next_element.remove
35
35
  s.remove
@@ -40,6 +40,7 @@ module Asciidoctor
40
40
  def insert_thead(s)
41
41
  thead = s.at("./thead")
42
42
  return thead unless thead.nil?
43
+
43
44
  if tname = s.at("./name")
44
45
  thead = tname.add_next_sibling("<thead/>").first
45
46
  return thead
@@ -80,22 +81,22 @@ module Asciidoctor
80
81
  end
81
82
 
82
83
  # include where definition list inside stem block
83
- def formula_cleanup(x)
84
- formula_cleanup_where1(x)
85
- formula_cleanup_where2(x)
84
+ def formula_cleanup(formula)
85
+ formula_cleanup_where1(formula)
86
+ formula_cleanup_where2(formula)
86
87
  end
87
88
 
88
- def formula_cleanup_where1(x)
89
+ def formula_cleanup_where1(formula)
89
90
  q = "//formula/following-sibling::*[1][self::dl]"
90
- x.xpath(q).each do |s|
91
+ formula.xpath(q).each do |s|
91
92
  s["key"] == "true" and s.previous_element << s.remove
92
93
  end
93
94
  end
94
95
 
95
- def formula_cleanup_where2(x)
96
+ def formula_cleanup_where2(formula)
96
97
  q = "//formula/following-sibling::*[1][self::p]"
97
- x.xpath(q).each do |s|
98
- if s.text =~ /^\s*where[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
98
+ formula.xpath(q).each do |s|
99
+ if s.text =~ /^\s*where[^a-z]*$/i && s&.next_element&.name == "dl"
99
100
  s.next_element["key"] = "true"
100
101
  s.previous_element << s.next_element.remove
101
102
  s.remove
@@ -114,7 +115,7 @@ module Asciidoctor
114
115
  def figure_dl_cleanup2(xmldoc)
115
116
  q = "//figure/following-sibling::*[self::p]"
116
117
  xmldoc.xpath(q).each do |s|
117
- if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
118
+ if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
118
119
  s.next_element["key"] = "true"
119
120
  s.previous_element << s.next_element.remove
120
121
  s.remove
@@ -125,7 +126,10 @@ module Asciidoctor
125
126
  # examples containing only figures become subfigures of figures
126
127
  def subfigure_cleanup(xmldoc)
127
128
  xmldoc.xpath("//example[figure]").each do |e|
128
- next unless e.elements.map { |m| m.name }.reject { |m| %w(name figure).include? m }.empty?
129
+ next unless e.elements.map(&:name).reject do |m|
130
+ %w(name figure).include? m
131
+ end.empty?
132
+
129
133
  e.name = "figure"
130
134
  end
131
135
  end
@@ -140,82 +144,75 @@ module Asciidoctor
140
144
  ELEMS_ALLOW_NOTES = %w[p formula ul ol dl figure].freeze
141
145
 
142
146
  # if a note is at the end of a section, it is left alone
143
- # if a note is followed by a non-note block, it is moved inside its preceding block if it is not delimited
147
+ # if a note is followed by a non-note block,
148
+ # it is moved inside its preceding block if it is not delimited
144
149
  # (so there was no way of making that block include the note)
145
150
  def note_cleanup(xmldoc)
146
151
  q = "//note[following-sibling::*[not(local-name() = 'note')]]"
147
152
  xmldoc.xpath(q).each do |n|
148
153
  next if n["keep-separate"] == "true"
149
154
  next unless n.ancestors("table").empty?
155
+
150
156
  prev = n.previous_element || next
151
157
  n.parent = prev if ELEMS_ALLOW_NOTES.include? prev.name
152
158
  end
153
- xmldoc.xpath("//note[@keep-separate]").each { |n| n.delete("keep-separate") }
154
- xmldoc.xpath("//termnote[@keep-separate]").each { |n| n.delete("keep-separate") }
159
+ xmldoc.xpath("//note[@keep-separate] | "\
160
+ "//termnote[@keep-separate]").each do |n|
161
+ n.delete("keep-separate")
162
+ end
155
163
  end
156
164
 
157
- def requirement_cleanup(x)
158
- requirement_descriptions(x)
159
- requirement_inherit(x)
165
+ def link_callouts_to_annotations(callouts, annotations)
166
+ callouts.each_with_index do |c, i|
167
+ c["target"] = "_" + UUIDTools::UUID.random_create
168
+ annotations[i]["id"] = c["target"]
169
+ end
160
170
  end
161
171
 
162
- def requirement_inherit(x)
163
- x.xpath("//requirement | //recommendation | //permission").each do |r|
164
- ins = r.at("./classification") ||
165
- r.at("./description | ./measurementtarget | ./specification | "\
166
- "./verification | ./import | ./description | ./requirement | "\
167
- "./recommendation | ./permission")
168
- r.xpath("./*//inherit").each { |i| ins.previous = i }
172
+ def align_callouts_to_annotations(xmldoc)
173
+ xmldoc.xpath("//sourcecode").each do |x|
174
+ callouts = x.elements.select { |e| e.name == "callout" }
175
+ annotations = x.elements.select { |e| e.name == "annotation" }
176
+ callouts.size == annotations.size and
177
+ link_callouts_to_annotations(callouts, annotations)
169
178
  end
170
179
  end
171
180
 
172
- def requirement_descriptions(x)
173
- x.xpath("//requirement | //recommendation | //permission").each do |r|
174
- r.children.each do |e|
175
- unless e.element? && (reqt_subpart(e.name) ||
176
- %w(requirement recommendation permission).include?(e.name))
177
- t = Nokogiri::XML::Element.new("description", x)
178
- e.before(t)
179
- t.children = e.remove
180
- end
181
+ def merge_annotations_into_sourcecode(xmldoc)
182
+ xmldoc.xpath("//sourcecode").each do |x|
183
+ while x&.next_element&.name == "annotation"
184
+ x.next_element.parent = x
181
185
  end
182
- requirement_cleanup1(r)
183
186
  end
184
187
  end
185
188
 
186
- def requirement_cleanup1(r)
187
- while d = r.at("./description[following-sibling::*[1][self::description]]")
188
- n = d.next.remove
189
- d << n.children
190
- end
191
- r.xpath("./description[normalize-space(.)='']").each { |d| d.replace("\n") }
189
+ def callout_cleanup(xmldoc)
190
+ merge_annotations_into_sourcecode(xmldoc)
191
+ align_callouts_to_annotations(xmldoc)
192
192
  end
193
193
 
194
- def svgmap_cleanup(xmldoc)
195
- svgmap_populate(xmldoc)
196
- Metanorma::Utils::svgmap_rewrite(xmldoc, @localdir)
197
- end
194
+ def sourcecode_cleanup(xmldoc)
195
+ xmldoc.xpath("//sourcecode").each do |x|
196
+ x.traverse do |n|
197
+ next unless n.text?
198
+ next unless /#{Regexp.escape(@sourcecode_markup_start)}/.match?(n.text)
198
199
 
199
- def svgmap_populate(xmldoc)
200
- xmldoc.xpath("//svgmap").each do |s|
201
- s1 = s.dup
202
- s.children.remove
203
- f = s1.at(".//figure") and s << f
204
- s1.xpath(".//li").each do |li|
205
- t = li&.at(".//eref | .//link | .//xref") or next
206
- href = t.xpath("./following-sibling::node()")
207
- next if href.empty?
208
- s << %[<target href="#{svgmap_target(href)}">#{t.to_xml}</target>]
200
+ n.replace(sourcecode_markup(n))
209
201
  end
210
202
  end
211
203
  end
212
204
 
213
- def svgmap_target(nodeset)
214
- nodeset.each do |n|
215
- next unless n.name == "link"
216
- n.children = n["target"]
205
+ def sourcecode_markup(n)
206
+ acc = []
207
+ n.text.split(/(#{Regexp.escape(@sourcecode_markup_start)}|#{Regexp.escape(@sourcecode_markup_end)})/)
208
+ .each_slice(4).map do |a|
209
+ acc << Nokogiri::XML::Text.new(a[0], n.document)
210
+ .to_xml(encoding: "US-ASCII", save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
211
+ next unless a.size == 4
212
+
213
+ acc << Asciidoctor.convert(a[2], backend: (self&.backend&.to_sym || :standoc), doctype: :inline)
217
214
  end
218
- nodeset.text.sub(/^[,; ]/, "").strip
215
+ acc.join
219
216
  end
220
217
  end
221
218
  end
@@ -3,21 +3,26 @@ module Asciidoctor
3
3
  module Cleanup
4
4
  def external_terms_boilerplate(sources)
5
5
  @i18n.l10n(
6
- @i18n.external_terms_boilerplate.gsub(/%/, sources || "???"), @lang, @script)
6
+ @i18n.external_terms_boilerplate.gsub(/%/, sources || "???"),
7
+ @lang, @script
8
+ )
7
9
  end
8
10
 
9
11
  def internal_external_terms_boilerplate(sources)
10
12
  @i18n.l10n(
11
- @i18n.internal_external_terms_boilerplate.gsub(/%/, sources || "??"), @lang, @script)
13
+ @i18n.internal_external_terms_boilerplate.gsub(/%/, sources || "??"),
14
+ @lang, @script
15
+ )
12
16
  end
13
17
 
14
18
  def term_defs_boilerplate(div, source, term, preface, isodoc)
15
19
  a = @i18n.term_def_boilerplate and div.next = a
16
20
  source.each do |s|
17
21
  @anchors[s["bibitemid"]] or
18
- @log.add("Crossreferences", nil, "term source #{s['bibitemid']} not referenced")
22
+ @log.add("Crossreferences", nil,
23
+ "term source #{s['bibitemid']} not referenced")
19
24
  end
20
- a = (source.empty? && term.nil?) ? @i18n.no_terms_boilerplate :
25
+ a = source.empty? && term.nil? ? @i18n.no_terms_boilerplate :
21
26
  term_defs_boilerplate_cont(source, term, isodoc)
22
27
  a and div.next = a
23
28
  end
@@ -33,17 +38,19 @@ module Asciidoctor
33
38
  end
34
39
  end
35
40
 
36
- def norm_ref_preface(f)
37
- refs = f.elements.select do |e|
38
- ["reference", "bibitem"].include? e.name
41
+ def norm_ref_preface(ref)
42
+ refs = ref.elements.select do |e|
43
+ %w(references bibitem).include? e.name
39
44
  end
40
- f.at("./title").next =
41
- "<p>#{(refs.empty? ? @i18n.norm_empty_pref : @i18n.norm_with_refs_pref)}</p>"
45
+ pref = refs.empty? ? @i18n.norm_empty_pref : @i18n.norm_with_refs_pref
46
+ ref.at("./title").next = "<p>#{pref}</p>"
42
47
  end
43
48
 
44
- TERM_CLAUSE = "//sections/terms | //sections/clause[descendant::terms]".freeze
49
+ TERM_CLAUSE = "//sections/terms | "\
50
+ "//sections/clause[descendant::terms]".freeze
45
51
 
46
- NORM_REF = "//bibliography/references[@normative = 'true']".freeze
52
+ NORM_REF = "//bibliography/references[@normative = 'true'] | "\
53
+ "//bibliography/clause[.//references[@normative = 'true']]".freeze
47
54
 
48
55
  def boilerplate_isodoc(xmldoc)
49
56
  x = xmldoc.dup
@@ -55,7 +62,7 @@ module Asciidoctor
55
62
  end
56
63
 
57
64
  def termdef_boilerplate_cleanup(xmldoc)
58
- #termdef_remove_initial_paras(xmldoc)
65
+ # termdef_remove_initial_paras(xmldoc)
59
66
  end
60
67
 
61
68
  def termdef_remove_initial_paras(xmldoc)
@@ -76,6 +83,7 @@ module Asciidoctor
76
83
  termdef_boilerplate_cleanup(xmldoc)
77
84
  xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
78
85
  next if f.at("./clause[@type = 'boilerplate']")
86
+
79
87
  term_defs_boilerplate(f.at("./title"), xmldoc.xpath(".//termdocsource"),
80
88
  f.at(".//term"), f.at(".//p"), isodoc)
81
89
  end
@@ -84,15 +92,16 @@ module Asciidoctor
84
92
  initial_boilerplate(xmldoc, isodoc)
85
93
  end
86
94
 
87
- def initial_boilerplate(x, isodoc)
88
- return if x.at("//boilerplate")
89
- preface = x.at("//preface") || x.at("//sections") || x.at("//annex") ||
90
- x.at("//references") || return
91
- b = boilerplate(x, isodoc) or return
95
+ def initial_boilerplate(xml, isodoc)
96
+ return if xml.at("//boilerplate")
97
+
98
+ preface = xml.at("//preface") || xml.at("//sections") ||
99
+ xml.at("//annex") || xml.at("//references") || return
100
+ b = boilerplate(xml, isodoc) or return
92
101
  preface.previous = b
93
102
  end
94
103
 
95
- def boilerplate_file(xmldoc)
104
+ def boilerplate_file(_xmldoc)
96
105
  File.join(@libdir, "boilerplate.xml")
97
106
  end
98
107
 
@@ -100,7 +109,7 @@ module Asciidoctor
100
109
  file = boilerplate_file(xml)
101
110
  file = File.join(@localdir, @boilerplateauthority) if @boilerplateauthority
102
111
  !file.nil? and File.exists?(file) or return
103
- conv.populate_template((File.read(file, encoding: "UTF-8")), nil)
112
+ conv.populate_template(File.read(file, encoding: "UTF-8"), nil)
104
113
  end
105
114
 
106
115
  def bibdata_cleanup(xmldoc)
@@ -118,14 +127,16 @@ module Asciidoctor
118
127
  def bibdata_docidentifier_cleanup(xmldoc)
119
128
  ins = xmldoc.at("//bibdata/docidentifier")
120
129
  xmldoc.xpath("//bibdata/docidentifier").each_with_index do |b, i|
121
- next if i == 0
130
+ next if i.zero?
131
+
122
132
  ins.next = b.remove
123
133
  ins = ins.next
124
134
  end
125
135
  end
126
136
 
127
137
  def gather_indirect_erefs(xmldoc, prefix)
128
- xmldoc.xpath("//eref[@type = '#{prefix}']").each_with_object({}) do |e, m|
138
+ xmldoc.xpath("//eref[@type = '#{prefix}']")
139
+ .each_with_object({}) do |e, m|
129
140
  e.delete("type")
130
141
  m[e["bibitemid"]] = true
131
142
  end.keys
@@ -20,6 +20,7 @@ module Asciidoctor
20
20
  nomatches = true
21
21
  xmldoc.xpath(q).each do |s|
22
22
  next if s.children.map { |c| c.text? && /[[:alpha:]]/.match(c.text) }.any?
23
+
23
24
  s.previous_element << s.first_element_child.remove
24
25
  s.remove
25
26
  nomatches = false
@@ -0,0 +1,71 @@
1
+ module Asciidoctor
2
+ module Standoc
3
+ module Cleanup
4
+ def svgmap_cleanup(xmldoc)
5
+ svgmap_moveattrs(xmldoc)
6
+ svgmap_populate(xmldoc)
7
+ Metanorma::Utils::svgmap_rewrite(xmldoc, @localdir)
8
+ end
9
+
10
+ def guid?(str)
11
+ /^_[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
12
+ .match(str)
13
+ end
14
+
15
+ def svgmap_moveattrs(xmldoc)
16
+ xmldoc.xpath("//svgmap").each do |s|
17
+ f = s.at(".//figure") or next
18
+ if (t = s.at("./name")) && !f.at("./name")
19
+ f.children.first.previous = t.remove
20
+ end
21
+ if s["id"] && guid?(f["id"])
22
+ f["id"] = s["id"]
23
+ s.delete("id")
24
+ end
25
+ svgmap_moveattrs1(s, f)
26
+ end
27
+ end
28
+
29
+ def svgmap_moveattrs1(s, f)
30
+ %w(unnumbered number subsequence keep-with-next
31
+ keep-lines-together).each do |a|
32
+ next if f[a] || !s[a]
33
+
34
+ f[a] = s[a]
35
+ s.delete(a)
36
+ end
37
+ end
38
+
39
+ def svgmap_populate(xmldoc)
40
+ xmldoc.xpath("//svgmap").each do |s|
41
+ s1 = s.dup
42
+ s.children.remove
43
+ f = s1.at(".//figure") and s << f
44
+ s1.xpath(".//li").each do |li|
45
+ t = li&.at(".//eref | .//link | .//xref") or next
46
+ href = t.xpath("./following-sibling::node()")
47
+ href.empty? or
48
+ s << %[<target href="#{svgmap_target(href)}">#{t.to_xml}</target>]
49
+ end
50
+ end
51
+ end
52
+
53
+ def svgmap_target(nodeset)
54
+ nodeset.each do |n|
55
+ next unless n.name == "link"
56
+
57
+ n.children = n["target"]
58
+ end
59
+ nodeset.text.sub(/^[,; ]/, "").strip
60
+ end
61
+
62
+ def img_cleanup(xmldoc)
63
+ return xmldoc unless @datauriimage
64
+
65
+ xmldoc.xpath("//image").each do |i|
66
+ i["src"] = Metanorma::Utils::datauri(i["src"], @localdir)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -3,36 +3,39 @@ require "pathname"
3
3
  require "open-uri"
4
4
  require "html2doc"
5
5
  require "asciimath2unitsml"
6
- require_relative "./cleanup_block.rb"
7
- require_relative "./cleanup_footnotes.rb"
8
- require_relative "./cleanup_ref.rb"
9
- require_relative "./cleanup_ref_dl.rb"
10
- require_relative "./cleanup_boilerplate.rb"
11
- require_relative "./cleanup_section.rb"
12
- require_relative "./cleanup_terms.rb"
13
- require_relative "./cleanup_inline.rb"
14
- require_relative "./cleanup_amend.rb"
6
+ require_relative "./cleanup_block"
7
+ require_relative "./cleanup_footnotes"
8
+ require_relative "./cleanup_ref"
9
+ require_relative "./cleanup_ref_dl"
10
+ require_relative "./cleanup_boilerplate"
11
+ require_relative "./cleanup_section"
12
+ require_relative "./cleanup_terms"
13
+ require_relative "./cleanup_inline"
14
+ require_relative "./cleanup_amend"
15
15
  require "relaton_iev"
16
16
 
17
17
  module Asciidoctor
18
18
  module Standoc
19
19
  module Cleanup
20
20
  def asciimath2mathml(text)
21
- text = text.gsub(%r{<stem type="AsciiMath">(.+?)</stem>}m) do |m|
22
- "<amathstem>#{HTMLEntities.new.decode($1)}</amathstem>"
23
- end
24
- text = Html2Doc.asciimath_to_mathml(text, ["<amathstem>", "</amathstem>"])
25
- x = Nokogiri::XML(text)
26
- x.xpath("//*[local-name() = 'math'][not(parent::stem)]").each do |y|
27
- y.wrap("<stem type='MathML'></stem>")
28
- end
29
- x.to_xml
21
+ text = text.gsub(%r{<stem type="AsciiMath">(.+?)</stem>}m) do
22
+ "<amathstem>#{HTMLEntities.new.decode($1)}</amathstem>"
23
+ end
24
+ text = Html2Doc.asciimath_to_mathml(text,
25
+ ["<amathstem>", "</amathstem>"])
26
+ x = Nokogiri::XML(text)
27
+ x.xpath("//*[local-name() = 'math'][not(parent::stem)]").each do |y|
28
+ y.wrap("<stem type='MathML'></stem>")
29
+ end
30
+ x.to_xml
30
31
  end
31
32
 
32
33
  def xml_unescape_mathml(x)
33
34
  return if x.children.any? { |y| y.element? }
34
- math = x.text.gsub(/&lt;/, "<").gsub(/&gt;/, ">").gsub(/&quot;/, '"').gsub(/&apos;/, "'").gsub(/&amp;/, "&").
35
- gsub(/<[^: \r\n\t\/]+:/, "<").gsub(/<\/[^ \r\n\t:]+:/, "</")
35
+
36
+ math = x.text.gsub(/&lt;/, "<").gsub(/&gt;/, ">")
37
+ .gsub(/&quot;/, '"').gsub(/&apos;/, "'").gsub(/&amp;/, "&")
38
+ .gsub(/<[^: \r\n\t\/]+:/, "<").gsub(/<\/[^ \r\n\t:]+:/, "</")
36
39
  x.children = math
37
40
  end
38
41
 
@@ -40,12 +43,13 @@ module Asciidoctor
40
43
 
41
44
  def mathml_preserve_space(m)
42
45
  m.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
43
- x.children = x.children.to_xml.gsub(/^\s/, "&#xA0;").gsub(/\s$/, "&#xA0;")
46
+ x.children = x.children.to_xml
47
+ .gsub(/^\s/, "&#xA0;").gsub(/\s$/, "&#xA0;")
44
48
  end
45
49
  end
46
50
 
47
51
  def mathml_namespace(stem)
48
- stem.xpath("./math", ).each { |x| x.default_namespace = MATHML_NS }
52
+ stem.xpath("./math").each { |x| x.default_namespace = MATHML_NS }
49
53
  end
50
54
 
51
55
  def mathml_mi_italics
@@ -55,7 +59,8 @@ module Asciidoctor
55
59
 
56
60
  # presuppose multichar mi upright, singlechar mi MathML default italic
57
61
  def mathml_italicise(x)
58
- x.xpath(".//m:mi[not(ancestor::*[@mathvariant])]", "m" => MATHML_NS).each do |i|
62
+ x.xpath(".//m:mi[not(ancestor::*[@mathvariant])]",
63
+ "m" => MATHML_NS).each do |i|
59
64
  char = HTMLEntities.new.decode(i.text)
60
65
  i["mathvariant"] = "normal" if mi_italicise?(char)
61
66
  end
@@ -63,10 +68,11 @@ module Asciidoctor
63
68
 
64
69
  def mi_italicise?(c)
65
70
  return false if c.length > 1
66
- if /\p{Greek}/.match(c)
71
+
72
+ if /\p{Greek}/.match?(c)
67
73
  /\p{Lower}/.match(c) && !mathml_mi_italics[:lowergreek] ||
68
74
  /\p{Upper}/.match(c) && !mathml_mi_italics[:uppergreek]
69
- elsif /\p{Latin}/.match(c)
75
+ elsif /\p{Latin}/.match?(c)
70
76
  /\p{Lower}/.match(c) && !mathml_mi_italics[:lowerroman] ||
71
77
  /\p{Upper}/.match(c) && !mathml_mi_italics[:upperroman]
72
78
  else
@@ -74,7 +80,7 @@ module Asciidoctor
74
80
  end
75
81
  end
76
82
 
77
- UNITSML_NS = "http://unitsml.nist.gov/2005".freeze
83
+ UNITSML_NS = "https://schema.unitsml.org/unitsml/1.0".freeze
78
84
 
79
85
  def add_misc_container(xmldoc)
80
86
  unless ins = xmldoc.at("//misc-container")
@@ -87,6 +93,7 @@ module Asciidoctor
87
93
 
88
94
  def mathml_unitsML(xmldoc)
89
95
  return unless xmldoc.at(".//m:*", "m" => UNITSML_NS)
96
+
90
97
  misc = add_misc_container(xmldoc)
91
98
  unitsml = misc.add_child("<UnitsML xmlns='#{UNITSML_NS}'/>").first
92
99
  %w(Unit CountedItem Quantity Dimension Prefix).each do |t|
@@ -95,12 +102,14 @@ module Asciidoctor
95
102
  end
96
103
 
97
104
  def gather_unitsml(unitsml, xmldoc, t)
98
- tags = xmldoc.xpath(".//m:#{t}", "m" => UNITSML_NS).each_with_object({}) do |x, m|
105
+ tags = xmldoc.xpath(".//m:#{t}", "m" => UNITSML_NS)
106
+ .each_with_object({}) do |x, m|
99
107
  m[x["id"]] = x.remove
100
108
  end
101
109
  return if tags.empty?
110
+
102
111
  set = unitsml.add_child("<#{t}Set/>").first
103
- tags.values.each { |v| set << v }
112
+ tags.each_value { |v| set << v }
104
113
  end
105
114
 
106
115
  def asciimath2unitsml_options