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 +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 +3 -3
- 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,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
|
-
|
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-
|
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
|