metanorma-standoc 2.4.8 → 2.4.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/isodoc/html/htmlstyle.css +13 -9
- data/lib/isodoc/html/htmlstyle.scss +6 -6
- data/lib/metanorma/standoc/cleanup_block.rb +1 -0
- data/lib/metanorma/standoc/cleanup_terms.rb +1 -0
- data/lib/metanorma/standoc/cleanup_terms_designations.rb +20 -5
- data/lib/metanorma/standoc/converter.rb +2 -2
- data/lib/metanorma/standoc/inline.rb +8 -1
- data/lib/metanorma/standoc/macros.rb +0 -2
- data/lib/metanorma/standoc/ref_sect.rb +4 -3
- data/lib/metanorma/standoc/term_lookup_cleanup.rb +106 -59
- data/lib/metanorma/standoc/validate.rb +30 -65
- data/lib/metanorma/standoc/validate_term.rb +89 -0
- data/lib/metanorma/standoc/version.rb +1 -1
- metadata +3 -3
- data/lib/metanorma/standoc/validate_xref.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70483d0ae3e7369ea535a02fed125b9b073c2792cc9a589c22cd94ea98948d1e
|
4
|
+
data.tar.gz: 9fb3bcbfb78079b25cbdfb6f49fdefc4df8928a8d0782878396be6a6f286374c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
124
|
+
a.FootnoteRef + a.FootnoteRef::before {
|
125
125
|
content: ", ";
|
126
126
|
vertical-align: super; }
|
127
127
|
|
128
|
-
a.TableFootnoteRef + a.TableFootnoteRef
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
304
|
+
ol[class="roman"] ol[class="roman"] > li::before {
|
305
305
|
counter-increment: none;
|
306
306
|
content: initial;
|
307
307
|
}
|
@@ -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
|
-
|
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
|
-
|
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 =
|
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
|
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,6 +20,8 @@ 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
27
|
preprocessor Metanorma::Plugin::Datastruct::Json2TextPreprocessor
|
@@ -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
|
-
|
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
|
@@ -85,13 +85,14 @@ module Metanorma
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
def
|
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
|
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
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
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 =
|
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
|
-
|
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.
|
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 = "
|
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
|
-
|
141
|
-
|
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
|
-
|
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.
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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
|
161
|
-
|
162
|
-
|
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
|
166
|
-
term_text = normalize_ref_id(node
|
167
|
-
unless
|
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
|
-
|
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
|
185
|
-
|
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
|
-
|
190
|
-
|
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
|
-
|
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 "./
|
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
|
-
|
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
|
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.
|
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-07-
|
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/
|
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
|