metanorma-standoc 2.9.5 → 2.9.7

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