metanorma-iso 1.10.5 → 2.0.2
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/.github/workflows/rake.yml +3 -33
- data/.gitignore +26 -0
- data/Makefile +1 -1
- data/lib/asciidoctor/iso/base.rb +2 -69
- data/lib/asciidoctor/iso/cleanup.rb +2 -175
- data/lib/asciidoctor/iso/converter.rb +2 -17
- data/lib/asciidoctor/iso/deprecated.rb +5 -0
- data/lib/asciidoctor/iso/front.rb +2 -169
- data/lib/asciidoctor/iso/front_id.rb +2 -224
- data/lib/asciidoctor/iso/section.rb +2 -48
- data/lib/asciidoctor/iso/validate.rb +2 -171
- data/lib/asciidoctor/iso/validate_image.rb +2 -96
- data/lib/asciidoctor/iso/validate_requirements.rb +2 -110
- data/lib/asciidoctor/iso/validate_section.rb +2 -246
- data/lib/asciidoctor/iso/validate_style.rb +2 -169
- data/lib/asciidoctor/iso/validate_title.rb +2 -104
- data/lib/isodoc/iso/html/style-human.css +19 -14
- data/lib/isodoc/iso/html/style-human.scss +8 -2
- data/lib/isodoc/iso/html/style-iso.css +21 -15
- data/lib/isodoc/iso/html/style-iso.scss +9 -2
- data/lib/isodoc/iso/html_convert.rb +6 -4
- data/lib/isodoc/iso/iso.amendment.xsl +1449 -1222
- data/lib/isodoc/iso/iso.international-standard.xsl +1449 -1222
- data/lib/isodoc/iso/word_convert.rb +2 -0
- data/lib/metanorma/iso/base.rb +70 -0
- data/lib/{asciidoctor → metanorma}/iso/basicdoc.rng +0 -0
- data/lib/{asciidoctor → metanorma}/iso/biblio.rng +2 -2
- data/lib/{asciidoctor → metanorma}/iso/boilerplate-fr.xml +0 -0
- data/lib/{asciidoctor → metanorma}/iso/boilerplate.xml +0 -0
- data/lib/metanorma/iso/cleanup.rb +176 -0
- data/lib/metanorma/iso/converter.rb +18 -0
- data/lib/metanorma/iso/front.rb +170 -0
- data/lib/metanorma/iso/front_id.rb +225 -0
- data/lib/{asciidoctor → metanorma}/iso/isodoc.rng +98 -1
- data/lib/{asciidoctor → metanorma}/iso/isostandard-amd.rng +0 -0
- data/lib/{asciidoctor → metanorma}/iso/isostandard.rnc +0 -0
- data/lib/{asciidoctor → metanorma}/iso/isostandard.rng +0 -0
- data/lib/{asciidoctor → metanorma}/iso/reqt.rng +0 -0
- data/lib/metanorma/iso/section.rb +49 -0
- data/lib/metanorma/iso/validate.rb +172 -0
- data/lib/metanorma/iso/validate_image.rb +97 -0
- data/lib/metanorma/iso/validate_requirements.rb +111 -0
- data/lib/metanorma/iso/validate_section.rb +247 -0
- data/lib/metanorma/iso/validate_style.rb +170 -0
- data/lib/metanorma/iso/validate_title.rb +105 -0
- data/lib/metanorma/iso/version.rb +1 -1
- data/lib/metanorma-iso.rb +1 -1
- data/metanorma-iso.gemspec +2 -2
- data/spec/isodoc/ref_spec.rb +4 -2
- data/spec/isodoc/section_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/amd_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/base_spec.rb +141 -130
- data/spec/{asciidoctor → metanorma}/blank_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/blocks_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/cleanup_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/inline_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/lists_spec.rb +1 -1
- data/spec/metanorma/processor_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/refs_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/section_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/table_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/validate_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/vcr_cassettes/docrels.yml +21 -216
- metadata +39 -26
@@ -1,247 +1,3 @@
|
|
1
|
-
require "
|
1
|
+
require "asciidoctor/iso/deprecated"
|
2
|
+
require "metanorma/iso/validate_section"
|
2
3
|
|
3
|
-
module Asciidoctor
|
4
|
-
module ISO
|
5
|
-
class Converter < Standoc::Converter
|
6
|
-
def section_validate(doc)
|
7
|
-
doctype = doc&.at("//bibdata/ext/doctype")&.text
|
8
|
-
unless %w(amendment technical-corrigendum).include? doctype
|
9
|
-
foreword_validate(doc.root)
|
10
|
-
normref_validate(doc.root)
|
11
|
-
symbols_validate(doc.root)
|
12
|
-
sections_presence_validate(doc.root)
|
13
|
-
sections_sequence_validate(doc.root)
|
14
|
-
end
|
15
|
-
section_style(doc.root)
|
16
|
-
subclause_validate(doc.root)
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
|
-
# ISO/IEC DIR 2, 12.4
|
21
|
-
def foreword_validate(root)
|
22
|
-
f = root.at("//foreword") || return
|
23
|
-
s = f.at("./clause")
|
24
|
-
@log.add("Style", f, "foreword contains subclauses") unless s.nil?
|
25
|
-
end
|
26
|
-
|
27
|
-
# ISO/IEC DIR 2, 15.4
|
28
|
-
def normref_validate(root)
|
29
|
-
f = root.at("//references[@normative = 'true']") || return
|
30
|
-
f.at("./references | ./clause") &&
|
31
|
-
@log.add("Style", f, "normative references contains subclauses")
|
32
|
-
end
|
33
|
-
|
34
|
-
ONE_SYMBOLS_WARNING = "Only one Symbols and Abbreviated "\
|
35
|
-
"Terms section in the standard".freeze
|
36
|
-
|
37
|
-
NON_DL_SYMBOLS_WARNING = "Symbols and Abbreviated Terms can "\
|
38
|
-
"only contain a definition list".freeze
|
39
|
-
|
40
|
-
def symbols_validate(root)
|
41
|
-
f = root.xpath("//definitions")
|
42
|
-
f.empty? && return
|
43
|
-
(f.size == 1) || @log.add("Style", f.first, ONE_SYMBOLS_WARNING)
|
44
|
-
f.first.elements.each do |e|
|
45
|
-
unless %w(title dl).include? e.name
|
46
|
-
@log.add("Style", f.first, NON_DL_SYMBOLS_WARNING)
|
47
|
-
return
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def seqcheck(names, msg, accepted)
|
53
|
-
n = names.shift
|
54
|
-
return [] if n.nil?
|
55
|
-
|
56
|
-
test = accepted.map { |a| n.at(a) }
|
57
|
-
if test.all?(&:nil?)
|
58
|
-
@log.add("Style", nil, msg)
|
59
|
-
end
|
60
|
-
names
|
61
|
-
end
|
62
|
-
|
63
|
-
def sections_presence_validate(root)
|
64
|
-
root.at("//sections/clause[@type = 'scope']") or
|
65
|
-
@log.add("Style", nil, "Scope clause missing")
|
66
|
-
root.at("//references[@normative = 'true']") or
|
67
|
-
@log.add("Style", nil, "Normative references missing")
|
68
|
-
root.at("//terms") or
|
69
|
-
@log.add("Style", nil, "Terms & definitions missing")
|
70
|
-
end
|
71
|
-
|
72
|
-
# spec of permissible section sequence
|
73
|
-
# we skip normative references, it goes to end of list
|
74
|
-
SEQ =
|
75
|
-
[
|
76
|
-
{
|
77
|
-
msg: "Initial section must be (content) Foreword",
|
78
|
-
val: ["./self::foreword"],
|
79
|
-
},
|
80
|
-
{
|
81
|
-
msg: "Prefatory material must be followed by (clause) Scope",
|
82
|
-
val: ["./self::introduction", "./self::clause[@type = 'scope']"],
|
83
|
-
},
|
84
|
-
{
|
85
|
-
msg: "Prefatory material must be followed by (clause) Scope",
|
86
|
-
val: ["./self::clause[@type = 'scope']"],
|
87
|
-
},
|
88
|
-
{
|
89
|
-
msg: "Normative References must be followed by "\
|
90
|
-
"Terms and Definitions",
|
91
|
-
val: ["./self::terms | .//terms"],
|
92
|
-
},
|
93
|
-
].freeze
|
94
|
-
|
95
|
-
SECTIONS_XPATH =
|
96
|
-
"//foreword | //introduction | //sections/terms | .//annex | "\
|
97
|
-
"//sections/definitions | //sections/clause | "\
|
98
|
-
"//references[not(parent::clause)] | "\
|
99
|
-
"//clause[descendant::references][not(parent::clause)]".freeze
|
100
|
-
|
101
|
-
def sections_sequence_validate(root)
|
102
|
-
names, n = sections_sequence_validate_start(root)
|
103
|
-
if root&.at("//bibdata/ext/subdoctype")&.text == "vocabulary"
|
104
|
-
names, n = sections_sequence_validate_body_vocab(names, n)
|
105
|
-
else
|
106
|
-
names, n = sections_sequence_validate_body(names, n)
|
107
|
-
end
|
108
|
-
sections_sequence_validate_end(names, n)
|
109
|
-
end
|
110
|
-
|
111
|
-
def sections_sequence_validate_start(root)
|
112
|
-
names = root.xpath(SECTIONS_XPATH)
|
113
|
-
names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val])
|
114
|
-
n = names[0]
|
115
|
-
names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val])
|
116
|
-
n&.at("./self::introduction") and
|
117
|
-
names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val])
|
118
|
-
names = seqcheck(names, SEQ[3][:msg], SEQ[3][:val])
|
119
|
-
n = names.shift
|
120
|
-
n = names.shift if n&.at("./self::definitions")
|
121
|
-
[names, n]
|
122
|
-
end
|
123
|
-
|
124
|
-
def sections_sequence_validate_body(names, elem)
|
125
|
-
if elem.nil? || elem.name != "clause"
|
126
|
-
@log.add("Style", elem, "Document must contain at least one clause")
|
127
|
-
end
|
128
|
-
elem&.at("./self::clause") ||
|
129
|
-
@log.add("Style", elem, "Document must contain clause after "\
|
130
|
-
"Terms and Definitions")
|
131
|
-
elem&.at("./self::clause[@type = 'scope']") &&
|
132
|
-
@log.add("Style", elem,
|
133
|
-
"Scope must occur before Terms and Definitions")
|
134
|
-
elem = names.shift
|
135
|
-
while elem&.name == "clause"
|
136
|
-
elem&.at("./self::clause[@type = 'scope']")
|
137
|
-
@log.add("Style", elem,
|
138
|
-
"Scope must occur before Terms and Definitions")
|
139
|
-
elem = names.shift
|
140
|
-
end
|
141
|
-
%w(annex references).include? elem&.name or
|
142
|
-
@log.add("Style", elem,
|
143
|
-
"Only annexes and references can follow clauses")
|
144
|
-
[names, elem]
|
145
|
-
end
|
146
|
-
|
147
|
-
def sections_sequence_validate_body_vocab(names, elem)
|
148
|
-
while elem && %w(clause terms).include?(elem.name)
|
149
|
-
elem = names.shift
|
150
|
-
end
|
151
|
-
%w(annex references).include? elem&.name or
|
152
|
-
@log.add("Style", elem,
|
153
|
-
"Only annexes and references can follow terms and clauses")
|
154
|
-
[names, elem]
|
155
|
-
end
|
156
|
-
|
157
|
-
def sections_sequence_validate_end(names, elem)
|
158
|
-
while elem&.name == "annex"
|
159
|
-
elem = names.shift
|
160
|
-
if elem.nil?
|
161
|
-
@log.add("Style", nil, "Document must include (references) "\
|
162
|
-
"Normative References")
|
163
|
-
end
|
164
|
-
end
|
165
|
-
elem&.at("./self::references[@normative = 'true']") ||
|
166
|
-
@log.add("Style", nil, "Document must include (references) "\
|
167
|
-
"Normative References")
|
168
|
-
elem = names&.shift
|
169
|
-
elem&.at("./self::references[@normative = 'false']") ||
|
170
|
-
@log.add("Style", elem,
|
171
|
-
"Final section must be (references) Bibliography")
|
172
|
-
names.empty? ||
|
173
|
-
@log.add("Style", elem,
|
174
|
-
"There are sections after the final Bibliography")
|
175
|
-
end
|
176
|
-
|
177
|
-
NORM_ISO_WARN = "non-ISO/IEC reference not expected as normative".freeze
|
178
|
-
SCOPE_WARN = "Scope contains subclauses: should be succinct".freeze
|
179
|
-
|
180
|
-
def section_style(root)
|
181
|
-
foreword_style(root.at("//foreword"))
|
182
|
-
introduction_style(root.at("//introduction"))
|
183
|
-
scope_style(root.at("//clause[@type = 'scope']"))
|
184
|
-
scope = root.at("//clause[@type = 'scope']/clause")
|
185
|
-
# ISO/IEC DIR 2, 14.4
|
186
|
-
scope.nil? || style_warning(scope, SCOPE_WARN, nil)
|
187
|
-
tech_report_style(root)
|
188
|
-
end
|
189
|
-
|
190
|
-
def tech_report_style(root)
|
191
|
-
root.at("//bibdata/ext/doctype")&.text == "technical-report" or return
|
192
|
-
root.xpath("//sections/clause[not(@type = 'scope')] | //annex")
|
193
|
-
.each do |s|
|
194
|
-
r = requirement_check(extract_text(s)) and
|
195
|
-
style_warning(s,
|
196
|
-
"Technical Report clause may contain requirement", r)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
ASSETS_TO_STYLE =
|
201
|
-
"//termsource | //formula | //termnote | "\
|
202
|
-
"//p[not(ancestor::boilerplate)] | //li[not(p)] | //dt | "\
|
203
|
-
"//dd[not(p)] | //td[not(p)] | //th[not(p)]".freeze
|
204
|
-
|
205
|
-
NORM_BIBITEMS =
|
206
|
-
"//references[@normative = 'true']/bibitem".freeze
|
207
|
-
|
208
|
-
# ISO/IEC DIR 2, 10.2
|
209
|
-
def norm_bibitem_style(root)
|
210
|
-
root.xpath(NORM_BIBITEMS).each do |b|
|
211
|
-
if b.at(Standoc::Converter::ISO_PUBLISHER_XPATH).nil?
|
212
|
-
@log.add("Style", b, "#{NORM_ISO_WARN}: #{b.text}")
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def asset_style(root)
|
218
|
-
root.xpath("//example | //termexample").each { |e| example_style(e) }
|
219
|
-
root.xpath("//definition/verbal-definition").each { |e| definition_style(e) }
|
220
|
-
root.xpath("//note").each { |e| note_style(e) }
|
221
|
-
root.xpath("//fn").each { |e| footnote_style(e) }
|
222
|
-
root.xpath(ASSETS_TO_STYLE).each { |e| style(e, extract_text(e)) }
|
223
|
-
norm_bibitem_style(root)
|
224
|
-
super
|
225
|
-
end
|
226
|
-
|
227
|
-
def subclause_validate(root)
|
228
|
-
root.xpath("//clause/clause/clause/clause/clause/clause/clause/clause")
|
229
|
-
.each do |c|
|
230
|
-
style_warning(c, "Exceeds the maximum clause depth of 7", nil)
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
# ISO/IEC DIR 2, 22.3.2
|
235
|
-
def onlychild_clause_validate(root)
|
236
|
-
root.xpath(Standoc::Utils::SUBCLAUSE_XPATH).each do |c|
|
237
|
-
next unless c.xpath("../clause").size == 1
|
238
|
-
|
239
|
-
title = c.at("./title")
|
240
|
-
location = c["id"] || "#{c.text[0..60]}..."
|
241
|
-
location += ":#{title.text}" if c["id"] && !title.nil?
|
242
|
-
@log.add("Style", nil, "#{location}: subclause is only child")
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
@@ -1,170 +1,3 @@
|
|
1
|
-
require "
|
2
|
-
require "
|
3
|
-
require "tokenizer"
|
1
|
+
require "asciidoctor/iso/deprecated"
|
2
|
+
require "metanorma/iso/validate_style"
|
4
3
|
|
5
|
-
module Asciidoctor
|
6
|
-
module ISO
|
7
|
-
class Converter < Standoc::Converter
|
8
|
-
def extract_text(node)
|
9
|
-
return "" if node.nil?
|
10
|
-
|
11
|
-
node1 = Nokogiri::XML.fragment(node.to_s)
|
12
|
-
node1.xpath("//link | //locality | //localityStack").each(&:remove)
|
13
|
-
ret = ""
|
14
|
-
node1.traverse { |x| ret += x.text if x.text? }
|
15
|
-
HTMLEntities.new.decode(ret)
|
16
|
-
end
|
17
|
-
|
18
|
-
# ISO/IEC DIR 2, 12.2
|
19
|
-
def foreword_style(node)
|
20
|
-
return if @novalid
|
21
|
-
|
22
|
-
style_no_guidance(node, extract_text(node), "Foreword")
|
23
|
-
end
|
24
|
-
|
25
|
-
# ISO/IEC DIR 2, 14.2
|
26
|
-
def scope_style(node)
|
27
|
-
return if @novalid
|
28
|
-
|
29
|
-
style_no_guidance(node, extract_text(node), "Scope")
|
30
|
-
end
|
31
|
-
|
32
|
-
# ISO/IEC DIR 2, 13.2
|
33
|
-
def introduction_style(node)
|
34
|
-
return if @novalid
|
35
|
-
|
36
|
-
r = requirement_check(extract_text(node))
|
37
|
-
style_warning(node, "Introduction may contain requirement", r) if r
|
38
|
-
end
|
39
|
-
|
40
|
-
# ISO/IEC DIR 2, 16.5.6
|
41
|
-
def definition_style(node)
|
42
|
-
return if @novalid
|
43
|
-
|
44
|
-
r = requirement_check(extract_text(node))
|
45
|
-
style_warning(node, "Definition may contain requirement", r) if r
|
46
|
-
end
|
47
|
-
|
48
|
-
# ISO/IEC DIR 2, 16.5.7
|
49
|
-
# ISO/IEC DIR 2, 25.5
|
50
|
-
def example_style(node)
|
51
|
-
return if @novalid
|
52
|
-
|
53
|
-
style_no_guidance(node, extract_text(node), "Example")
|
54
|
-
style(node, extract_text(node))
|
55
|
-
end
|
56
|
-
|
57
|
-
# ISO/IEC DIR 2, 24.5
|
58
|
-
def note_style(node)
|
59
|
-
return if @novalid
|
60
|
-
|
61
|
-
style_no_guidance(node, extract_text(node), "Note")
|
62
|
-
style(node, extract_text(node))
|
63
|
-
end
|
64
|
-
|
65
|
-
# ISO/IEC DIR 2, 26.5
|
66
|
-
def footnote_style(node)
|
67
|
-
return if @novalid
|
68
|
-
|
69
|
-
style_no_guidance(node, extract_text(node), "Footnote")
|
70
|
-
style(node, extract_text(node))
|
71
|
-
end
|
72
|
-
|
73
|
-
def style_regex(regex, warning, n, text)
|
74
|
-
(m = regex.match(text)) && style_warning(n, warning, m[:num])
|
75
|
-
end
|
76
|
-
|
77
|
-
# style check with a regex on a token
|
78
|
-
# and a negative match on its preceding token
|
79
|
-
def style_two_regex_not_prev(n, text, regex, re_prev, warning)
|
80
|
-
return if text.nil?
|
81
|
-
|
82
|
-
arr = Tokenizer::WhitespaceTokenizer.new.tokenize(text)
|
83
|
-
arr.each_index do |i|
|
84
|
-
m = regex.match arr[i]
|
85
|
-
m_prev = i.zero? ? nil : re_prev.match(arr[i - 1])
|
86
|
-
if !m.nil? && m_prev.nil?
|
87
|
-
style_warning(n, warning, m[:num])
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def style(node, text)
|
93
|
-
return if @novalid
|
94
|
-
|
95
|
-
style_number(node, text)
|
96
|
-
style_percent(node, text)
|
97
|
-
style_abbrev(node, text)
|
98
|
-
style_units(node, text)
|
99
|
-
end
|
100
|
-
|
101
|
-
# ISO/IEC DIR 2, 9.1
|
102
|
-
# ISO/IEC DIR 2, Table B.1
|
103
|
-
def style_number(node, text)
|
104
|
-
style_two_regex_not_prev(
|
105
|
-
node, text, /^(?<num>-?[0-9]{4,}[,0-9]*)\Z/,
|
106
|
-
%r{\b(ISO|IEC|IEEE/|(in|January|February|March|April|May|June|August|September|October|November|December)\b)\Z},
|
107
|
-
"number not broken up in threes"
|
108
|
-
)
|
109
|
-
style_regex(/\b(?<num>[0-9]+\.[0-9]+)/i,
|
110
|
-
"possible decimal point", node, text)
|
111
|
-
style_regex(/\b(?<num>billions?)\b/i,
|
112
|
-
"ambiguous number", node, text)
|
113
|
-
end
|
114
|
-
|
115
|
-
# ISO/IEC DIR 2, 9.2.1
|
116
|
-
def style_percent(node, text)
|
117
|
-
style_regex(/\b(?<num>[0-9.,]+%)/,
|
118
|
-
"no space before percent sign", node, text)
|
119
|
-
style_regex(/\b(?<num>[0-9.,]+ \u00b1 [0-9,.]+ %)/,
|
120
|
-
"unbracketed tolerance before percent sign", node, text)
|
121
|
-
end
|
122
|
-
|
123
|
-
# ISO/IEC DIR 2, 8.4
|
124
|
-
# ISO/IEC DIR 2, 9.3
|
125
|
-
def style_abbrev(node, text)
|
126
|
-
style_regex(/(\A|\s)(?!e\.g\.|i\.e\.)
|
127
|
-
(?<num>[a-z]{1,2}\.([a-z]{1,2}|\.))\b/ix,
|
128
|
-
"no dots in abbreviations", node, text)
|
129
|
-
style_regex(/\b(?<num>ppm)\b/i,
|
130
|
-
"language-specific abbreviation", node, text)
|
131
|
-
end
|
132
|
-
|
133
|
-
# leaving out as problematic: N J K C S T H h d B o E
|
134
|
-
SI_UNIT = "(m|cm|mm|km|μm|nm|g|kg|mgmol|cd|rad|sr|Hz|Hz|MHz|Pa|hPa|kJ|"\
|
135
|
-
"V|kV|W|MW|kW|F|μF|Ω|Wb|°C|lm|lx|Bq|Gy|Sv|kat|l|t|eV|u|Np|Bd|"\
|
136
|
-
"bit|kB|MB|Hart|nat|Sh|var)".freeze
|
137
|
-
|
138
|
-
# ISO/IEC DIR 2, 9.3
|
139
|
-
def style_units(node, text)
|
140
|
-
style_regex(/\b(?<num>[0-9][0-9,]*\s+[\u00b0\u2032\u2033])/,
|
141
|
-
"space between number and degrees/minutes/seconds",
|
142
|
-
node, text)
|
143
|
-
style_regex(/\b(?<num>[0-9][0-9,]*#{SI_UNIT})\b/o,
|
144
|
-
"no space between number and SI unit", node, text)
|
145
|
-
style_non_std_units(node, text)
|
146
|
-
end
|
147
|
-
|
148
|
-
NONSTD_UNITS = {
|
149
|
-
sec: "s", mins: "min", hrs: "h", hr: "h", cc: "cm^3",
|
150
|
-
lit: "l", amp: "A", amps: "A", rpm: "r/min"
|
151
|
-
}.freeze
|
152
|
-
|
153
|
-
# ISO/IEC DIR 2, 9.3
|
154
|
-
def style_non_std_units(node, text)
|
155
|
-
NONSTD_UNITS.each do |k, v|
|
156
|
-
style_regex(/\b(?<num>[0-9][0-9,]*\s+#{k})\b/,
|
157
|
-
"non-standard unit (should be #{v})", node, text)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def style_warning(node, msg, text = nil)
|
162
|
-
return if @novalid
|
163
|
-
|
164
|
-
w = msg
|
165
|
-
w += ": #{text}" if text
|
166
|
-
@log.add("Style", node, w)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
@@ -1,105 +1,3 @@
|
|
1
|
-
require "
|
1
|
+
require "asciidoctor/iso/deprecated"
|
2
|
+
require "metanorma/iso/validate_title"
|
2
3
|
|
3
|
-
module Asciidoctor
|
4
|
-
module ISO
|
5
|
-
class Converter < Standoc::Converter
|
6
|
-
def title_lang_part(doc, part, lang)
|
7
|
-
doc.at("//bibdata/title[@type='title-#{part}' and @language='#{lang}']")
|
8
|
-
end
|
9
|
-
|
10
|
-
def title_intro_validate(root)
|
11
|
-
title_intro_en = title_lang_part(root, "intro", "en")
|
12
|
-
title_intro_fr = title_lang_part(root, "intro", "fr")
|
13
|
-
if title_intro_en.nil? && !title_intro_fr.nil?
|
14
|
-
@log.add("Style", title_intro_fr, "No English Title Intro!")
|
15
|
-
end
|
16
|
-
if !title_intro_en.nil? && title_intro_fr.nil?
|
17
|
-
@log.add("Style", title_intro_en, "No French Title Intro!")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def title_main_validate(root)
|
22
|
-
title_main_en = title_lang_part(root, "main", "en")
|
23
|
-
title_main_fr = title_lang_part(root, "main", "fr")
|
24
|
-
if title_main_en.nil? && !title_main_fr.nil?
|
25
|
-
@log.add("Style", title_main_fr, "No English Title!")
|
26
|
-
end
|
27
|
-
if !title_main_en.nil? && title_main_fr.nil?
|
28
|
-
@log.add("Style", title_main_en, "No French Title!")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def title_part_validate(root)
|
33
|
-
title_part_en = title_lang_part(root, "part", "en")
|
34
|
-
title_part_fr = title_lang_part(root, "part", "fr")
|
35
|
-
(title_part_en.nil? && !title_part_fr.nil?) &&
|
36
|
-
@log.add("Style", title_part_fr, "No English Title Part!")
|
37
|
-
(!title_part_en.nil? && title_part_fr.nil?) &&
|
38
|
-
@log.add("Style", title_part_en, "No French Title Part!")
|
39
|
-
end
|
40
|
-
|
41
|
-
# ISO/IEC DIR 2, 11.4
|
42
|
-
def title_subpart_validate(root)
|
43
|
-
docid = root.at("//bibdata/docidentifier[@type = 'ISO']")
|
44
|
-
subpart = /-\d+-\d+/.match docid
|
45
|
-
iec = root.at("//bibdata/contributor[role/@type = 'publisher']/"\
|
46
|
-
"organization[abbreviation = 'IEC' or "\
|
47
|
-
"name = 'International Electrotechnical Commission']")
|
48
|
-
subpart && !iec and
|
49
|
-
@log.add("Style", docid, "Subpart defined on non-IEC document!")
|
50
|
-
end
|
51
|
-
|
52
|
-
# ISO/IEC DIR 2, 11.5.2
|
53
|
-
def title_names_type_validate(root)
|
54
|
-
doctypes = /International\sStandard | Technical\sSpecification |
|
55
|
-
Publicly\sAvailable\sSpecification | Technical\sReport | Guide /xi
|
56
|
-
title_main_en = title_lang_part(root, "main", "en")
|
57
|
-
!title_main_en.nil? && doctypes.match(title_main_en.text) and
|
58
|
-
@log.add("Style", title_main_en, "Main Title may name document type")
|
59
|
-
title_intro_en = title_lang_part(root, "intro", "en")
|
60
|
-
!title_intro_en.nil? && doctypes.match(title_intro_en.text) and
|
61
|
-
@log.add("Style", title_intro_en,
|
62
|
-
"Title Intro may name document type")
|
63
|
-
end
|
64
|
-
|
65
|
-
# ISO/IEC DIR 2, 22.2
|
66
|
-
def title_first_level_validate(root)
|
67
|
-
root.xpath(SECTIONS_XPATH).each do |s|
|
68
|
-
title = s&.at("./title")&.text || s.name
|
69
|
-
s.xpath("./clause | ./terms | ./references").each do |ss|
|
70
|
-
subtitle = ss.at("./title")
|
71
|
-
!subtitle.nil? && !subtitle&.text&.empty? or
|
72
|
-
@log.add("Style", ss,
|
73
|
-
"#{title}: each first-level subclause must have a title")
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# ISO/IEC DIR 2, 22.2
|
79
|
-
def title_all_siblings(xpath, label)
|
80
|
-
notitle = false
|
81
|
-
withtitle = false
|
82
|
-
xpath.each do |s|
|
83
|
-
title_all_siblings(s.xpath("./clause | ./terms | ./references"),
|
84
|
-
s&.at("./title")&.text || s["id"])
|
85
|
-
subtitle = s.at("./title")
|
86
|
-
notitle = notitle || (!subtitle || subtitle.text.empty?)
|
87
|
-
withtitle = withtitle || (subtitle && !subtitle.text.empty?)
|
88
|
-
end
|
89
|
-
notitle && withtitle &&
|
90
|
-
@log.add("Style", nil,
|
91
|
-
"#{label}: all subclauses must have a title, or none")
|
92
|
-
end
|
93
|
-
|
94
|
-
def title_validate(root)
|
95
|
-
title_intro_validate(root)
|
96
|
-
title_main_validate(root)
|
97
|
-
title_part_validate(root)
|
98
|
-
title_subpart_validate(root)
|
99
|
-
title_names_type_validate(root)
|
100
|
-
title_first_level_validate(root)
|
101
|
-
title_all_siblings(root.xpath(SECTIONS_XPATH), "(top level)")
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
@@ -443,44 +443,49 @@ p.Terms {
|
|
443
443
|
margin-top: 0em; }
|
444
444
|
|
445
445
|
/* Navigation*/
|
446
|
-
#toc {
|
446
|
+
#toc, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) {
|
447
447
|
font-family: {{bodyfont}};
|
448
448
|
font-weight: 400; }
|
449
|
-
#toc ul {
|
449
|
+
#toc ul, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) ul {
|
450
450
|
margin: 0;
|
451
451
|
padding: 0;
|
452
452
|
list-style: none; }
|
453
|
-
#toc ul li a {
|
453
|
+
#toc ul li a, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) ul li a {
|
454
454
|
padding: 5px 10px; }
|
455
|
-
#toc ul a {
|
455
|
+
#toc ul a, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) ul a {
|
456
456
|
text-decoration: none;
|
457
457
|
display: block; }
|
458
|
-
#toc ul a:hover {
|
458
|
+
#toc ul a:hover, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) ul a:hover {
|
459
459
|
box-shadow: none;
|
460
460
|
color: white; }
|
461
|
-
#toc .h2 {
|
461
|
+
#toc .h2, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) .h2 {
|
462
462
|
padding-left: 30px; }
|
463
|
-
#toc .h3 {
|
463
|
+
#toc .h3, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) .h3 {
|
464
464
|
padding-left: 50px; }
|
465
|
-
#toc .toc-active, #toc li:hover {
|
465
|
+
#toc .toc-active, #toc li:hover, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) .toc-active, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) li:hover {
|
466
466
|
background: #1d1d1d;
|
467
467
|
box-shadow: inset -5px 0px 10px -5px #1d1d1d !important; }
|
468
|
-
#toc .toc-active a, #toc li:hover a {
|
468
|
+
#toc .toc-active a, #toc li:hover a, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) .toc-active a, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) li:hover a {
|
469
469
|
color: white; }
|
470
470
|
@media print {
|
471
|
-
#toc .toc-active, #toc li:hover {
|
471
|
+
#toc .toc-active, #toc li:hover, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) .toc-active, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) li:hover {
|
472
472
|
background: white;
|
473
473
|
box-shadow: none !important; }
|
474
|
-
#toc li:hover a {
|
474
|
+
#toc li:hover a, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) li:hover a {
|
475
475
|
color: black; } }
|
476
476
|
@media screen and (max-width: 768px) {
|
477
|
-
#toc {
|
477
|
+
#toc, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) {
|
478
478
|
padding: 0 1.5em;
|
479
479
|
overflow: visible; } }
|
480
|
-
#toc li:before {
|
480
|
+
#toc li:before, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) li:before {
|
481
481
|
content: " ";
|
482
482
|
display: none; }
|
483
483
|
|
484
|
+
#toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) {
|
485
|
+
margin-top: 0;
|
486
|
+
margin-bottom: 0;
|
487
|
+
font-size: 100%; }
|
488
|
+
|
484
489
|
nav {
|
485
490
|
line-height: 1.2em; }
|
486
491
|
@media screen and (min-width: 768px) {
|
@@ -534,7 +539,7 @@ nav {
|
|
534
539
|
display: none; }
|
535
540
|
h1.toc-contents {
|
536
541
|
margin-top: 1em; }
|
537
|
-
ul#toc-list {
|
542
|
+
ul#toc-list, ul#toc-list > :is(.h1, .h2, .h3, .h4, .h5, .h6) {
|
538
543
|
padding: 0;
|
539
544
|
margin: 0; } }
|
540
545
|
|
@@ -259,7 +259,7 @@ p.Terms {
|
|
259
259
|
|
260
260
|
/* Navigation*/
|
261
261
|
|
262
|
-
#toc {
|
262
|
+
#toc, #toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) {
|
263
263
|
@include toc(null, #1d1d1d, white);
|
264
264
|
@include sidebarToc();
|
265
265
|
|
@@ -275,6 +275,12 @@ p.Terms {
|
|
275
275
|
}
|
276
276
|
}
|
277
277
|
|
278
|
+
#toc > ul :is(.h1, .h2, .h3, .h4, .h5, .h6) {
|
279
|
+
margin-top: 0;
|
280
|
+
margin-bottom: 0;
|
281
|
+
font-size: 100%;
|
282
|
+
}
|
283
|
+
|
278
284
|
nav {
|
279
285
|
@include sidebarNav(#f7f7f7, 278px, 20px);
|
280
286
|
line-height: 1.2em;
|
@@ -299,7 +305,7 @@ nav {
|
|
299
305
|
margin-top: 1em;
|
300
306
|
}
|
301
307
|
|
302
|
-
ul#toc-list {
|
308
|
+
ul#toc-list, ul#toc-list > :is(.h1, .h2, .h3, .h4, .h5, .h6) {
|
303
309
|
padding: 0;
|
304
310
|
margin: 0;
|
305
311
|
}
|