metanorma-standoc 2.4.7 → 2.4.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66a2d55d6c29842acb1b636afe7cf434c1769692a4b81ddee42fe77abf706f2a
4
- data.tar.gz: 77cc311b6679b34314274cb136807747a2e029eb7ced3bdd5830c16732a15d28
3
+ metadata.gz: 70483d0ae3e7369ea535a02fed125b9b073c2792cc9a589c22cd94ea98948d1e
4
+ data.tar.gz: 9fb3bcbfb78079b25cbdfb6f49fdefc4df8928a8d0782878396be6a6f286374c
5
5
  SHA512:
6
- metadata.gz: c65b3f99e33a4ad4452b05cc3c0d6c9e545179d50bc5e6bf8ff8a718287a3dfa2b344c233c7fb3adf1c95835aa0370910740b0262c8266f26dd9b8920ea074bc
7
- data.tar.gz: 347dbf45508a7ab22323e24ba46abc08c1c4f1d091b17823fe941d844726774b85c0fa9c82a8399c08ac763fbb6d2cf5bb3e5e9f554e21d6e2a3e0abf39dc7e4
6
+ metadata.gz: f2b70e60bd3f83f8218c16bf24d9ff8a164b4a0467cf6f47e4090da745034f048a5dd91d813e0242f365eccf52ab71e2af1b477b320d1e310412c8065b02742b
7
+ data.tar.gz: 2008df0fab61498838336fa8ddbf94efa3845583ed1740223a877b8ad27ccfc8d257553067f3a84226ff41ef0cc2bda91b2fd90e88a2d8be2aaf3032688bebef
@@ -98,7 +98,7 @@ h1, h2, h3, h4, h5, h6 {
98
98
 
99
99
  blockquote, q {
100
100
  quotes: none; }
101
- blockquote:before, blockquote:after, q:before, q:after {
101
+ blockquote::before, blockquote::after, q::before, q::after {
102
102
  content: '';
103
103
  content: none; }
104
104
 
@@ -121,14 +121,18 @@ b, strong {
121
121
  div.document-stage-band, div.document-type-band {
122
122
  background-color: #333333; }
123
123
 
124
- a.FootnoteRef + a.FootnoteRef:before {
124
+ a.FootnoteRef + a.FootnoteRef::before {
125
125
  content: ", ";
126
126
  vertical-align: super; }
127
127
 
128
- a.TableFootnoteRef + a.TableFootnoteRef:before {
128
+ a.TableFootnoteRef + a.TableFootnoteRef::before {
129
129
  content: ", ";
130
130
  vertical-align: super; }
131
131
 
132
+ a.TableFootnoteRef, span.TableFootnoteRef,
133
+ a.FootnoteRef, span.FootnoteRef {
134
+ vertical-align: super; }
135
+
132
136
  .addition {
133
137
  color: blue; }
134
138
 
@@ -594,7 +598,7 @@ ul, ol {
594
598
  ul li {
595
599
  list-style: none; }
596
600
 
597
- ul li:before {
601
+ ul li::before {
598
602
  content: "—";
599
603
  display: inline-block;
600
604
  width: 1em;
@@ -612,7 +616,7 @@ ul li:first-child {
612
616
  #toc-list li {
613
617
  list-style-type: none; }
614
618
 
615
- #toc li:before {
619
+ #toc li::before {
616
620
  content: " ";
617
621
  display: none; }
618
622
 
@@ -633,13 +637,13 @@ ol[class="alphabet"] > li {
633
637
  ol[class="alphabet"] ol[class="alphabet"] > li {
634
638
  list-style: inherit; }
635
639
 
636
- ol[class="alphabet"] > li:before {
640
+ ol[class="alphabet"] > li::before {
637
641
  counter-increment: alphabet;
638
642
  content: counter(alphabet, lower-alpha) ") ";
639
643
  position: absolute;
640
644
  left: -1.4em; }
641
645
 
642
- ol[class="alphabet"] ol[class="alphabet"] > li:before {
646
+ ol[class="alphabet"] ol[class="alphabet"] > li::before {
643
647
  counter-increment: none;
644
648
  content: initial; }
645
649
 
@@ -653,13 +657,13 @@ ol[class="roman"] > li {
653
657
  ol[class="roman"] ol[class="roman"] > li {
654
658
  list-style: inherit; }
655
659
 
656
- ol[class="roman"] > li:before {
660
+ ol[class="roman"] > li::before {
657
661
  counter-increment: roman;
658
662
  content: "(" counter(roman, lower-roman) ") ";
659
663
  position: absolute;
660
664
  left: -2.0em; }
661
665
 
662
- ol[class="roman"] ol[class="roman"] > li:before {
666
+ ol[class="roman"] ol[class="roman"] > li::before {
663
667
  counter-increment: none;
664
668
  content: initial; }
665
669
 
@@ -230,7 +230,7 @@ ul li {
230
230
  list-style: none;
231
231
  }
232
232
 
233
- ul li:before {
233
+ ul li::before {
234
234
  content: "—";
235
235
  display: inline-block; width: 1em;
236
236
  margin-left: -1.2em;
@@ -252,7 +252,7 @@ ul li:first-child {
252
252
  list-style-type: none;
253
253
  }
254
254
 
255
- #toc li:before {
255
+ #toc li::before {
256
256
  content: " ";
257
257
  display: none;
258
258
  }
@@ -275,13 +275,13 @@ ol[class="alphabet"] > li {
275
275
  ol[class="alphabet"] ol[class="alphabet"] > li {
276
276
  list-style: inherit;
277
277
  }
278
- ol[class="alphabet"] > li:before {
278
+ ol[class="alphabet"] > li::before {
279
279
  counter-increment: alphabet;
280
280
  content: counter(alphabet, lower-alpha)") ";
281
281
  position: absolute;
282
282
  left: -1.4em;
283
283
  }
284
- ol[class="alphabet"] ol[class="alphabet"] > li:before {
284
+ ol[class="alphabet"] ol[class="alphabet"] > li::before {
285
285
  counter-increment: none;
286
286
  content: initial;
287
287
  }
@@ -295,13 +295,13 @@ ol[class="roman"] > li {
295
295
  ol[class="roman"] ol[class="roman"] > li {
296
296
  list-style: inherit;
297
297
  }
298
- ol[class="roman"] > li:before {
298
+ ol[class="roman"] > li::before {
299
299
  counter-increment: roman;
300
300
  content: "("counter(roman, lower-roman)") ";
301
301
  position: absolute;
302
302
  left: -2.0em;
303
303
  }
304
- ol[class="roman"] ol[class="roman"] > li:before {
304
+ ol[class="roman"] ol[class="roman"] > li::before {
305
305
  counter-increment: none;
306
306
  content: initial;
307
307
  }
@@ -233,6 +233,7 @@ module Metanorma
233
233
  def unnumbered_blocks_cleanup(xmldoc)
234
234
  @blockunnumbered&.each do |b|
235
235
  xmldoc.xpath("//#{b}").each do |e|
236
+ /^[^_]/.match?(e["id"]) and e["unnumbered"] = "false"
236
237
  e["unnumbered"] ||= "true"
237
238
  end
238
239
  end
@@ -111,6 +111,7 @@ module Metanorma
111
111
  term_dl_to_metadata(xmldoc)
112
112
  term_termsource_to_designation(xmldoc)
113
113
  term_designation_reorder(xmldoc)
114
+ term_designation_redundant(xmldoc)
114
115
  termdef_from_termbase(xmldoc)
115
116
  termdomain_cleanup(xmldoc)
116
117
  termdef_stem_cleanup(xmldoc)
@@ -101,7 +101,7 @@ module Metanorma
101
101
 
102
102
  def term_dl_to_designation_category(prev, category)
103
103
  cat = prev.at(".//expression/grammar/#{category}")
104
- /,/.match?(cat&.text) and
104
+ cat&.text&.include?(",") and
105
105
  cat.replace(cat.text.split(/,\s*/)
106
106
  .map { |x| "<#{category}>#{x}</#{category}>" }.join)
107
107
  end
@@ -148,13 +148,15 @@ module Metanorma
148
148
  end
149
149
  end
150
150
 
151
+ DESIGNATOR = %w(preferred admitted deprecates related).freeze
152
+
151
153
  def term_termsource_to_designation(xmldoc)
152
154
  xmldoc.xpath("//term/termsource").each do |t|
153
155
  p = t.previous_element
154
156
  while %w(domain subject).include? p&.name
155
157
  p = p.previous_element
156
158
  end
157
- %w(preferred admitted deprecates related).include?(p&.name) or
159
+ DESIGNATOR.include?(p&.name) or
158
160
  next
159
161
  related2pref(p) << t.remove
160
162
  end
@@ -162,8 +164,7 @@ module Metanorma
162
164
 
163
165
  def term_designation_reorder(xmldoc)
164
166
  xmldoc.xpath("//term").each do |t|
165
- des = %w(preferred admitted deprecates related)
166
- .each_with_object([]) do |tag, m|
167
+ des = DESIGNATOR.each_with_object([]) do |tag, m|
167
168
  t.xpath("./#{tag}").each { |x| m << x.remove }
168
169
  end.reverse
169
170
  t << " "
@@ -174,7 +175,21 @@ module Metanorma
174
175
  end
175
176
 
176
177
  def related2pref(elem)
177
- elem&.name == "related" ? elem = elem.at("./preferred") : elem
178
+ elem&.name == "related" ? elem.at("./preferred") : elem
179
+ end
180
+
181
+ def term_designation_redundant(xmldoc)
182
+ xmldoc.xpath("//term").each do |t|
183
+ DESIGNATOR.each do |n|
184
+ t.xpath("./#{n}/expression/name").each_with_object([]) do |d, m|
185
+ if m.include?(d.text)
186
+ @log.add("Terms", t, "Removed duplicate designation #{d.text}")
187
+ d.parent.parent.remove
188
+ end
189
+ m << d.text
190
+ end
191
+ end
192
+ end
178
193
  end
179
194
  end
180
195
  end
@@ -20,11 +20,13 @@ module Metanorma
20
20
  # schema encapsulation of the document for validation
21
21
  class Converter
22
22
  Asciidoctor::Extensions.register do
23
+ preprocessor Metanorma::Standoc::EmbedIncludeProcessor
24
+ preprocessor Metanorma::Standoc::NamedEscapePreprocessor
23
25
  preprocessor Metanorma::Standoc::Datamodel::AttributesTablePreprocessor
24
26
  preprocessor Metanorma::Standoc::Datamodel::DiagramPreprocessor
25
- preprocessor Metanorma::Plugin::Glossarist::DatasetPreprocessor
26
27
  preprocessor Metanorma::Plugin::Datastruct::Json2TextPreprocessor
27
28
  preprocessor Metanorma::Plugin::Datastruct::Yaml2TextPreprocessor
29
+ preprocessor Metanorma::Plugin::Glossarist::DatasetPreprocessor
28
30
  inline_macro Metanorma::Standoc::PreferredTermInlineMacro
29
31
  inline_macro Metanorma::Standoc::DateInlineMacro
30
32
  inline_macro Metanorma::Standoc::SpanInlineMacro
@@ -60,8 +62,6 @@ module Metanorma
60
62
  treeprocessor Metanorma::Standoc::ToDoInlineAdmonitionBlock
61
63
  block Metanorma::Standoc::PlantUMLBlockMacro
62
64
  block Metanorma::Standoc::PseudocodeBlockMacro
63
- preprocessor Metanorma::Standoc::EmbedIncludeProcessor
64
- preprocessor Metanorma::Standoc::NamedEscapePreprocessor
65
65
  end
66
66
 
67
67
  include ::Asciidoctor::Converter
@@ -215,7 +215,14 @@ module Metanorma
215
215
  end
216
216
 
217
217
  def image_attributes(node)
218
- uri = node.image_uri (node.attr("target") || node.target)
218
+ nodetarget = node.attr("target") || node.target
219
+ if Gem.win_platform? && /^[a-zA-Z]:/.match?(nodetarget)
220
+ nodetarget.prepend("/")
221
+ end
222
+ uri = node.image_uri (nodetarget)
223
+ if Gem.win_platform? && /^\/[a-zA-Z]:/.match?(uri)
224
+ uri = uri[1..-1]
225
+ end
219
226
  types = if /^data:/.match?(uri) then Metanorma::Utils::datauri2mime(uri)
220
227
  else MIME::Types.type_for(uri)
221
228
  end
@@ -1,5 +1,3 @@
1
- require "asciidoctor/extensions"
2
- require "fileutils"
3
1
  require "uuidtools"
4
2
  require "yaml"
5
3
  require "csv"
@@ -85,13 +85,14 @@ module Metanorma
85
85
  end
86
86
  end
87
87
 
88
- def fetchable_ref_code?(ref)
89
- ref[:code].nil? || ref[:code].empty? || ref[:no_year] ||
88
+ def unfetchable_ref_code?(ref)
89
+ ref[:code].nil? || ref[:code].empty? || ref[:no_year] ||
90
+ /^\(.+\)$/.match?(ref[:code]) ||
90
91
  (@bibdb.nil? && !ref[:localfile])
91
92
  end
92
93
 
93
94
  def fetch_ref_async(ref, idx, res)
94
- if fetchable_ref_code?(ref)
95
+ if unfetchable_ref_code?(ref)
95
96
  res << [ref, idx, nil]
96
97
  elsif ref[:localfile]
97
98
  res << [ref, idx, @local_bibdb.get(ref[:code], ref[:localfile])]
@@ -1,11 +1,10 @@
1
- # frozen_string_literal: true.
2
1
  require "metanorma/standoc/utils"
3
2
 
4
3
  module Metanorma
5
4
  module Standoc
6
5
  # Intelligent term lookup xml modifier
7
6
  class TermLookupCleanup
8
- AUTOMATIC_GENERATED_ID_REGEXP = /\A_/.freeze
7
+ AUTO_GEN_ID_REGEXP = /\A_/.freeze
9
8
  EXISTING_TERM_REGEXP = /\Aterm-/.freeze
10
9
  EXISTING_SYMBOL_REGEXP = /\Asymbol-/.freeze
11
10
 
@@ -16,6 +15,8 @@ module Metanorma
16
15
  @log = log
17
16
  @termlookup = { term: {}, symbol: {}, secondary2primary: {} }
18
17
  @idhash = {}
18
+ @unique_designs = {}
19
+ @c = HTMLEntities.new
19
20
  @terms_tags = xmldoc.xpath("//terms").each_with_object({}) do |t, m|
20
21
  m[t["id"]] = true
21
22
  end
@@ -23,63 +24,101 @@ module Metanorma
23
24
 
24
25
  def call
25
26
  @idhash = populate_idhash
27
+ @unique_designs = unique_designators
26
28
  @termlookup = replace_automatic_generated_ids_terms
27
29
  set_termxref_tags_target
28
30
  concept_cleanup
29
31
  related_cleanup
32
+ remove_missing_refs
33
+ concept_cleanup2
30
34
  end
31
35
 
32
36
  private
33
37
 
38
+ def unique_designators
39
+ ret = xmldoc
40
+ .xpath("//preferred/expression/name | //admitted/expression/name | " \
41
+ "//deprecated/expression/name").each_with_object({}) do |n, m|
42
+ m[n.text] ||= 0
43
+ m[n.text] += 1
44
+ end
45
+ ret.each { |k, v| v == 1 or ret.delete(k) }
46
+ ret
47
+ end
48
+
34
49
  def concept_cleanup
35
50
  xmldoc.xpath("//concept").each do |n|
36
- n.delete("type")
37
51
  refterm = n.at("./refterm") or next
38
- p = @termlookup[:secondary2primary][refterm.text] and
39
- refterm.children = p
52
+ p = @termlookup[:secondary2primary][@c.encode(refterm.text)] and
53
+ refterm.children = @c.encode(p)
40
54
  end
41
55
  end
42
56
 
57
+ def concept_cleanup2
58
+ xmldoc.xpath("//concept").each { |n| n.delete("type") }
59
+ end
60
+
43
61
  def related_cleanup
44
62
  xmldoc.xpath("//related").each do |n|
45
63
  refterm = n.at("./refterm") or next
46
- p = @termlookup[:secondary2primary][refterm.text] and
47
- refterm.children = p
48
- refterm.replace("<preferred><expression>" \
49
- "<name>#{refterm.children.to_xml}" \
50
- "</name></expression></preferred>")
64
+ lookup = @c.encode(refterm.text)
65
+ p = @termlookup[:secondary2primary][lookup] and
66
+ refterm.children = @c.encode(p)
67
+ p || @termlookup[:term][lookup] and
68
+ refterm.replace("<preferred><expression>" \
69
+ "<name>#{refterm.children.to_xml}" \
70
+ "</name></expression></preferred>")
51
71
  end
52
72
  end
53
73
 
54
74
  def populate_idhash
55
75
  xmldoc.xpath("//*[@id]").each_with_object({}) do |n, mem|
56
- next unless /^(term|symbol)-/.match?(n["id"])
57
-
76
+ /^(term|symbol)-/.match?(n["id"]) or next
58
77
  mem[n["id"]] = true
59
78
  end
60
79
  end
61
80
 
62
81
  def set_termxref_tags_target
63
82
  xmldoc.xpath("//termxref").each do |node|
64
- target = normalize_ref_id(node)
65
- if termlookup[:term][target].nil? && termlookup[:symbol][target].nil?
66
- remove_missing_ref(node, target)
67
- next
68
- end
83
+ target = normalize_ref_id1(node)
69
84
  x = node.at("../xrefrender") and modify_ref_node(x, target)
70
85
  node.name = "refterm"
71
86
  end
72
87
  end
73
88
 
89
+ def remove_missing_refs
90
+ xmldoc.xpath("//refterm").each do |node|
91
+ remove_missing_ref?(node) or next
92
+ lookup_refterm(node)
93
+ end
94
+ end
95
+
96
+ def remove_missing_ref?(node)
97
+ node.at("../eref | ../termref") and return false
98
+ xref = node.at("../xref") or return true
99
+ xref["target"] && !xref["target"]&.empty? and return false
100
+ xref.remove # if xref supplied by user, we won't delete
101
+ true
102
+ end
103
+
104
+ def lookup_refterm(node)
105
+ target = normalize_ref_id1(node)
106
+ if termlookup[:term][target].nil? && termlookup[:symbol][target].nil?
107
+ remove_missing_ref(node, target)
108
+ else
109
+ x = node.at("../xrefrender") and x.name = "xref"
110
+ end
111
+ end
112
+
74
113
  def remove_missing_ref(node, target)
75
114
  if node.at("./parent::concept[@type = 'symbol']")
76
115
  log.add("AsciiDoc Input", node,
77
116
  remove_missing_ref_msg(node, target, :symbol))
78
- remove_missing_ref_symbol(node, target)
117
+ remove_missing_ref_term(node, target, "symbol")
79
118
  else
80
119
  log.add("AsciiDoc Input", node,
81
120
  remove_missing_ref_msg(node, target, :term))
82
- remove_missing_ref_term(node, target)
121
+ remove_missing_ref_term(node, target, "term")
83
122
  end
84
123
  end
85
124
 
@@ -102,23 +141,13 @@ module Metanorma
102
141
  ret
103
142
  end
104
143
 
105
- def remove_missing_ref_term(node, target)
144
+ def remove_missing_ref_term(node, target, type)
106
145
  node.name = "strong"
107
- node.at("../xrefrender")&.remove
146
+ node.xpath("../xrefrender | ../xref").each(&:remove)
108
147
  display = node.at("../renderterm")&.remove&.children
109
148
  display = [] if display.nil? || display.to_xml == node.text
110
149
  d = display.empty? ? "" : ", display <tt>#{display.to_xml}</tt>"
111
- node.children = "term <tt>#{node.text}</tt>#{d} " \
112
- "not resolved via ID <tt>#{target}</tt>"
113
- end
114
-
115
- def remove_missing_ref_symbol(node, target)
116
- node.name = "strong"
117
- node.at("../xrefrender")&.remove
118
- display = node.at("../renderterm")&.remove&.children
119
- display = [] if display.nil? || display.to_xml == node.text
120
- d = display.empty? ? "" : ", display <tt>#{display.to_xml}</tt>"
121
- node.children = "symbol <tt>#{node.text}</tt>#{d} " \
150
+ node.children = "#{type} <tt>#{@c.encode(node.text)}</tt>#{d} " \
122
151
  "not resolved via ID <tt>#{target}</tt>"
123
152
  end
124
153
 
@@ -137,35 +166,47 @@ module Metanorma
137
166
 
138
167
  def replace_automatic_generated_ids_terms
139
168
  r = xmldoc.xpath("//term").each.with_object({}) do |n, res|
140
- normalize_id_and_memorize(n, res, "./preferred//name", "term")
141
- normalize_id_and_memorize(n, res, "./admitted//name", "term")
169
+ norm_id_memorize(n, res, "./preferred//name", "term", true)
170
+ norm_id_memorize(n, res, "./admitted//name", "term", true)
142
171
  end
143
172
  s = xmldoc.xpath("//definitions//dt").each.with_object({}) do |n, res|
144
- normalize_id_and_memorize(n, res, ".", "symbol")
173
+ norm_id_memorize(n, res, ".", "symbol", false)
145
174
  end
146
175
  { term: r, symbol: s, secondary2primary: pref_secondary2primary }
147
176
  end
148
177
 
149
178
  def pref_secondary2primary
150
- term = ""
151
179
  xmldoc.xpath("//term").each.with_object({}) do |n, res|
152
- n.xpath("./preferred//name").each_with_index do |p, i|
153
- i.zero? and term = p.text
154
- i.positive? and res[p.text] = term
155
- end
156
- n.xpath("./admitted//name").each { |p| res[p.text] = term }
180
+ primary = domain_prefix(n, n.at("./preferred//name")&.text)
181
+ pref_secondary2primary_preferred(n, res, primary)
182
+ pref_secondary2primary_admitted(n, res, primary)
183
+ end
184
+ end
185
+
186
+ def pref_secondary2primary_preferred(term, res, primary)
187
+ term.xpath("./preferred//name").each_with_index do |p, i|
188
+ i.positive? and res[domain_prefix(term, p.text)] = primary
189
+ @unique_designs[p.text] && term.at(".//domain") and
190
+ res[p.text] = primary
157
191
  end
158
192
  end
159
193
 
160
- def normalize_id_and_memorize(node, res_table, text_selector, prefix)
161
- normalize_id_and_memorize_init(node, res_table, text_selector, prefix)
162
- memorize_other_pref_terms(node, res_table, text_selector)
194
+ def pref_secondary2primary_admitted(term, res, primary)
195
+ term.xpath("./admitted//name").each do |p|
196
+ res[domain_prefix(term, p.text)] = primary
197
+ @unique_designs[p.text] && term.at(".//domain") and
198
+ res[p.text] = primary
199
+ end
200
+ end
201
+
202
+ def norm_id_memorize(node, res_table, selector, prefix, use_domain)
203
+ norm_id_memorize_init(node, res_table, selector, prefix, use_domain)
204
+ memorize_other_pref_terms(node, res_table, selector, use_domain)
163
205
  end
164
206
 
165
- def normalize_id_and_memorize_init(node, res_table, text_selector, prefix)
166
- term_text = normalize_ref_id(node.at(text_selector)) or return
167
- unless AUTOMATIC_GENERATED_ID_REGEXP.match(node["id"]).nil? &&
168
- !node["id"].nil?
207
+ def norm_id_memorize_init(node, res_table, selector, prefix, use_domain)
208
+ term_text = normalize_ref_id(node, selector, use_domain) or return
209
+ unless AUTO_GEN_ID_REGEXP.match(node["id"]).nil? && !node["id"].nil?
169
210
  id = unique_text_id(term_text, prefix)
170
211
  node["id"] = id
171
212
  @idhash[id] = true
@@ -173,28 +214,34 @@ module Metanorma
173
214
  res_table[term_text] = node["id"]
174
215
  end
175
216
 
176
- def memorize_other_pref_terms(node, res_table, text_selector)
217
+ def memorize_other_pref_terms(node, res_table, text_selector, use_domain)
177
218
  node.xpath(text_selector).each_with_index do |p, i|
178
- next unless i.positive?
179
-
180
- res_table[normalize_ref_id(p)] = node["id"]
219
+ i.positive? or next
220
+ res_table[normalize_ref_id1(p, use_domain ? node : nil)] = node["id"]
181
221
  end
182
222
  end
183
223
 
184
- def normalize_ref_id(term)
185
- return nil if term.nil?
224
+ def domain_prefix(node, term)
225
+ d = node&.at(".//domain") or return term
226
+ "<#{d.text}> #{term}"
227
+ end
186
228
 
229
+ def normalize_ref_id(node, selector, use_domain)
230
+ term = node.at(selector) or return nil
231
+ normalize_ref_id1(term, use_domain ? node : nil)
232
+ end
233
+
234
+ def normalize_ref_id1(term, node = nil)
187
235
  t = term.dup
188
236
  t.xpath(".//index").map(&:remove)
189
- Metanorma::Utils::to_ncname(t.text.strip
190
- .gsub(/[[:space:]]+/, "-"))
237
+ ret = t.text.strip
238
+ node and ret = domain_prefix(node, ret)
239
+ Metanorma::Utils::to_ncname(ret.gsub(/[[:space:]]+/, "-"))
191
240
  end
192
241
 
193
242
  def unique_text_id(text, prefix)
194
- unless @idhash["#{prefix}-#{text}"]
243
+ @idhash["#{prefix}-#{text}"] or
195
244
  return "#{prefix}-#{text}"
196
- end
197
-
198
245
  (1..Float::INFINITY).lazy.each do |index|
199
246
  unless @idhash["#{prefix}-#{text}-#{index}"]
200
247
  break("#{prefix}-#{text}-#{index}")
@@ -1,7 +1,7 @@
1
1
  require "metanorma/standoc/utils"
2
2
  require_relative "./validate_section"
3
3
  require_relative "./validate_table"
4
- require_relative "./validate_xref"
4
+ require_relative "./validate_term"
5
5
  require "nokogiri"
6
6
  require "jing"
7
7
  require "iev"
@@ -10,38 +10,6 @@ require "pngcheck"
10
10
  module Metanorma
11
11
  module Standoc
12
12
  module Validate
13
- SOURCELOCALITY = "./origin//locality[@type = 'clause']/" \
14
- "referenceFrom".freeze
15
-
16
- def init_iev
17
- @no_isobib and return nil
18
- @iev and return @iev
19
- @iev = Iev::Db.new(@iev_globalname, @iev_localname) unless @no_isobib
20
- @iev
21
- end
22
-
23
- def iev_validate(xmldoc)
24
- @iev = init_iev or return
25
- xmldoc.xpath("//term").each do |t|
26
- t.xpath(".//termsource").each do |src|
27
- (/^IEC[  ]60050-/.match(src.at("./origin/@citeas")&.text) &&
28
- loc = src.xpath(SOURCELOCALITY)&.text) or next
29
- iev_validate1(t, loc, xmldoc)
30
- end
31
- end
32
- end
33
-
34
- def iev_validate1(term, loc, xmldoc)
35
- iev = @iev.fetch(loc,
36
- xmldoc.at("//language")&.text || "en") or return
37
- pref = term.xpath("./preferred//name").inject([]) do |m, x|
38
- m << x.text&.downcase
39
- end
40
- pref.include?(iev.downcase) or
41
- @log.add("Bibliography", term, %(Term "#{pref[0]}" does not match ) +
42
- %(IEV #{loc} "#{iev}"))
43
- end
44
-
45
13
  def content_validate(doc)
46
14
  repeat_id_validate(doc.root) # feeds xref_validate
47
15
  xref_validate(doc) # feeds nested_asset_validate
@@ -51,6 +19,7 @@ module Metanorma
51
19
  iev_validate(doc.root)
52
20
  concept_validate(doc, "concept", "refterm")
53
21
  concept_validate(doc, "related", "preferred//name")
22
+ preferred_validate(doc)
54
23
  table_validate(doc)
55
24
  @fatalerror += requirement_validate(doc)
56
25
  image_validate(doc)
@@ -73,7 +42,7 @@ module Metanorma
73
42
  def mathml_sanitise(math)
74
43
  math.to_xml(encoding: "US-ASCII").gsub(/ xmlns=["'][^"']+["']/, "")
75
44
  .gsub(%r{<[^:/>]+:}, "<").gsub(%r{</[^:/>]+:}, "</")
76
- #.gsub(/&#([^;]+);/) { |x| "&#x#{$1.to_i.to_s(16)};" }
45
+ # .gsub(/&#([^;]+);/) { |x| "&#x#{$1.to_i.to_s(16)};" }
77
46
  end
78
47
 
79
48
  def math_validate_error(math, elem, error)
@@ -125,37 +94,6 @@ module Metanorma
125
94
  # @fatalerror << err2
126
95
  end
127
96
 
128
- def concept_validate(doc, tag, refterm)
129
- found = false
130
- concept_validate_ids(doc)
131
- doc.xpath("//#{tag}/xref").each do |x|
132
- @concept_ids[x["target"]] and next
133
- @log.add("Anchors", x, concept_validate_msg(doc, tag, refterm, x))
134
- found = true
135
- end
136
- found and @fatalerror << "#{tag.capitalize} not cross-referencing " \
137
- "term or symbol"
138
- end
139
-
140
- def concept_validate_ids(doc)
141
- @concept_ids ||= doc.xpath("//term | //definitions//dt")
142
- .each_with_object({}) { |x, m| m[x["id"]] = true }
143
- @concept_terms_tags ||= doc.xpath("//terms")
144
- .each_with_object({}) { |t, m| m[t["id"]] = true }
145
- nil
146
- end
147
-
148
- def concept_validate_msg(_doc, tag, refterm, xref)
149
- ret = <<~LOG
150
- #{tag.capitalize} #{xref.at("../#{refterm}")&.text} is pointing to #{xref['target']}, which is not a term or symbol
151
- LOG
152
- if @concept_terms_tags[xref["target"]]
153
- ret = ret.strip
154
- ret += ". Did you mean to point to a subterm?"
155
- end
156
- ret
157
- end
158
-
159
97
  def schema_validate(doc, schema)
160
98
  Tempfile.open(["tmp", ".xml"], encoding: "UTF-8") do |f|
161
99
  schema_validate1(f, doc, schema)
@@ -247,6 +185,33 @@ module Metanorma
247
185
  schema_validate(formattedstr_strip(doc.dup),
248
186
  File.join(File.dirname(__FILE__), "isodoc-compile.rng"))
249
187
  end
188
+
189
+ def repeat_id_validate1(elem)
190
+ if @doc_ids[elem["id"]]
191
+ @log.add("Anchors", elem, "Anchor #{elem['id']} has already been " \
192
+ "used at line #{@doc_ids[elem['id']]}")
193
+ @fatalerror << "Multiple instances of same ID: #{elem['id']}"
194
+ end
195
+ @doc_ids[elem["id"]] = elem.line
196
+ end
197
+
198
+ def repeat_id_validate(doc)
199
+ @doc_ids = {}
200
+ doc.xpath("//*[@id]").each do |x|
201
+ repeat_id_validate1(x)
202
+ end
203
+ end
204
+
205
+ # manually check for xref/@target, xref/@to integrity
206
+ def xref_validate(doc)
207
+ @doc_xrefs = doc.xpath("//xref/@target | //xref/@to")
208
+ .each_with_object({}) do |x, m|
209
+ m[x.text] = x
210
+ @doc_ids[x.text] and next
211
+ @log.add("Anchors", x.parent,
212
+ "Crossreference target #{x} is undefined")
213
+ end
214
+ end
250
215
  end
251
216
  end
252
217
  end
@@ -0,0 +1,89 @@
1
+ module Metanorma
2
+ module Standoc
3
+ module Validate
4
+ SOURCELOCALITY = "./origin//locality[@type = 'clause']/" \
5
+ "referenceFrom".freeze
6
+
7
+ def init_iev
8
+ @no_isobib and return nil
9
+ @iev and return @iev
10
+ @iev = Iev::Db.new(@iev_globalname, @iev_localname) unless @no_isobib
11
+ @iev
12
+ end
13
+
14
+ def iev_validate(xmldoc)
15
+ @iev = init_iev or return
16
+ xmldoc.xpath("//term").each do |t|
17
+ t.xpath(".//termsource").each do |src|
18
+ (/^IEC[  ]60050-/.match(src.at("./origin/@citeas")&.text) &&
19
+ loc = src.xpath(SOURCELOCALITY)&.text) or next
20
+ iev_validate1(t, loc, xmldoc)
21
+ end
22
+ end
23
+ end
24
+
25
+ def iev_validate1(term, loc, xmldoc)
26
+ iev = @iev.fetch(loc,
27
+ xmldoc.at("//language")&.text || "en") or return
28
+ pref = term.xpath("./preferred//name").inject([]) do |m, x|
29
+ m << x.text&.downcase
30
+ end
31
+ pref.include?(iev.downcase) or
32
+ @log.add("Bibliography", term, %(Term "#{pref[0]}" does not match ) +
33
+ %(IEV #{loc} "#{iev}"))
34
+ end
35
+
36
+ def concept_validate(doc, tag, refterm)
37
+ found = false
38
+ concept_validate_ids(doc)
39
+ doc.xpath("//#{tag}/xref").each do |x|
40
+ @concept_ids[x["target"]] and next
41
+ @log.add("Anchors", x, concept_validate_msg(doc, tag, refterm, x))
42
+ found = true
43
+ end
44
+ found and @fatalerror << "#{tag.capitalize} not cross-referencing " \
45
+ "term or symbol"
46
+ end
47
+
48
+ def concept_validate_ids(doc)
49
+ @concept_ids ||= doc.xpath("//term | //definitions//dt")
50
+ .each_with_object({}) { |x, m| m[x["id"]] = true }
51
+ @concept_terms_tags ||= doc.xpath("//terms")
52
+ .each_with_object({}) { |t, m| m[t["id"]] = true }
53
+ nil
54
+ end
55
+
56
+ def concept_validate_msg(_doc, tag, refterm, xref)
57
+ ret = <<~LOG
58
+ #{tag.capitalize} #{xref.at("../#{refterm}")&.text} is pointing to #{xref['target']}, which is not a term or symbol
59
+ LOG
60
+ if @concept_terms_tags[xref["target"]]
61
+ ret = ret.strip
62
+ ret += ". Did you mean to point to a subterm?"
63
+ end
64
+ ret
65
+ end
66
+
67
+ def preferred_validate(doc)
68
+ out = []
69
+ ret = doc.xpath("//term").each_with_object({}) do |t, m|
70
+ prefix = t.at("./domain")&.text
71
+ t.xpath("./preferred//name").each do |n|
72
+ ret = n.text
73
+ prefix and ret = "<#{prefix}> #{ret}"
74
+ (m[ret] and out << ret) or m[ret] = t
75
+ end
76
+ end
77
+ preferred_validate_report(out, ret)
78
+ end
79
+
80
+ def preferred_validate_report(terms, locations)
81
+ terms.each do |e|
82
+ err = "Term #{e} occurs twice as preferred designation"
83
+ @log.add("Terms", locations[e], err)
84
+ @fatalerror << err
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION = "2.4.7".freeze
22
+ VERSION = "2.4.9".freeze
23
23
  end
24
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-standoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.7
4
+ version: 2.4.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-20 00:00:00.000000000 Z
11
+ date: 2023-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -529,7 +529,7 @@ files:
529
529
  - lib/metanorma/standoc/validate.rb
530
530
  - lib/metanorma/standoc/validate_section.rb
531
531
  - lib/metanorma/standoc/validate_table.rb
532
- - lib/metanorma/standoc/validate_xref.rb
532
+ - lib/metanorma/standoc/validate_term.rb
533
533
  - lib/metanorma/standoc/version.rb
534
534
  - lib/metanorma/standoc/views/datamodel/model_representation.adoc.erb
535
535
  - lib/metanorma/standoc/views/datamodel/plantuml_representation.adoc.erb
@@ -1,32 +0,0 @@
1
- module Metanorma
2
- module Standoc
3
- module Validate
4
- def repeat_id_validate1(elem)
5
- if @doc_ids[elem["id"]]
6
- @log.add("Anchors", elem, "Anchor #{elem['id']} has already been " \
7
- "used at line #{@doc_ids[elem['id']]}")
8
- @fatalerror << "Multiple instances of same ID: #{elem['id']}"
9
- end
10
- @doc_ids[elem["id"]] = elem.line
11
- end
12
-
13
- def repeat_id_validate(doc)
14
- @doc_ids = {}
15
- doc.xpath("//*[@id]").each do |x|
16
- repeat_id_validate1(x)
17
- end
18
- end
19
-
20
- # manually check for xref/@target, xref/@to integrity
21
- def xref_validate(doc)
22
- @doc_xrefs = doc.xpath("//xref/@target | //xref/@to")
23
- .each_with_object({}) do |x, m|
24
- m[x.text] = x
25
- @doc_ids[x.text] and next
26
- @log.add("Anchors", x.parent,
27
- "Crossreference target #{x} is undefined")
28
- end
29
- end
30
- end
31
- end
32
- end