metanorma-standoc 2.9.5 → 2.9.7
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/lib/isodoc/html/htmlstyle.css +4 -1
- data/lib/metanorma/standoc/base.rb +8 -8
- data/lib/metanorma/standoc/basicdoc.rng +909 -464
- data/lib/metanorma/standoc/biblio-standoc.rng +87 -20
- data/lib/metanorma/standoc/biblio.rng +884 -325
- data/lib/metanorma/standoc/blocks.rb +1 -1
- data/lib/metanorma/standoc/cleanup.rb +4 -2
- data/lib/metanorma/standoc/cleanup_bibitem.rb +18 -6
- data/lib/metanorma/standoc/cleanup_boilerplate.rb +9 -93
- data/lib/metanorma/standoc/cleanup_inline.rb +1 -1
- data/lib/metanorma/standoc/cleanup_maths.rb +51 -101
- data/lib/metanorma/standoc/cleanup_mathvariant.rb +88 -0
- data/lib/metanorma/standoc/cleanup_terms.rb +4 -1
- data/lib/metanorma/standoc/cleanup_terms_boilerplate.rb +106 -0
- data/lib/metanorma/standoc/cleanup_terms_designations.rb +1 -2
- data/lib/metanorma/standoc/cleanup_text.rb +11 -4
- data/lib/metanorma/standoc/cleanup_xref.rb +1 -1
- data/lib/metanorma/standoc/converter.rb +2 -0
- data/lib/metanorma/standoc/datamodel/plantuml_renderer.rb +1 -1
- data/lib/metanorma/standoc/init.rb +23 -4
- data/lib/metanorma/standoc/inline.rb +27 -14
- data/lib/metanorma/standoc/isodoc.rng +1031 -912
- data/lib/metanorma/standoc/localbib.rb +1 -1
- data/lib/metanorma/standoc/macros.rb +1 -1
- data/lib/metanorma/standoc/macros_inline.rb +11 -9
- data/lib/metanorma/standoc/macros_plantuml.rb +1 -1
- data/lib/metanorma/standoc/ref.rb +1 -1
- data/lib/metanorma/standoc/ref_queue.rb +1 -1
- data/lib/metanorma/standoc/ref_utility.rb +7 -6
- data/lib/metanorma/standoc/reqt.rng +94 -72
- data/lib/metanorma/standoc/section.rb +2 -2
- data/lib/metanorma/standoc/term_lookup_cleanup.rb +2 -2
- data/lib/metanorma/standoc/utils.rb +4 -2
- data/lib/metanorma/standoc/version.rb +1 -1
- metadata +4 -2
@@ -54,6 +54,7 @@ module Metanorma
|
|
54
54
|
normref_cleanup(xmldoc)
|
55
55
|
biblio_cleanup(xmldoc)
|
56
56
|
reference_names(xmldoc)
|
57
|
+
terms_terms_cleanup(xmldoc) # feeds: boilerplate_cleanup
|
57
58
|
asciimath_cleanup(xmldoc) # feeds: mathml_cleanup, termdef_cleanup,
|
58
59
|
# symbols_cleanup
|
59
60
|
symbols_cleanup(xmldoc) # feeds: termdef_cleanup
|
@@ -77,9 +78,10 @@ module Metanorma
|
|
77
78
|
docidentifier_cleanup(xmldoc) # feeds: bibdata_cleanup
|
78
79
|
ext_contributor_cleanup(xmldoc) # feeds: bibdata_cleanup
|
79
80
|
ext_dochistory_cleanup(xmldoc) # feeds: bibdata_cleanup
|
80
|
-
bibdata_cleanup(xmldoc)
|
81
|
+
bibdata_cleanup(xmldoc) # feeds: boilerplate_cleanup
|
82
|
+
boilerplate_cleanup(xmldoc) # feeds: xref_cleanup for new <<>> introduced
|
83
|
+
xref_cleanup(xmldoc)
|
81
84
|
svgmap_cleanup(xmldoc) # feeds: img_cleanup
|
82
|
-
boilerplate_cleanup(xmldoc)
|
83
85
|
toc_cleanup(xmldoc)
|
84
86
|
smartquotes_cleanup(xmldoc)
|
85
87
|
linebreak_cleanup(xmldoc)
|
@@ -142,34 +142,46 @@ module Metanorma
|
|
142
142
|
u = b.at("./uri[@type = 'attachment']")
|
143
143
|
c = b.at("./uri[@type = 'citation']") ||
|
144
144
|
u.after("<uri type='citation'/>")
|
145
|
-
uri =
|
145
|
+
uri = attachment_uri(u.text, b)
|
146
146
|
u.children = uri
|
147
147
|
c.children = uri
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
151
|
-
def
|
151
|
+
def attachment_uri(path, bib)
|
152
152
|
init_attachments
|
153
153
|
path = File.join(@localdir, path)
|
154
154
|
valid_attachment?(path, bib) or return ""
|
155
|
+
@datauriattachment or return attachment_location(path)
|
156
|
+
save_attachment(path, bib)
|
157
|
+
end
|
158
|
+
|
159
|
+
def save_attachment(path, bib)
|
160
|
+
init_attachments
|
155
161
|
f = File.basename(path)
|
156
162
|
File.exist?(File.join(@attachmentsdir, f)) and
|
157
163
|
f += "_#{UUIDTools::UUID.random_create}"
|
158
164
|
out_fld = File.join(@attachmentsdir, f)
|
159
165
|
FileUtils.cp(path, out_fld)
|
160
166
|
datauri_attachment(out_fld, bib.document)
|
161
|
-
|
167
|
+
end
|
168
|
+
|
169
|
+
def attachment_location(path)
|
170
|
+
f = path
|
171
|
+
@datauriattachment and
|
172
|
+
f = File.join(@attachmentsdir, File.basename(path))
|
173
|
+
Pathname.new(File.expand_path(f))
|
174
|
+
.relative_path_from(Pathname.new(File.expand_path(@localdir))).to_s
|
162
175
|
end
|
163
176
|
|
164
177
|
def datauri_attachment(path, doc)
|
165
178
|
@datauriattachment or return
|
166
179
|
m = add_misc_container(doc)
|
167
|
-
f =
|
168
|
-
f = Pathname.new(File.expand_path(f))
|
169
|
-
.relative_path_from(Pathname.new(File.expand_path(@localdir)))
|
180
|
+
f = attachment_location(path)
|
170
181
|
e = (m << "<attachment name='#{f}'/>").last_element_child
|
171
182
|
Vectory::Utils::datauri(path, @localdir).scan(/.{1,60}/)
|
172
183
|
.each { |dd| e << "#{dd}\n" }
|
184
|
+
f
|
173
185
|
end
|
174
186
|
|
175
187
|
def valid_attachment?(path, bib)
|
@@ -1,41 +1,8 @@
|
|
1
|
+
require_relative "cleanup_terms_boilerplate"
|
2
|
+
|
1
3
|
module Metanorma
|
2
4
|
module Standoc
|
3
5
|
module Cleanup
|
4
|
-
def external_terms_boilerplate(sources)
|
5
|
-
e = @i18n.external_terms_boilerplate
|
6
|
-
@i18n.l10n(e.gsub(/%(?=\p{P}|\p{Z}|$)/, sources || "???"),
|
7
|
-
@lang, @script, @locale)
|
8
|
-
end
|
9
|
-
|
10
|
-
def internal_external_terms_boilerplate(sources)
|
11
|
-
e = @i18n.internal_external_terms_boilerplate
|
12
|
-
@i18n.l10n(e.gsub(/%(?=\p{P}|\p{Z}|$)/, sources || "??"),
|
13
|
-
@lang, @script)
|
14
|
-
end
|
15
|
-
|
16
|
-
def term_defs_boilerplate(div, source, term, _preface, isodoc)
|
17
|
-
a = @i18n.term_def_boilerplate and div.next = a
|
18
|
-
source.each do |s|
|
19
|
-
@anchors[s["bibitemid"]] or
|
20
|
-
@log.add("Crossreferences", nil,
|
21
|
-
"term source #{s['bibitemid']} not referenced", severity: 1)
|
22
|
-
end
|
23
|
-
a = if source.empty? && term.nil? then @i18n.no_terms_boilerplate
|
24
|
-
else term_defs_boilerplate_cont(source, term, isodoc)
|
25
|
-
end and div.next = a
|
26
|
-
end
|
27
|
-
|
28
|
-
def term_defs_boilerplate_cont(src, term, isodoc)
|
29
|
-
sources = isodoc.sentence_join(src.map do |s|
|
30
|
-
%{<eref bibitemid="#{s['bibitemid']}"/>}
|
31
|
-
end)
|
32
|
-
if src.empty? then @i18n.internal_terms_boilerplate
|
33
|
-
elsif term.nil? then external_terms_boilerplate(sources)
|
34
|
-
else
|
35
|
-
internal_external_terms_boilerplate(sources)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
6
|
def norm_ref_preface(ref)
|
40
7
|
ins = norm_ref_boilerplate_insert_location(ref)
|
41
8
|
ins2 = norm_ref_process_boilerplate_note(ref)
|
@@ -45,7 +12,7 @@ module Metanorma
|
|
45
12
|
%w(references bibitem).include? e.name
|
46
13
|
end
|
47
14
|
pref = refs.empty? ? @i18n.norm_empty_pref : @i18n.norm_with_refs_pref
|
48
|
-
ins.next =
|
15
|
+
ins.next = boilerplate_snippet_convert(pref)
|
49
16
|
end
|
50
17
|
|
51
18
|
def norm_ref_process_boilerplate_note(ref)
|
@@ -69,16 +36,15 @@ module Metanorma
|
|
69
36
|
ref.at("./title")
|
70
37
|
end
|
71
38
|
|
72
|
-
TERM_CLAUSE =
|
73
|
-
"//sections//terms[not(.//ancestor::clause[@type = 'terms'])] | " \
|
74
|
-
"//sections/clause[descendant::terms][@type = 'terms'] | " \
|
75
|
-
"//sections/clause[not(@type = 'terms')]//terms".freeze
|
76
|
-
|
77
39
|
NORM_REF =
|
78
40
|
"//bibliography/references[@normative = 'true'][not(@hidden)] | " \
|
79
41
|
"//bibliography/clause[.//references[@normative = 'true']]".freeze
|
80
42
|
|
81
43
|
def boilerplate_isodoc(xmldoc)
|
44
|
+
# prevent infinite recursion of asciidoc boilerplate processing
|
45
|
+
# in termdef_boilerplate_insert and initial_boilerplate
|
46
|
+
xmldoc.at("//metanorma-extension/semantic-metadata/" \
|
47
|
+
"headless[text() = 'true']") and return nil
|
82
48
|
x = xmldoc.dup
|
83
49
|
x.root.add_namespace(nil, self.class::XML_NAMESPACE)
|
84
50
|
xml = Nokogiri::XML(x.to_xml)
|
@@ -87,14 +53,6 @@ module Metanorma
|
|
87
53
|
@isodoc
|
88
54
|
end
|
89
55
|
|
90
|
-
def termdef_boilerplate_cleanup(xmldoc)
|
91
|
-
# termdef_remove_initial_paras(xmldoc)
|
92
|
-
end
|
93
|
-
|
94
|
-
def termdef_remove_initial_paras(xmldoc)
|
95
|
-
xmldoc.xpath("//terms/p | //terms/ul").each(&:remove)
|
96
|
-
end
|
97
|
-
|
98
56
|
def unwrap_boilerplate_clauses(xmldoc, xpath)
|
99
57
|
xmldoc.xpath(xpath).each do |f|
|
100
58
|
f.xpath(".//clause[@type = 'boilerplate'] | " \
|
@@ -105,51 +63,8 @@ module Metanorma
|
|
105
63
|
end
|
106
64
|
end
|
107
65
|
|
108
|
-
def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
|
109
|
-
if once
|
110
|
-
f = termdef_boilerplate_insert_location(xmldoc) and
|
111
|
-
termdef_boilerplate_insert1(f, xmldoc, isodoc)
|
112
|
-
else
|
113
|
-
xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
|
114
|
-
termdef_boilerplate_insert1(f, xmldoc, isodoc)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def termdef_boilerplate_insert_location(xmldoc)
|
120
|
-
f = xmldoc.at(self.class::TERM_CLAUSE)
|
121
|
-
root = xmldoc.at("//sections/terms | //sections/clause[@type = 'terms']")
|
122
|
-
if f && root && f["id"] != root["id"]
|
123
|
-
f = termdef_boilerplate_climb_up(f, root)
|
124
|
-
elsif !f && root then f = root
|
125
|
-
end
|
126
|
-
f
|
127
|
-
end
|
128
|
-
|
129
|
-
def termdef_boilerplate_climb_up(clause, container)
|
130
|
-
container.at(".//*[@id = '#{clause['id']}']") or return clause
|
131
|
-
while (n = clause.parent)
|
132
|
-
n.at(".//definitions") and break
|
133
|
-
clause = n
|
134
|
-
n["id"] == container["id"] and break
|
135
|
-
end
|
136
|
-
clause
|
137
|
-
end
|
138
|
-
|
139
|
-
def termdef_boilerplate_insert1(sect, xmldoc, isodoc)
|
140
|
-
ins = sect.at("./title")
|
141
|
-
if (ins2 = sect.at("./clause[@type = 'boilerplate'] | " \
|
142
|
-
"./note[@type = 'boilerplate']"))
|
143
|
-
ins2.text.strip.downcase == "(default)" or return
|
144
|
-
ins2.children = " "
|
145
|
-
ins = ins2.children.first
|
146
|
-
end
|
147
|
-
term_defs_boilerplate(ins, xmldoc.xpath(".//termdocsource"),
|
148
|
-
sect.at(".//term"), sect.at(".//p"), isodoc)
|
149
|
-
end
|
150
|
-
|
151
66
|
def boilerplate_cleanup(xmldoc)
|
152
|
-
isodoc = boilerplate_isodoc(xmldoc)
|
67
|
+
isodoc = boilerplate_isodoc(xmldoc) or return
|
153
68
|
termdef_boilerplate_cleanup(xmldoc)
|
154
69
|
termdef_boilerplate_insert(xmldoc, isodoc)
|
155
70
|
unwrap_boilerplate_clauses(xmldoc, self.class::TERM_CLAUSE)
|
@@ -245,6 +160,7 @@ module Metanorma
|
|
245
160
|
/^_\d+$/.match?(n["id"]) and
|
246
161
|
n["id"] = "_#{UUIDTools::UUID.random_create}"
|
247
162
|
end
|
163
|
+
xml
|
248
164
|
end
|
249
165
|
|
250
166
|
def boilerplate_top_elements(xml)
|
@@ -99,7 +99,7 @@ module Metanorma
|
|
99
99
|
def key_extract_locality(elem)
|
100
100
|
elem["key"].include?(",") or return
|
101
101
|
elem.add_child("<locality>#{elem['key'].sub(/^[^,]+,/, '')}</locality>")
|
102
|
-
elem["key"] = elem["key"].sub(
|
102
|
+
elem["key"] = elem["key"].sub(/(^[^,]+),.*$/, "\\1")
|
103
103
|
end
|
104
104
|
|
105
105
|
def concept_termbase_cleanup(elem)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "asciimath2unitsml"
|
2
|
+
require_relative "cleanup_mathvariant"
|
2
3
|
|
3
4
|
module Metanorma
|
4
5
|
module Standoc
|
@@ -19,7 +20,7 @@ module Metanorma
|
|
19
20
|
def asciimath2mathml_indiv(elem)
|
20
21
|
elem["type"] = "MathML"
|
21
22
|
expr = @c.decode(elem.text)
|
22
|
-
ret = asciimath_parse(expr, elem)
|
23
|
+
ret = asciimath_parse(expr, elem)&.strip
|
23
24
|
ret += "<asciimath>#{@c.encode(expr, :basic)}</asciimath>"
|
24
25
|
elem.children = ret
|
25
26
|
rescue StandardError => e
|
@@ -58,15 +59,19 @@ module Metanorma
|
|
58
59
|
xml
|
59
60
|
end
|
60
61
|
|
61
|
-
def
|
62
|
-
|
62
|
+
def mathml_xml_cleanup(stem)
|
63
|
+
xml_unescape_mathml(stem)
|
64
|
+
mathml_namespace(stem)
|
65
|
+
mathml_preserve_space(stem)
|
66
|
+
end
|
63
67
|
|
68
|
+
def progress_conv(idx, step, total, threshold, msg)
|
69
|
+
(idx % step).zero? && total > threshold && idx.positive? or return
|
64
70
|
warn "#{msg} #{idx} of #{total}"
|
65
71
|
end
|
66
72
|
|
67
73
|
def xml_unescape_mathml(xml)
|
68
|
-
|
69
|
-
|
74
|
+
xml.children.any?(&:element?) and return
|
70
75
|
math = xml.text.gsub("<", "<").gsub(">", ">")
|
71
76
|
.gsub(""", '"').gsub("'", "'").gsub("&", "&")
|
72
77
|
.gsub(/<[^: \r\n\t\/]+:/, "<").gsub(/<\/[^ \r\n\t:]+:/, "</")
|
@@ -86,33 +91,6 @@ module Metanorma
|
|
86
91
|
end
|
87
92
|
end
|
88
93
|
|
89
|
-
def mathml_mi_italics
|
90
|
-
{ uppergreek: true, upperroman: true,
|
91
|
-
lowergreek: true, lowerroman: true }
|
92
|
-
end
|
93
|
-
|
94
|
-
# presuppose multichar mi upright, singlechar mi MathML default italic
|
95
|
-
def mathml_italicise(xml)
|
96
|
-
xml.xpath(".//m:mi[not(ancestor::*[@mathvariant])]",
|
97
|
-
"m" => MATHML_NS).each do |i|
|
98
|
-
char = @c.decode(i.text)
|
99
|
-
i["mathvariant"] = "normal" if mi_italicise?(char)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def mi_italicise?(char)
|
104
|
-
char.length > 1 and return false
|
105
|
-
case char
|
106
|
-
when /\p{Greek}/
|
107
|
-
(/\p{Lower}/.match(char) && !mathml_mi_italics[:lowergreek]) ||
|
108
|
-
(/\p{Upper}/.match(char) && !mathml_mi_italics[:uppergreek])
|
109
|
-
when /\p{Latin}/
|
110
|
-
(/\p{Lower}/.match(char) && !mathml_mi_italics[:lowerroman]) ||
|
111
|
-
(/\p{Upper}/.match(char) && !mathml_mi_italics[:upperroman])
|
112
|
-
else false
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
94
|
UNITSML_NS = "https://schema.unitsml.org/unitsml/1.0".freeze
|
117
95
|
|
118
96
|
def add_misc_container(xmldoc)
|
@@ -124,9 +102,8 @@ module Metanorma
|
|
124
102
|
ins
|
125
103
|
end
|
126
104
|
|
127
|
-
def
|
128
|
-
|
129
|
-
|
105
|
+
def mathml_unitsml(xmldoc)
|
106
|
+
xmldoc.at(".//m:*", "m" => UNITSML_NS) or return
|
130
107
|
misc = add_misc_container(xmldoc)
|
131
108
|
unitsml = misc.add_child("<UnitsML xmlns='#{UNITSML_NS}'/>").first
|
132
109
|
%w(Unit CountedItem Quantity Dimension Prefix).each do |t|
|
@@ -139,8 +116,7 @@ module Metanorma
|
|
139
116
|
.each_with_object({}) do |x, m|
|
140
117
|
m[x["xml:id"]] = x.remove
|
141
118
|
end
|
142
|
-
|
143
|
-
|
119
|
+
tags.empty? and return
|
144
120
|
set = unitsml.add_child("<#{tag}Set/>").first
|
145
121
|
tags.each_value { |v| set << v }
|
146
122
|
end
|
@@ -149,67 +125,13 @@ module Metanorma
|
|
149
125
|
{ multiplier: :space }
|
150
126
|
end
|
151
127
|
|
152
|
-
MATHVARIANT_OVERRIDE = {
|
153
|
-
bold: { normal: "bold", italic: "bold-italic", fraktur: "bold-fraktur",
|
154
|
-
script: "bold-script", "sans-serif": "bold-sans-serif",
|
155
|
-
"sans-serif-italic": "sans-serif-bold-italic" },
|
156
|
-
italic: { normal: "italic", bod: "bold-italic",
|
157
|
-
"sans-serif": "sans-serif-italic",
|
158
|
-
"bold-sans-serif": "sans-serif-bold-italic" },
|
159
|
-
"bold-italic": { normal: "bold-italic", bold: "bold-italic",
|
160
|
-
italic: "bold-italic",
|
161
|
-
"sans-serif": "sans-serif-bold-italic",
|
162
|
-
"bold-sans-serif": "sans-serif-bold-italic",
|
163
|
-
"sans-serif-italic": "sans-serif-bold-italic" },
|
164
|
-
fraktur: { normal: "fraktur", bold: "bold-fraktur" },
|
165
|
-
"bold-fraktur": { normal: "bold-fraktur", fraktur: "bold-fraktur" },
|
166
|
-
script: { normal: "script", bold: "bold-script" },
|
167
|
-
"bold-script": { normal: "script", script: "bold-script" },
|
168
|
-
"sans-serif": { normal: "sans-serif", bold: "bold-sans-serif",
|
169
|
-
italic: "sans-serif-italic",
|
170
|
-
"bold-italic": "sans-serif-bold-italic" },
|
171
|
-
"bold-sans-serif": { normal: "bold-sans-serif", bold: "bold-sans-serif",
|
172
|
-
"sans-serif": "bold-sans-serif",
|
173
|
-
italic: "sans-serif-bold-italic",
|
174
|
-
"bold-italic": "sans-serif-bold-italic",
|
175
|
-
"sans-serif-italic": "sans-serif-bold-italic" },
|
176
|
-
"sans-serif-italic": { normal: "sans-serif-italic",
|
177
|
-
italic: "sans-serif-italic",
|
178
|
-
"sans-serif": "sans-serif-italic",
|
179
|
-
bold: "sans-serif-bold-italic",
|
180
|
-
"bold-italic": "sans-serif-bold-italic",
|
181
|
-
"sans-serif-bold": "sans-serif-bold-italic" },
|
182
|
-
"sans-serif-bold-italic": { normal: "sans-serif-bold-italic",
|
183
|
-
italic: "sans-serif-bold-italic",
|
184
|
-
"sans-serif": "sans-serif-bold-italic",
|
185
|
-
"sans-serif-italic": "sans-serif-bold-italic",
|
186
|
-
bold: "sans-serif-bold-italic",
|
187
|
-
"bold-italic": "sans-serif-bold-italic",
|
188
|
-
"sans-serif-bold": "sans-serif-bold-italic" },
|
189
|
-
}.freeze
|
190
|
-
|
191
|
-
def mathvariant_override(inner, outer)
|
192
|
-
o = outer.to_sym
|
193
|
-
i = inner.to_sym
|
194
|
-
MATHVARIANT_OVERRIDE[o] or return inner
|
195
|
-
MATHVARIANT_OVERRIDE[o][i] || inner
|
196
|
-
end
|
197
|
-
|
198
|
-
def mathml_mathvariant(math)
|
199
|
-
math.xpath(".//*[@mathvariant]").each do |outer|
|
200
|
-
outer.xpath(".//*[@mathvariant]").each do |inner|
|
201
|
-
inner["mathvariant"] =
|
202
|
-
mathvariant_override(inner["mathvariant"], outer["mathvariant"])
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
128
|
def mathml_mn_format(math)
|
129
|
+
math["number-format"] or return
|
208
130
|
math.xpath(".//m:mn", "m" => MATHML_NS).each do |m|
|
209
131
|
profile = mathml_mn_profile(m)
|
210
132
|
attr = profile.each_with_object([]) do |(k, v), acc|
|
211
133
|
v == "nil" and next
|
212
|
-
acc << "#{k}='#{v}'"
|
134
|
+
acc << "#{k}='#{@c.decode v}'"
|
213
135
|
end.join(",")
|
214
136
|
attr.empty? or m["data-metanorma-numberformat"] = attr
|
215
137
|
end
|
@@ -226,19 +148,47 @@ module Metanorma
|
|
226
148
|
fmt.merge(fmt1).merge(fmt2)
|
227
149
|
end
|
228
150
|
|
151
|
+
def mathml_stem_format(stem)
|
152
|
+
f = mathml_stem_format_attr(stem) or return
|
153
|
+
attr = quoted_csv_split(f, ",").map do |x|
|
154
|
+
m = /^(.+?)=(.+)?$/.match(x) or next
|
155
|
+
"#{m[1]}='#{@c.decode m[2]}'"
|
156
|
+
end.join(",")
|
157
|
+
stem.xpath(".//m:mn", "m" => MATHML_NS).each do |m|
|
158
|
+
attr.empty? or m["data-metanorma-numberformat"] = attr
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def mathml_stem_format_attr(stem)
|
163
|
+
f = stem["number-format"] || @numberfmt_formula or return
|
164
|
+
if f == "nil"
|
165
|
+
stem.delete("number-format")
|
166
|
+
return
|
167
|
+
end
|
168
|
+
f == "default" or return f
|
169
|
+
if @numberfmt_default.empty?
|
170
|
+
"notation='basic'"
|
171
|
+
else @numberfmt_default&.map { |k, v| "#{k}='#{v}'" }&.join(",")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def mathml_number_format(stem)
|
176
|
+
mathml_stem_format(stem)
|
177
|
+
mathml_mn_format(stem)
|
178
|
+
stem.delete("number-format")
|
179
|
+
end
|
180
|
+
|
229
181
|
def mathml_cleanup(xmldoc)
|
230
|
-
|
182
|
+
a2u = Asciimath2UnitsML::Conv.new(asciimath2unitsml_options)
|
231
183
|
xmldoc.xpath("//stem[@type = 'MathML'][not(@validate = 'false')]")
|
232
184
|
.each do |x|
|
233
|
-
|
234
|
-
|
235
|
-
mathml_preserve_space(x)
|
236
|
-
unitsml.MathML2UnitsML(x)
|
185
|
+
mathml_xml_cleanup(x)
|
186
|
+
a2u.MathML2UnitsML(x)
|
237
187
|
mathml_mathvariant(x)
|
238
|
-
mathml_italicise(x)
|
239
|
-
mathml_mn_format(x)
|
240
188
|
end
|
241
|
-
|
189
|
+
xmldoc.xpath("//stem[@type = 'MathML']")
|
190
|
+
.each { |x| mathml_number_format(x) }
|
191
|
+
mathml_unitsml(xmldoc)
|
242
192
|
end
|
243
193
|
end
|
244
194
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Standoc
|
3
|
+
module Cleanup
|
4
|
+
def mathml_mi_italics
|
5
|
+
{ uppergreek: true, upperroman: true,
|
6
|
+
lowergreek: true, lowerroman: true }
|
7
|
+
end
|
8
|
+
|
9
|
+
# presuppose multichar mi upright, singlechar mi MathML default italic
|
10
|
+
def mathml_italicise(xml)
|
11
|
+
xml.xpath(".//m:mi[not(ancestor::*[@mathvariant])]",
|
12
|
+
"m" => MATHML_NS).each do |i|
|
13
|
+
char = @c.decode(i.text)
|
14
|
+
i["mathvariant"] = "normal" if mi_italicise?(char)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def mi_italicise?(char)
|
19
|
+
char.length > 1 and return false
|
20
|
+
case char
|
21
|
+
when /\p{Greek}/
|
22
|
+
(/\p{Lower}/.match(char) && !mathml_mi_italics[:lowergreek]) ||
|
23
|
+
(/\p{Upper}/.match(char) && !mathml_mi_italics[:uppergreek])
|
24
|
+
when /\p{Latin}/
|
25
|
+
(/\p{Lower}/.match(char) && !mathml_mi_italics[:lowerroman]) ||
|
26
|
+
(/\p{Upper}/.match(char) && !mathml_mi_italics[:upperroman])
|
27
|
+
else false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
MATHVARIANT_OVERRIDE = {
|
32
|
+
bold: { normal: "bold", italic: "bold-italic", fraktur: "bold-fraktur",
|
33
|
+
script: "bold-script", "sans-serif": "bold-sans-serif",
|
34
|
+
"sans-serif-italic": "sans-serif-bold-italic" },
|
35
|
+
italic: { normal: "italic", bod: "bold-italic",
|
36
|
+
"sans-serif": "sans-serif-italic",
|
37
|
+
"bold-sans-serif": "sans-serif-bold-italic" },
|
38
|
+
"bold-italic": { normal: "bold-italic", bold: "bold-italic",
|
39
|
+
italic: "bold-italic",
|
40
|
+
"sans-serif": "sans-serif-bold-italic",
|
41
|
+
"bold-sans-serif": "sans-serif-bold-italic",
|
42
|
+
"sans-serif-italic": "sans-serif-bold-italic" },
|
43
|
+
fraktur: { normal: "fraktur", bold: "bold-fraktur" },
|
44
|
+
"bold-fraktur": { normal: "bold-fraktur", fraktur: "bold-fraktur" },
|
45
|
+
script: { normal: "script", bold: "bold-script" },
|
46
|
+
"bold-script": { normal: "script", script: "bold-script" },
|
47
|
+
"sans-serif": { normal: "sans-serif", bold: "bold-sans-serif",
|
48
|
+
italic: "sans-serif-italic",
|
49
|
+
"bold-italic": "sans-serif-bold-italic" },
|
50
|
+
"bold-sans-serif": { normal: "bold-sans-serif", bold: "bold-sans-serif",
|
51
|
+
"sans-serif": "bold-sans-serif",
|
52
|
+
italic: "sans-serif-bold-italic",
|
53
|
+
"bold-italic": "sans-serif-bold-italic",
|
54
|
+
"sans-serif-italic": "sans-serif-bold-italic" },
|
55
|
+
"sans-serif-italic": { normal: "sans-serif-italic",
|
56
|
+
italic: "sans-serif-italic",
|
57
|
+
"sans-serif": "sans-serif-italic",
|
58
|
+
bold: "sans-serif-bold-italic",
|
59
|
+
"bold-italic": "sans-serif-bold-italic",
|
60
|
+
"sans-serif-bold": "sans-serif-bold-italic" },
|
61
|
+
"sans-serif-bold-italic": { normal: "sans-serif-bold-italic",
|
62
|
+
italic: "sans-serif-bold-italic",
|
63
|
+
"sans-serif": "sans-serif-bold-italic",
|
64
|
+
"sans-serif-italic": "sans-serif-bold-italic",
|
65
|
+
bold: "sans-serif-bold-italic",
|
66
|
+
"bold-italic": "sans-serif-bold-italic",
|
67
|
+
"sans-serif-bold": "sans-serif-bold-italic" },
|
68
|
+
}.freeze
|
69
|
+
|
70
|
+
def mathvariant_override(inner, outer)
|
71
|
+
o = outer.to_sym
|
72
|
+
i = inner.to_sym
|
73
|
+
MATHVARIANT_OVERRIDE[o] or return inner
|
74
|
+
MATHVARIANT_OVERRIDE[o][i] || inner
|
75
|
+
end
|
76
|
+
|
77
|
+
def mathml_mathvariant(math)
|
78
|
+
math.xpath(".//*[@mathvariant]").each do |outer|
|
79
|
+
outer.xpath(".//*[@mathvariant]").each do |inner|
|
80
|
+
inner["mathvariant"] =
|
81
|
+
mathvariant_override(inner["mathvariant"], outer["mathvariant"])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
mathml_italicise(math)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -73,11 +73,14 @@ module Metanorma
|
|
73
73
|
xmldoc.xpath("//termdocsource").each { |s| f.previous = s.remove }
|
74
74
|
end
|
75
75
|
|
76
|
-
def
|
76
|
+
def terms_terms_cleanup(xmldoc)
|
77
77
|
xmldoc.xpath("//terms[terms][not(term)]").each do |t|
|
78
78
|
t.name = "clause"
|
79
79
|
t["type"] = "terms"
|
80
80
|
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def term_children_cleanup(xmldoc)
|
81
84
|
xmldoc.xpath("//term").each do |t|
|
82
85
|
%w(termnote termexample termsource term).each do |w|
|
83
86
|
t.xpath("./#{w}").each { |n| t << n.remove }
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Standoc
|
3
|
+
module Cleanup
|
4
|
+
def external_terms_boilerplate(sources)
|
5
|
+
e = @i18n.external_terms_boilerplate
|
6
|
+
e.gsub(/%(?=\p{P}|\p{Z}|$)/, sources || "???")
|
7
|
+
end
|
8
|
+
|
9
|
+
def internal_external_terms_boilerplate(sources)
|
10
|
+
e = @i18n.internal_external_terms_boilerplate
|
11
|
+
e.gsub(/%(?=\p{P}|\p{Z}|$)/, sources || "??")
|
12
|
+
end
|
13
|
+
|
14
|
+
def boilerplate_snippet_convert(adoc)
|
15
|
+
ret = boilerplate_xml_cleanup(adoc2xml(adoc, backend.to_sym))
|
16
|
+
@i18n.l10n(ret.children.to_xml, @lang, @script)
|
17
|
+
end
|
18
|
+
|
19
|
+
def term_defs_boilerplate(div, source, term, _preface, isodoc)
|
20
|
+
verify_term_defs_source(source)
|
21
|
+
a = @i18n.term_def_boilerplate and
|
22
|
+
div.next = boilerplate_snippet_convert(a)
|
23
|
+
a = if source.empty? && term.nil? then @i18n.no_terms_boilerplate
|
24
|
+
else term_defs_boilerplate_cont(source, term, isodoc)
|
25
|
+
end
|
26
|
+
a and div.next = boilerplate_snippet_convert(a)
|
27
|
+
end
|
28
|
+
|
29
|
+
def verify_term_defs_source(source)
|
30
|
+
source.each do |s|
|
31
|
+
@anchors[s["bibitemid"]] or
|
32
|
+
@log.add("Crossreferences", nil,
|
33
|
+
"term source #{s['bibitemid']} not referenced",
|
34
|
+
severity: 1)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def term_defs_boilerplate_cont(src, term, isodoc)
|
39
|
+
sources = isodoc.sentence_join(src.map do |s|
|
40
|
+
%{<<#{s['bibitemid']}>>}
|
41
|
+
end)
|
42
|
+
if src.empty? then @i18n.internal_terms_boilerplate
|
43
|
+
elsif term.nil? then external_terms_boilerplate(sources)
|
44
|
+
else
|
45
|
+
internal_external_terms_boilerplate(sources)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
TERM_CLAUSE =
|
50
|
+
"//sections//terms[not(.//ancestor::clause[@type = 'terms'])] | " \
|
51
|
+
"//sections/clause[descendant::terms][@type = 'terms'] | " \
|
52
|
+
"//sections/clause[not(@type = 'terms')]//terms".freeze
|
53
|
+
|
54
|
+
def termdef_boilerplate_cleanup(xmldoc)
|
55
|
+
# termdef_remove_initial_paras(xmldoc)
|
56
|
+
end
|
57
|
+
|
58
|
+
def termdef_remove_initial_paras(xmldoc)
|
59
|
+
xmldoc.xpath("//terms/p | //terms/ul").each(&:remove)
|
60
|
+
end
|
61
|
+
|
62
|
+
def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
|
63
|
+
if once
|
64
|
+
f = termdef_boilerplate_insert_location(xmldoc) and
|
65
|
+
termdef_boilerplate_insert1(f, xmldoc, isodoc)
|
66
|
+
else
|
67
|
+
xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
|
68
|
+
termdef_boilerplate_insert1(f, xmldoc, isodoc)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def termdef_boilerplate_insert_location(xmldoc)
|
74
|
+
f = xmldoc.at(self.class::TERM_CLAUSE)
|
75
|
+
root = xmldoc.at("//sections/terms | //sections/clause[@type = 'terms']")
|
76
|
+
if f && root && f["id"] != root["id"]
|
77
|
+
f = termdef_boilerplate_climb_up(f, root)
|
78
|
+
elsif !f && root then f = root
|
79
|
+
end
|
80
|
+
f
|
81
|
+
end
|
82
|
+
|
83
|
+
def termdef_boilerplate_climb_up(clause, container)
|
84
|
+
container.at(".//*[@id = '#{clause['id']}']") or return clause
|
85
|
+
while (n = clause.parent)
|
86
|
+
n.at(".//definitions") and break
|
87
|
+
clause = n
|
88
|
+
n["id"] == container["id"] and break
|
89
|
+
end
|
90
|
+
clause
|
91
|
+
end
|
92
|
+
|
93
|
+
def termdef_boilerplate_insert1(sect, xmldoc, isodoc)
|
94
|
+
ins = sect.at("./title")
|
95
|
+
if (ins2 = sect.at("./clause[@type = 'boilerplate'] | " \
|
96
|
+
"./note[@type = 'boilerplate']"))
|
97
|
+
ins2.text.strip.downcase == "(default)" or return
|
98
|
+
ins2.children = " "
|
99
|
+
ins = ins2.children.first
|
100
|
+
end
|
101
|
+
term_defs_boilerplate(ins, xmldoc.xpath(".//termdocsource"),
|
102
|
+
sect.at(".//term"), sect.at(".//p"), isodoc)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|