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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +5 -1
- data/Gemfile.devel +0 -0
- data/lib/asciidoctor/standoc/base.rb +41 -36
- data/lib/asciidoctor/standoc/biblio.rng +4 -6
- data/lib/asciidoctor/standoc/blocks.rb +27 -12
- data/lib/asciidoctor/standoc/blocks_notes.rb +20 -14
- data/lib/asciidoctor/standoc/cleanup.rb +32 -78
- data/lib/asciidoctor/standoc/cleanup_block.rb +56 -59
- data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +32 -21
- data/lib/asciidoctor/standoc/cleanup_footnotes.rb +1 -0
- data/lib/asciidoctor/standoc/cleanup_image.rb +71 -0
- data/lib/asciidoctor/standoc/cleanup_maths.rb +37 -28
- data/lib/asciidoctor/standoc/cleanup_ref.rb +21 -13
- data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +1 -1
- data/lib/asciidoctor/standoc/cleanup_reqt.rb +47 -0
- data/lib/asciidoctor/standoc/cleanup_section.rb +21 -15
- data/lib/asciidoctor/standoc/converter.rb +3 -1
- data/lib/asciidoctor/standoc/front.rb +35 -18
- data/lib/asciidoctor/standoc/front_contributor.rb +5 -5
- data/lib/asciidoctor/standoc/inline.rb +1 -1
- data/lib/asciidoctor/standoc/isodoc.rng +130 -1
- data/lib/asciidoctor/standoc/lists.rb +4 -2
- data/lib/asciidoctor/standoc/macros.rb +40 -13
- data/lib/asciidoctor/standoc/ref.rb +87 -112
- data/lib/asciidoctor/standoc/ref_date_id.rb +62 -0
- data/lib/asciidoctor/standoc/ref_sect.rb +12 -12
- data/lib/asciidoctor/standoc/terms.rb +10 -6
- data/lib/asciidoctor/standoc/utils.rb +32 -6
- data/lib/asciidoctor/standoc/validate.rb +12 -12
- data/lib/metanorma/standoc/version.rb +5 -5
- data/metanorma-standoc.gemspec +11 -11
- data/spec/asciidoctor/base_spec.rb +78 -8
- data/spec/asciidoctor/blocks_spec.rb +10 -0
- data/spec/asciidoctor/cleanup_sections_spec.rb +14 -14
- data/spec/asciidoctor/cleanup_spec.rb +1860 -1874
- data/spec/asciidoctor/inline_spec.rb +272 -273
- data/spec/asciidoctor/macros_spec.rb +8 -2
- data/spec/asciidoctor/refs_spec.rb +135 -7
- data/spec/asciidoctor/section_spec.rb +670 -687
- data/spec/assets/html-override.css +1 -0
- data/spec/assets/word-override.css +1 -0
- data/spec/spec_helper.rb +11 -9
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +60 -60
- data/spec/vcr_cassettes/isobib_get_123.yml +16 -16
- data/spec/vcr_cassettes/isobib_get_123_1.yml +32 -32
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +41 -41
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +15 -15
- data/spec/vcr_cassettes/isobib_get_124.yml +17 -17
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +53 -49
- metadata +71 -68
- data/.rubocop.ribose.yml +0 -66
- data/.rubocop.tb.yml +0 -650
- 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 &&
|
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(
|
84
|
-
formula_cleanup_where1(
|
85
|
-
formula_cleanup_where2(
|
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(
|
89
|
+
def formula_cleanup_where1(formula)
|
89
90
|
q = "//formula/following-sibling::*[1][self::dl]"
|
90
|
-
|
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(
|
96
|
+
def formula_cleanup_where2(formula)
|
96
97
|
q = "//formula/following-sibling::*[1][self::p]"
|
97
|
-
|
98
|
-
if s.text =~ /^\s*where[^a-z]*$/i &&
|
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 &&
|
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
|
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,
|
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]
|
154
|
-
|
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
|
158
|
-
|
159
|
-
|
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
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
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
|
173
|
-
|
174
|
-
|
175
|
-
|
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
|
187
|
-
|
188
|
-
|
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
|
195
|
-
|
196
|
-
|
197
|
-
|
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
|
-
|
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
|
214
|
-
|
215
|
-
|
216
|
-
|
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
|
-
|
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 || "???"),
|
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 || "??"),
|
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,
|
22
|
+
@log.add("Crossreferences", nil,
|
23
|
+
"term source #{s['bibitemid']} not referenced")
|
19
24
|
end
|
20
|
-
a =
|
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(
|
37
|
-
refs =
|
38
|
-
|
41
|
+
def norm_ref_preface(ref)
|
42
|
+
refs = ref.elements.select do |e|
|
43
|
+
%w(references bibitem).include? e.name
|
39
44
|
end
|
40
|
-
|
41
|
-
|
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 |
|
49
|
+
TERM_CLAUSE = "//sections/terms | "\
|
50
|
+
"//sections/clause[descendant::terms]".freeze
|
45
51
|
|
46
|
-
NORM_REF = "//bibliography/references[@normative = 'true']"
|
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(
|
88
|
-
return if
|
89
|
-
|
90
|
-
|
91
|
-
|
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(
|
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(
|
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
|
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}']")
|
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
|
@@ -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
|
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
|
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
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
35
|
-
|
35
|
+
|
36
|
+
math = x.text.gsub(/</, "<").gsub(/>/, ">")
|
37
|
+
.gsub(/"/, '"').gsub(/'/, "'").gsub(/&/, "&")
|
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
|
46
|
+
x.children = x.children.to_xml
|
47
|
+
.gsub(/^\s/, " ").gsub(/\s$/, " ")
|
44
48
|
end
|
45
49
|
end
|
46
50
|
|
47
51
|
def mathml_namespace(stem)
|
48
|
-
stem.xpath("./math"
|
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])]",
|
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
|
-
|
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 = "
|
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)
|
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.
|
112
|
+
tags.each_value { |v| set << v }
|
104
113
|
end
|
105
114
|
|
106
115
|
def asciimath2unitsml_options
|