metanorma-iso 2.4.2 → 2.4.4
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/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"
|