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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/isodoc/html/htmlstyle.css +4 -1
  3. data/lib/metanorma/standoc/base.rb +8 -8
  4. data/lib/metanorma/standoc/basicdoc.rng +909 -464
  5. data/lib/metanorma/standoc/biblio-standoc.rng +87 -20
  6. data/lib/metanorma/standoc/biblio.rng +884 -325
  7. data/lib/metanorma/standoc/blocks.rb +1 -1
  8. data/lib/metanorma/standoc/cleanup.rb +4 -2
  9. data/lib/metanorma/standoc/cleanup_bibitem.rb +18 -6
  10. data/lib/metanorma/standoc/cleanup_boilerplate.rb +9 -93
  11. data/lib/metanorma/standoc/cleanup_inline.rb +1 -1
  12. data/lib/metanorma/standoc/cleanup_maths.rb +51 -101
  13. data/lib/metanorma/standoc/cleanup_mathvariant.rb +88 -0
  14. data/lib/metanorma/standoc/cleanup_terms.rb +4 -1
  15. data/lib/metanorma/standoc/cleanup_terms_boilerplate.rb +106 -0
  16. data/lib/metanorma/standoc/cleanup_terms_designations.rb +1 -2
  17. data/lib/metanorma/standoc/cleanup_text.rb +11 -4
  18. data/lib/metanorma/standoc/cleanup_xref.rb +1 -1
  19. data/lib/metanorma/standoc/converter.rb +2 -0
  20. data/lib/metanorma/standoc/datamodel/plantuml_renderer.rb +1 -1
  21. data/lib/metanorma/standoc/init.rb +23 -4
  22. data/lib/metanorma/standoc/inline.rb +27 -14
  23. data/lib/metanorma/standoc/isodoc.rng +1031 -912
  24. data/lib/metanorma/standoc/localbib.rb +1 -1
  25. data/lib/metanorma/standoc/macros.rb +1 -1
  26. data/lib/metanorma/standoc/macros_inline.rb +11 -9
  27. data/lib/metanorma/standoc/macros_plantuml.rb +1 -1
  28. data/lib/metanorma/standoc/ref.rb +1 -1
  29. data/lib/metanorma/standoc/ref_queue.rb +1 -1
  30. data/lib/metanorma/standoc/ref_utility.rb +7 -6
  31. data/lib/metanorma/standoc/reqt.rng +94 -72
  32. data/lib/metanorma/standoc/section.rb +2 -2
  33. data/lib/metanorma/standoc/term_lookup_cleanup.rb +2 -2
  34. data/lib/metanorma/standoc/utils.rb +4 -2
  35. data/lib/metanorma/standoc/version.rb +1 -1
  36. metadata +4 -2
@@ -77,7 +77,7 @@ module Metanorma
77
77
  def stem(node)
78
78
  noko do |xml|
79
79
  xml.formula **formula_attrs(node) do |s|
80
- stem_parse(node.lines.join("\n"), s, node.style.to_sym, node.block?)
80
+ stem_parse(node.lines.join("\n"), s, node.style.to_sym, node)
81
81
  end
82
82
  end
83
83
  end
@@ -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 = save_attachment(u.text, b)
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 save_attachment(path, bib)
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
- File.join(@attachmentsfld, f)
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 = File.join(@attachmentsdir, File.basename(path))
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 = "<p>#{pref}</p>"
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 progress_conv(idx, step, total, threshold, msg)
62
- return unless (idx % step).zero? && total > threshold && idx.positive?
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
- return if xml.children.any?(&:element?)
69
-
74
+ xml.children.any?(&:element?) and return
70
75
  math = xml.text.gsub("&lt;", "<").gsub("&gt;", ">")
71
76
  .gsub("&quot;", '"').gsub("&apos;", "'").gsub("&amp;", "&")
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 mathml_unitsML(xmldoc)
128
- return unless xmldoc.at(".//m:*", "m" => UNITSML_NS)
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
- return if tags.empty?
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
- unitsml = Asciimath2UnitsML::Conv.new(asciimath2unitsml_options)
182
+ a2u = Asciimath2UnitsML::Conv.new(asciimath2unitsml_options)
231
183
  xmldoc.xpath("//stem[@type = 'MathML'][not(@validate = 'false')]")
232
184
  .each do |x|
233
- xml_unescape_mathml(x)
234
- mathml_namespace(x)
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
- mathml_unitsML(xmldoc)
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 term_children_cleanup(xmldoc)
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