metanorma-iso 2.4.2 → 2.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/isodoc/iso/html/html_iso_intro.html +0 -1
- data/lib/isodoc/iso/html/word_iso_intro-dis.html +0 -2
- data/lib/isodoc/iso/html/word_iso_intro.html +0 -2
- data/lib/isodoc/iso/iso.amendment.xsl +874 -329
- data/lib/isodoc/iso/iso.international-standard.xsl +874 -329
- data/lib/isodoc/iso/presentation_terms.rb +102 -0
- data/lib/isodoc/iso/presentation_xml_convert.rb +7 -83
- data/lib/isodoc/iso/sections.rb +10 -10
- data/lib/isodoc/iso/word_cleanup.rb +3 -0
- data/lib/metanorma/iso/base.rb +1 -0
- data/lib/metanorma/iso/isodoc.rng +16 -7
- data/lib/metanorma/iso/isostandard-amd.rng +5 -8
- data/lib/metanorma/iso/isostandard.rng +5 -8
- data/lib/metanorma/iso/validate.rb +2 -0
- data/lib/metanorma/iso/validate_image.rb +6 -5
- data/lib/metanorma/iso/validate_list.rb +6 -6
- data/lib/metanorma/iso/validate_requirements.rb +24 -0
- data/lib/metanorma/iso/validate_style.rb +49 -8
- data/lib/metanorma/iso/version.rb +1 -1
- data/metanorma-iso.gemspec +1 -1
- metadata +5 -4
@@ -0,0 +1,102 @@
|
|
1
|
+
require_relative "init"
|
2
|
+
require "isodoc"
|
3
|
+
require_relative "index"
|
4
|
+
require_relative "presentation_xref"
|
5
|
+
require_relative "presentation_bibdata"
|
6
|
+
require_relative "../../relaton/render/general"
|
7
|
+
|
8
|
+
module IsoDoc
|
9
|
+
module Iso
|
10
|
+
class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
|
11
|
+
def concept(docxml)
|
12
|
+
concept_term(docxml)
|
13
|
+
docxml.xpath(ns("//concept")).each do |node|
|
14
|
+
concept_render(node, ital: "false", ref: "false",
|
15
|
+
linkref: "true", linkmention: "false")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def concept_term(docxml)
|
20
|
+
docxml.xpath(ns("//term")).each do |f|
|
21
|
+
m = {}
|
22
|
+
(f.xpath(ns(".//concept")) - f.xpath(ns(".//term//concept")))
|
23
|
+
.each { |c| concept_term1(c, m) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def concept_term1(node, seen)
|
28
|
+
term = to_xml(node.at(ns("./refterm")))
|
29
|
+
if term && seen[term]
|
30
|
+
concept_render(node, ital: "false", ref: "false",
|
31
|
+
linkref: "true", linkmention: "false")
|
32
|
+
else concept_render(node, ital: "true", ref: "true",
|
33
|
+
linkref: "true", linkmention: "false")
|
34
|
+
end
|
35
|
+
seen[term] = true if term
|
36
|
+
seen
|
37
|
+
end
|
38
|
+
|
39
|
+
def concept1_ref_content(ref)
|
40
|
+
prev = "("
|
41
|
+
foll = ")"
|
42
|
+
if ref.name == "termref"
|
43
|
+
prev, foll = @i18n.term_defined_in.split("%")
|
44
|
+
end
|
45
|
+
ref.previous = prev
|
46
|
+
ref.next = foll
|
47
|
+
end
|
48
|
+
|
49
|
+
def concept1(node)
|
50
|
+
node.replace(node&.at(ns("./renderterm"))&.children ||
|
51
|
+
node&.at(ns("./refterm"))&.children ||
|
52
|
+
node.children)
|
53
|
+
end
|
54
|
+
|
55
|
+
def termdefinition1(elem)
|
56
|
+
prefix_domain_to_definition(elem)
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
def prefix_domain_to_definition(elem)
|
61
|
+
((d = elem.at(ns("./domain"))) &&
|
62
|
+
(v = elem.at(ns("./definition/verbal-definition"))) &&
|
63
|
+
v.elements.first.name == "p") or return
|
64
|
+
v.elements.first.children.first.previous =
|
65
|
+
"<#{to_xml(d.remove.children)}> "
|
66
|
+
end
|
67
|
+
|
68
|
+
def insertall_after_here(node, insert, name)
|
69
|
+
node.children.each do |n|
|
70
|
+
n.name == name or next
|
71
|
+
insert.next = n.remove
|
72
|
+
insert = n
|
73
|
+
end
|
74
|
+
insert
|
75
|
+
end
|
76
|
+
|
77
|
+
def termexamples_before_termnotes(node)
|
78
|
+
insert = node.at(ns("./definition")) or return
|
79
|
+
insert = insertall_after_here(node, insert, "termexample")
|
80
|
+
insertall_after_here(node, insert, "termnote")
|
81
|
+
end
|
82
|
+
|
83
|
+
def terms(docxml)
|
84
|
+
docxml.xpath(ns("//term[termnote][termexample]")).each do |node|
|
85
|
+
termexamples_before_termnotes(node)
|
86
|
+
end
|
87
|
+
super
|
88
|
+
end
|
89
|
+
|
90
|
+
def related1(node)
|
91
|
+
node.remove
|
92
|
+
end
|
93
|
+
|
94
|
+
def termsource_status(status)
|
95
|
+
case status
|
96
|
+
when "modified", "adapted"
|
97
|
+
@i18n.modified
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -3,6 +3,7 @@ require "isodoc"
|
|
3
3
|
require_relative "index"
|
4
4
|
require_relative "presentation_xref"
|
5
5
|
require_relative "presentation_bibdata"
|
6
|
+
require_relative "presentation_terms"
|
6
7
|
require_relative "../../relaton/render/general"
|
7
8
|
|
8
9
|
module IsoDoc
|
@@ -86,50 +87,6 @@ module IsoDoc
|
|
86
87
|
end
|
87
88
|
end
|
88
89
|
|
89
|
-
def concept(docxml)
|
90
|
-
concept_term(docxml)
|
91
|
-
docxml.xpath(ns("//concept")).each do |node|
|
92
|
-
concept_render(node, ital: "false", ref: "false",
|
93
|
-
linkref: "true", linkmention: "false")
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def concept_term(docxml)
|
98
|
-
docxml.xpath(ns("//term")).each do |f|
|
99
|
-
m = {}
|
100
|
-
(f.xpath(ns(".//concept")) - f.xpath(ns(".//term//concept")))
|
101
|
-
.each { |c| concept_term1(c, m) }
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def concept_term1(node, seen)
|
106
|
-
term = to_xml(node.at(ns("./refterm")))
|
107
|
-
if term && seen[term]
|
108
|
-
concept_render(node, ital: "false", ref: "false",
|
109
|
-
linkref: "true", linkmention: "false")
|
110
|
-
else concept_render(node, ital: "true", ref: "true",
|
111
|
-
linkref: "true", linkmention: "false")
|
112
|
-
end
|
113
|
-
seen[term] = true if term
|
114
|
-
seen
|
115
|
-
end
|
116
|
-
|
117
|
-
def concept1_ref_content(ref)
|
118
|
-
prev = "("
|
119
|
-
foll = ")"
|
120
|
-
if ref.name == "termref"
|
121
|
-
prev, foll = @i18n.term_defined_in.split("%")
|
122
|
-
end
|
123
|
-
ref.previous = prev
|
124
|
-
ref.next = foll
|
125
|
-
end
|
126
|
-
|
127
|
-
def concept1(node)
|
128
|
-
node.replace(node&.at(ns("./renderterm"))&.children ||
|
129
|
-
node&.at(ns("./refterm"))&.children ||
|
130
|
-
node.children)
|
131
|
-
end
|
132
|
-
|
133
90
|
# we're assuming terms and clauses in the right place for display,
|
134
91
|
# to cope with multiple terms sections
|
135
92
|
def display_order(docxml)
|
@@ -145,41 +102,6 @@ module IsoDoc
|
|
145
102
|
display_order_xpath(docxml, "//indexsect", i)
|
146
103
|
end
|
147
104
|
|
148
|
-
def termdefinition1(elem)
|
149
|
-
prefix_domain_to_definition(elem)
|
150
|
-
super
|
151
|
-
end
|
152
|
-
|
153
|
-
def prefix_domain_to_definition(elem)
|
154
|
-
((d = elem.at(ns("./domain"))) &&
|
155
|
-
(v = elem.at(ns("./definition/verbal-definition"))) &&
|
156
|
-
v.elements.first.name == "p") or return
|
157
|
-
v.elements.first.children.first.previous =
|
158
|
-
"<#{to_xml(d.remove.children)}> "
|
159
|
-
end
|
160
|
-
|
161
|
-
def insertall_after_here(node, insert, name)
|
162
|
-
node.children.each do |n|
|
163
|
-
n.name == name or next
|
164
|
-
insert.next = n.remove
|
165
|
-
insert = n
|
166
|
-
end
|
167
|
-
insert
|
168
|
-
end
|
169
|
-
|
170
|
-
def termexamples_before_termnotes(node)
|
171
|
-
insert = node.at(ns("./definition")) or return
|
172
|
-
insert = insertall_after_here(node, insert, "termexample")
|
173
|
-
insertall_after_here(node, insert, "termnote")
|
174
|
-
end
|
175
|
-
|
176
|
-
def terms(docxml)
|
177
|
-
docxml.xpath(ns("//term[termnote][termexample]")).each do |node|
|
178
|
-
termexamples_before_termnotes(node)
|
179
|
-
end
|
180
|
-
super
|
181
|
-
end
|
182
|
-
|
183
105
|
def admonition1(elem)
|
184
106
|
super
|
185
107
|
n = elem.at(ns("./name")) or return
|
@@ -212,10 +134,6 @@ module IsoDoc
|
|
212
134
|
type
|
213
135
|
end
|
214
136
|
|
215
|
-
def related1(node)
|
216
|
-
node.remove
|
217
|
-
end
|
218
|
-
|
219
137
|
def note1(elem)
|
220
138
|
elem["type"] == "units" and return
|
221
139
|
super
|
@@ -237,6 +155,12 @@ module IsoDoc
|
|
237
155
|
dlist.remove
|
238
156
|
end
|
239
157
|
|
158
|
+
def toc_title(docxml)
|
159
|
+
doctype = docxml.at(ns("//bibdata/ext/doctype"))&.text
|
160
|
+
%w(amendment technical-corrigendum).include?(doctype) and return
|
161
|
+
super
|
162
|
+
end
|
163
|
+
|
240
164
|
include Init
|
241
165
|
end
|
242
166
|
end
|
data/lib/isodoc/iso/sections.rb
CHANGED
@@ -35,26 +35,26 @@ module IsoDoc
|
|
35
35
|
amd(isoxml) and @suppressheadingnumbers = true
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
38
|
+
=begin
|
39
|
+
def introduction(clause, out)
|
40
40
|
title_attr = { class: "IntroTitle" }
|
41
41
|
page_break(out)
|
42
|
-
out.div class: "Section3", id:
|
43
|
-
clause_name(
|
44
|
-
|
42
|
+
out.div class: "Section3", id: clause["id"] do |div|
|
43
|
+
clause_name(clause, clause.at(ns("./title")), div, title_attr)
|
44
|
+
clause.elements.each do |e|
|
45
45
|
parse(e, div) unless e.name == "title"
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
|
+
=end
|
49
50
|
|
50
|
-
def foreword(
|
51
|
-
f = isoxml.at(ns("//foreword")) or return
|
51
|
+
def foreword(clause, out)
|
52
52
|
@foreword = true
|
53
53
|
page_break(out)
|
54
|
-
out.div **attr_code(id:
|
55
|
-
clause_name(nil,
|
54
|
+
out.div **attr_code(id: clause["id"]) do |s|
|
55
|
+
clause_name(nil, clause.at(ns("./title")) || @i18n.foreword, s,
|
56
56
|
{ class: "ForewordTitle" })
|
57
|
-
|
57
|
+
clause.elements.each { |e| parse(e, s) unless e.name == "title" }
|
58
58
|
end
|
59
59
|
@foreword = false
|
60
60
|
end
|
@@ -142,6 +142,9 @@ module IsoDoc
|
|
142
142
|
# supply missing annex title
|
143
143
|
def make_WordToC(docxml, level)
|
144
144
|
toc = ""
|
145
|
+
if source = docxml.at("//div[@class = 'TOC']")
|
146
|
+
toc = to_xml(source.children)
|
147
|
+
end
|
145
148
|
xpath = (1..level).each.map { |i| "//h#{i}" }.join (" | ")
|
146
149
|
docxml.xpath(xpath).each do |h|
|
147
150
|
x = ""
|
data/lib/metanorma/iso/base.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
these elements; we just want one namespace for any child grammars
|
18
18
|
of this.
|
19
19
|
-->
|
20
|
+
<!-- VERSION v1.2.2 -->
|
20
21
|
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
21
22
|
<include href="reqt.rng"/>
|
22
23
|
<include href="basicdoc.rng">
|
@@ -210,6 +211,9 @@
|
|
210
211
|
<data type="boolean"/>
|
211
212
|
</attribute>
|
212
213
|
</optional>
|
214
|
+
<optional>
|
215
|
+
<attribute name="style"/>
|
216
|
+
</optional>
|
213
217
|
<ref name="CitationType"/>
|
214
218
|
<oneOrMore>
|
215
219
|
<ref name="PureTextElement"/>
|
@@ -1349,15 +1353,19 @@
|
|
1349
1353
|
</choice>
|
1350
1354
|
</element>
|
1351
1355
|
</define>
|
1356
|
+
<define name="Root-Attributes">
|
1357
|
+
<attribute name="version"/>
|
1358
|
+
<attribute name="schema-version"/>
|
1359
|
+
<attribute name="type">
|
1360
|
+
<choice>
|
1361
|
+
<value>semantic</value>
|
1362
|
+
<value>presentation</value>
|
1363
|
+
</choice>
|
1364
|
+
</attribute>
|
1365
|
+
</define>
|
1352
1366
|
<define name="standard-document">
|
1353
1367
|
<element name="standard-document">
|
1354
|
-
<
|
1355
|
-
<attribute name="type">
|
1356
|
-
<choice>
|
1357
|
-
<value>semantic</value>
|
1358
|
-
<value>presentation</value>
|
1359
|
-
</choice>
|
1360
|
-
</attribute>
|
1368
|
+
<ref name="Root-Attributes"/>
|
1361
1369
|
<ref name="bibdata"/>
|
1362
1370
|
<optional>
|
1363
1371
|
<ref name="misccontainer"/>
|
@@ -2131,6 +2139,7 @@
|
|
2131
2139
|
<choice>
|
2132
2140
|
<value>identical</value>
|
2133
2141
|
<value>modified</value>
|
2142
|
+
<value>adapted</value>
|
2134
2143
|
<value>restyled</value>
|
2135
2144
|
<value>context-added</value>
|
2136
2145
|
<value>generalisation</value>
|
@@ -1,6 +1,9 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<grammar ns="https://www.metanorma.org/ns/iso" xmlns="http://relaxng.org/ns/structure/1.0">
|
3
|
-
<!--
|
3
|
+
<!--
|
4
|
+
VERSION v1.2.1
|
5
|
+
default namespace isostandard = "https://www.metanorma.com/ns/iso"
|
6
|
+
-->
|
4
7
|
<include href="relaton-iso.rng"/>
|
5
8
|
<include href="isostandard.rng">
|
6
9
|
<start>
|
@@ -32,13 +35,7 @@
|
|
32
35
|
</define>
|
33
36
|
<define name="iso-standard">
|
34
37
|
<element name="iso-standard">
|
35
|
-
<
|
36
|
-
<attribute name="type">
|
37
|
-
<choice>
|
38
|
-
<value>semantic</value>
|
39
|
-
<value>presentation</value>
|
40
|
-
</choice>
|
41
|
-
</attribute>
|
38
|
+
<ref name="Root-Attributes"/>
|
42
39
|
<ref name="bibdata"/>
|
43
40
|
<optional>
|
44
41
|
<ref name="misccontainer"/>
|
@@ -1,6 +1,9 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
3
|
-
<!--
|
3
|
+
<!--
|
4
|
+
VERSION v1.2.1
|
5
|
+
default namespace isostandard = "https://www.metanorma.com/ns/iso"
|
6
|
+
-->
|
4
7
|
<include href="isodoc.rng">
|
5
8
|
<start>
|
6
9
|
<ref name="iso-standard"/>
|
@@ -240,13 +243,7 @@
|
|
240
243
|
-->
|
241
244
|
<define name="iso-standard">
|
242
245
|
<element name="iso-standard">
|
243
|
-
<
|
244
|
-
<attribute name="type">
|
245
|
-
<choice>
|
246
|
-
<value>semantic</value>
|
247
|
-
<value>presentation</value>
|
248
|
-
</choice>
|
249
|
-
</attribute>
|
246
|
+
<ref name="Root-Attributes"/>
|
250
247
|
<ref name="bibdata"/>
|
251
248
|
<zeroOrMore>
|
252
249
|
<ref name="termdocsource"/>
|
@@ -30,6 +30,7 @@ module Metanorma
|
|
30
30
|
# ISO/IEC DIR 2, 15.5.3, 20.2
|
31
31
|
# does not deal with preceding text marked up
|
32
32
|
def see_xrefs_validate(root)
|
33
|
+
@lang == "en" or return
|
33
34
|
root.xpath("//xref").each do |t|
|
34
35
|
preceding = t.at("./preceding-sibling::text()[last()]")
|
35
36
|
next unless !preceding.nil? &&
|
@@ -45,6 +46,7 @@ module Metanorma
|
|
45
46
|
|
46
47
|
# ISO/IEC DIR 2, 15.5.3
|
47
48
|
def see_erefs_validate(root)
|
49
|
+
@lang == "en" or return
|
48
50
|
root.xpath("//eref").each do |t|
|
49
51
|
prec = t.at("./preceding-sibling::text()[last()]")
|
50
52
|
next unless !prec.nil? && /\b(see|refer to)\s*\Z/mi.match(prec)
|
@@ -3,8 +3,9 @@ module Metanorma
|
|
3
3
|
class Converter < Standoc::Converter
|
4
4
|
# DRG directives 3.7; but anticipated by standoc
|
5
5
|
def subfigure_validate(xmldoc)
|
6
|
+
elems = { footnote: "fn", note: "note", key: "dl" }
|
6
7
|
xmldoc.xpath("//figure//figure").each do |f|
|
7
|
-
|
8
|
+
elems.each do |k, v|
|
8
9
|
f.xpath(".//#{v}").each do |n|
|
9
10
|
@log.add("Style", n, "#{k} is not permitted in a subfigure")
|
10
11
|
end
|
@@ -13,10 +14,10 @@ module Metanorma
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def image_name_prefix(xmldoc)
|
16
|
-
std = xmldoc
|
17
|
+
std = xmldoc.at("//bibdata/ext/structuredidentifier/project-number") or
|
17
18
|
return
|
18
|
-
num = xmldoc
|
19
|
-
ed = xmldoc
|
19
|
+
num = xmldoc.at("//bibdata/docnumber")&.text or return
|
20
|
+
ed = xmldoc.at("//bibdata/edition")&.text || "1"
|
20
21
|
prefix = num
|
21
22
|
std["part"] and prefix += "-#{std['part']}"
|
22
23
|
prefix += "_ed#{ed}"
|
@@ -25,7 +26,7 @@ module Metanorma
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def image_name_suffix(xmldoc)
|
28
|
-
case xmldoc
|
29
|
+
case xmldoc.at("//bibdata/language")&.text
|
29
30
|
when "fr" then "_f"
|
30
31
|
when "de" then "_d"
|
31
32
|
when "ru" then "_r"
|
@@ -60,7 +60,7 @@ module Metanorma
|
|
60
60
|
case prectext.strip[-1]
|
61
61
|
when ":", "" then list_after_colon_punctuation(list, entries)
|
62
62
|
when "." then entries.each { |li| list_full_sentence(li) }
|
63
|
-
else style_warning(list, "All lists must be preceded by "\
|
63
|
+
else style_warning(list, "All lists must be preceded by " \
|
64
64
|
"colon or full stop", prectext)
|
65
65
|
end
|
66
66
|
end
|
@@ -80,7 +80,7 @@ module Metanorma
|
|
80
80
|
def list_semicolon_phrase(elem, last)
|
81
81
|
text = elem.text.strip
|
82
82
|
starts_lowercase?(text) or
|
83
|
-
style_warning(elem, "List entry of broken up sentence must start "\
|
83
|
+
style_warning(elem, "List entry of broken up sentence must start " \
|
84
84
|
"with lowercase letter", text)
|
85
85
|
list_semicolon_phrase_punct(elem, text, last)
|
86
86
|
end
|
@@ -89,11 +89,11 @@ module Metanorma
|
|
89
89
|
punct = text.strip.sub(/^.*?(\S)$/m, "\\1")
|
90
90
|
if last
|
91
91
|
punct == "." or
|
92
|
-
style_warning(elem, "Final list entry of broken up "\
|
92
|
+
style_warning(elem, "Final list entry of broken up " \
|
93
93
|
"sentence must end with full stop", text)
|
94
94
|
else
|
95
95
|
punct == ";" or
|
96
|
-
style_warning(elem, "List entry of broken up sentence must "\
|
96
|
+
style_warning(elem, "List entry of broken up sentence must " \
|
97
97
|
"end with semicolon", text)
|
98
98
|
end
|
99
99
|
end
|
@@ -102,11 +102,11 @@ module Metanorma
|
|
102
102
|
%w(Cyrl Latn Grek).include?(@script) or return
|
103
103
|
text = elem.text.strip
|
104
104
|
starts_uppercase?(text) or
|
105
|
-
style_warning(elem, "List entry of separate sentences must start "\
|
105
|
+
style_warning(elem, "List entry of separate sentences must start " \
|
106
106
|
"with uppercase letter", text)
|
107
107
|
punct = text.strip.sub(/^.*?(\S)$/m, "\\1")
|
108
108
|
punct == "." or
|
109
|
-
style_warning(elem, "List entry of separate sentences must "\
|
109
|
+
style_warning(elem, "List entry of separate sentences must " \
|
110
110
|
"end with full stop", text)
|
111
111
|
end
|
112
112
|
|
@@ -24,6 +24,7 @@ module Metanorma
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def requirement_check(text)
|
27
|
+
@lang == "en" or return
|
27
28
|
text.split(/\.\s+/).each do |t|
|
28
29
|
return t if requirement_re.match t
|
29
30
|
end
|
@@ -44,6 +45,7 @@ module Metanorma
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def recommendation_check(text)
|
48
|
+
@lang == "en" or return
|
47
49
|
text.split(/\.\s+/).each do |t|
|
48
50
|
return t if recommendation_re.match t
|
49
51
|
end
|
@@ -60,6 +62,7 @@ module Metanorma
|
|
60
62
|
REGEXP
|
61
63
|
|
62
64
|
def permission_re
|
65
|
+
@lang == "en" or return
|
63
66
|
Regexp.new(self.class::PERMISSION_RE_STR.gsub(/\s/, "")
|
64
67
|
.gsub(/_/, "\\s"), Regexp::IGNORECASE)
|
65
68
|
end
|
@@ -82,6 +85,7 @@ module Metanorma
|
|
82
85
|
REGEXP
|
83
86
|
|
84
87
|
def possibility_re
|
88
|
+
@lang == "en" or return
|
85
89
|
Regexp.new(self.class::POSSIBILITY_RE_STR.gsub(/\s/, "")
|
86
90
|
.gsub(/_/, "\\s"), Regexp::IGNORECASE)
|
87
91
|
end
|
@@ -98,6 +102,26 @@ module Metanorma
|
|
98
102
|
nil
|
99
103
|
end
|
100
104
|
|
105
|
+
AMBIG_WORDS_RE_STR = <<~REGEXP.freeze
|
106
|
+
\\b
|
107
|
+
need_to | needs_to | might | could
|
108
|
+
\\b
|
109
|
+
REGEXP
|
110
|
+
|
111
|
+
def ambig_words_re
|
112
|
+
@lang == "en" or return
|
113
|
+
Regexp.new(self.class::AMBIG_WORDS_RE_STR.gsub(/\s/, "")
|
114
|
+
.gsub(/_/, "\\s"), Regexp::IGNORECASE)
|
115
|
+
end
|
116
|
+
|
117
|
+
def ambig_words_check(text)
|
118
|
+
@lang == "en" or return
|
119
|
+
text.split(/\.\s+/).each do |t|
|
120
|
+
return t if ambig_words_re.match t
|
121
|
+
end
|
122
|
+
nil
|
123
|
+
end
|
124
|
+
|
101
125
|
def style_no_guidance(node, text, docpart)
|
102
126
|
@lang == "en" or return
|
103
127
|
r = requirement_check(text)
|
@@ -90,32 +90,63 @@ module Metanorma
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def style(node, text)
|
93
|
-
|
94
|
-
|
93
|
+
@novalid and return
|
95
94
|
style_number(node, text)
|
96
95
|
style_percent(node, text)
|
97
96
|
style_abbrev(node, text)
|
98
97
|
style_units(node, text)
|
99
98
|
style_punct(node, text)
|
99
|
+
style_subscript(node)
|
100
|
+
style_ambig_words(node, text)
|
101
|
+
end
|
102
|
+
|
103
|
+
# https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-s-quantity
|
104
|
+
def style_subscript(node)
|
105
|
+
warning = "may contain nested subscripts (max 3 levels allowed)"
|
106
|
+
node.xpath(".//sub[.//sub]").each do |x|
|
107
|
+
style_warning(node, warning, x.to_xml)
|
108
|
+
end
|
109
|
+
node.xpath(".//m:msub[.//m:msub]", "m" => MATHML_NS).each do |x|
|
110
|
+
style_warning(node, warning, x.to_xml)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-s-need
|
115
|
+
# https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-s-might
|
116
|
+
def style_ambig_words(node, text)
|
117
|
+
r = ambig_words_check(text) and
|
118
|
+
style_warning(node, "may contain ambiguous provision", r)
|
100
119
|
end
|
101
120
|
|
102
121
|
# ISO/IEC DIR 2, 9.1
|
103
122
|
# ISO/IEC DIR 2, Table B.1
|
104
123
|
# https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-n-numbers
|
105
124
|
def style_number(node, text)
|
106
|
-
|
107
|
-
node, text, /^(?<num>-?[0-9]{4,}[,0-9]*)\Z/,
|
108
|
-
%r{\b(ISO|IEC|IEEE/|(in|January|February|March|April|May|June|August|September|October|November|December)\b)\Z},
|
109
|
-
"number not broken up in threes"
|
110
|
-
)
|
125
|
+
style_number_grouping(node, text)
|
111
126
|
style_regex(/\b(?<num>[0-9]+\.[0-9]+)/i,
|
112
127
|
"possible decimal point", node, text)
|
113
128
|
@lang == "en" and style_regex(/\b(?<num>billions?)\b/i,
|
114
129
|
"ambiguous number", node, text)
|
115
|
-
style_regex(/(
|
130
|
+
style_regex(/(?:^|\s)(?<num>-[0-9][0-9,.]*)/i,
|
116
131
|
"hyphen instead of minus sign U+2212", node, text)
|
117
132
|
end
|
118
133
|
|
134
|
+
def style_number_grouping(node, text)
|
135
|
+
if @validate_years
|
136
|
+
style_two_regex_not_prev(
|
137
|
+
node, text, /^(?<num>-?[0-9]{4,}[,0-9]*)\Z/,
|
138
|
+
%r{\b(ISO|IEC|IEEE|(in|January|February|March|April|May|June|August|September|October|November|December)\b)\Z},
|
139
|
+
"number not broken up in threes"
|
140
|
+
)
|
141
|
+
else
|
142
|
+
style_two_regex_not_prev(
|
143
|
+
node, text, /^(?<num>-?(?:[0-9]{5,}[,0-9]*|[03-9]\d\d\d|1[0-8]\d\d|2[1-9]\d\d|20[5-9]\d))\Z/,
|
144
|
+
%r{\b(ISO|IEC|IEEE|\b)\Z},
|
145
|
+
"number not broken up in threes"
|
146
|
+
)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
119
150
|
# ISO/IEC DIR 2, 9.2.1
|
120
151
|
def style_percent(node, text)
|
121
152
|
style_regex(/\b(?<num>[0-9.,]+%)/,
|
@@ -169,6 +200,16 @@ module Metanorma
|
|
169
200
|
"Use 'either x or y, or both'", node, text)
|
170
201
|
style_regex(/\s(?<num>&)\s/i,
|
171
202
|
"Avoid ampersand in ordinary text'", node, text)
|
203
|
+
eref_style_punct(node)
|
204
|
+
end
|
205
|
+
|
206
|
+
# https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-r-ref_unnumbered
|
207
|
+
def eref_style_punct(node)
|
208
|
+
node.xpath(".//eref[@type='footnote']").each do |e|
|
209
|
+
/^\p{P}/.match?(e.next&.text) or next
|
210
|
+
style_warning(node, "superscript cross-reference followed by punctuation",
|
211
|
+
node.to_xml)
|
212
|
+
end
|
172
213
|
end
|
173
214
|
|
174
215
|
def style_warning(node, msg, text = nil)
|
data/metanorma-iso.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.test_files = `git ls-files -- {spec}/*`.split("\n")
|
33
33
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
|
34
34
|
|
35
|
-
spec.add_dependency "metanorma-standoc", "~> 2.4.
|
35
|
+
spec.add_dependency "metanorma-standoc", "~> 2.4.3"
|
36
36
|
spec.add_dependency "mnconvert", "~> 1.14"
|
37
37
|
spec.add_dependency "pubid-iso", "~> 0.5.0"
|
38
38
|
spec.add_dependency "ruby-jing"
|