metanorma-iso 1.3.19 → 1.3.20
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/asciidoctor/iso/base.rb +1 -0
- data/lib/asciidoctor/iso/cleanup.rb +3 -1
- data/lib/asciidoctor/iso/isodoc.rng +5 -0
- data/lib/asciidoctor/iso/isostandard.rng +80 -0
- data/lib/asciidoctor/iso/validate.rb +19 -19
- data/lib/asciidoctor/iso/validate_section.rb +19 -19
- data/lib/asciidoctor/iso/validate_title.rb +11 -11
- data/lib/isodoc/iso/base_convert.rb +42 -1
- data/lib/isodoc/iso/html/isodoc.scss +4 -0
- data/lib/isodoc/iso/html/style-human.scss +7 -0
- data/lib/isodoc/iso/html/style-iso.scss +6 -0
- data/lib/isodoc/iso/html_convert.rb +6 -0
- data/lib/metanorma/iso/version.rb +1 -1
- data/metanorma-iso.gemspec +0 -1
- data/spec/asciidoctor-iso/cleanup_spec.rb +57 -21
- data/spec/asciidoctor-iso/validate_spec.rb +225 -75
- data/spec/isodoc/postproc_spec.rb +123 -3
- data/spec/isodoc/section_spec.rb +45 -0
- data/spec/isodoc/table_spec.rb +289 -0
- data/spec/isodoc/xref_spec.rb +92 -25
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0620b97c9f91f8019da7ec0cb25086303d5a98c9eda18740e14c581acd8bcea
|
4
|
+
data.tar.gz: 35ca2d87cf4d58f1d8e8d174f8fe802c1e986ad5a6a6d13dc45125e2f4b9dfd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c99794ef6ca381337f1be16465e1e97ac0656712608d69a7edbb5996213cca0cbe8c2558105e1543e0ef8760b7790dad9bed31b252b34cddd97d54b263be4d3
|
7
|
+
data.tar.gz: 51ca61be6991b07fd9f3b044bbd268893297bba14b59af561a2082983998e183548108e945cf113a9d0046055ced4f56600b0decc4fde38acb6730dd8295f951
|
data/lib/asciidoctor/iso/base.rb
CHANGED
@@ -91,6 +91,7 @@ module Asciidoctor
|
|
91
91
|
# then standard class (docid class other than DOI &c)
|
92
92
|
# then docnumber if present, numeric sort
|
93
93
|
# else alphanumeric metanorma id (abbreviation)
|
94
|
+
# then doc part number if present, numeric sort
|
94
95
|
# then doc id (not DOI &c)
|
95
96
|
# then title
|
96
97
|
def sort_biblio_key(bib)
|
@@ -99,12 +100,13 @@ module Asciidoctor
|
|
99
100
|
id = bib&.at("./docidentifier[not(#{OTHERIDS})]")
|
100
101
|
metaid = bib&.at("./docidentifier[@type = 'metanorma']")&.text
|
101
102
|
abbrid = metaid unless /^\[\d+\]$/.match(metaid)
|
103
|
+
/\d-(?<partid>\d+)/ =~ id&.text
|
102
104
|
type = id['type'] if id
|
103
105
|
title = bib&.at("./title[@type = 'main']")&.text ||
|
104
106
|
bib&.at("./title")&.text || bib&.at("./formattedref")&.text
|
105
107
|
"#{pubclass} :: #{type} :: "\
|
106
108
|
"#{num.nil? ? abbrid : sprintf("%09d", num.to_i)} :: "\
|
107
|
-
"#{id&.text} :: #{title}"
|
109
|
+
"#{partid} :: #{id&.text} :: #{title}"
|
108
110
|
end
|
109
111
|
end
|
110
112
|
end
|
@@ -73,6 +73,19 @@
|
|
73
73
|
</choice>
|
74
74
|
</element>
|
75
75
|
</define>
|
76
|
+
<define name="ul">
|
77
|
+
<element name="ul">
|
78
|
+
<attribute name="id">
|
79
|
+
<data type="ID"/>
|
80
|
+
</attribute>
|
81
|
+
<oneOrMore>
|
82
|
+
<ref name="ul_li"/>
|
83
|
+
</oneOrMore>
|
84
|
+
<zeroOrMore>
|
85
|
+
<ref name="note"/>
|
86
|
+
</zeroOrMore>
|
87
|
+
</element>
|
88
|
+
</define>
|
76
89
|
<define name="sections">
|
77
90
|
<element name="sections">
|
78
91
|
<ref name="clause"/>
|
@@ -325,6 +338,51 @@
|
|
325
338
|
</oneOrMore>
|
326
339
|
</choice>
|
327
340
|
</define>
|
341
|
+
<define name="table">
|
342
|
+
<element name="table">
|
343
|
+
<attribute name="id">
|
344
|
+
<data type="ID"/>
|
345
|
+
</attribute>
|
346
|
+
<optional>
|
347
|
+
<attribute name="width"/>
|
348
|
+
</optional>
|
349
|
+
<optional>
|
350
|
+
<attribute name="unnumbered">
|
351
|
+
<data type="boolean"/>
|
352
|
+
</attribute>
|
353
|
+
</optional>
|
354
|
+
<optional>
|
355
|
+
<attribute name="subsequence"/>
|
356
|
+
</optional>
|
357
|
+
<optional>
|
358
|
+
<attribute name="alt"/>
|
359
|
+
</optional>
|
360
|
+
<optional>
|
361
|
+
<attribute name="summary"/>
|
362
|
+
</optional>
|
363
|
+
<optional>
|
364
|
+
<attribute name="uri">
|
365
|
+
<data type="anyURI"/>
|
366
|
+
</attribute>
|
367
|
+
</optional>
|
368
|
+
<optional>
|
369
|
+
<ref name="tname"/>
|
370
|
+
</optional>
|
371
|
+
<optional>
|
372
|
+
<ref name="thead"/>
|
373
|
+
</optional>
|
374
|
+
<ref name="tbody"/>
|
375
|
+
<optional>
|
376
|
+
<ref name="tfoot"/>
|
377
|
+
</optional>
|
378
|
+
<zeroOrMore>
|
379
|
+
<ref name="table-note"/>
|
380
|
+
</zeroOrMore>
|
381
|
+
<optional>
|
382
|
+
<ref name="dl"/>
|
383
|
+
</optional>
|
384
|
+
</element>
|
385
|
+
</define>
|
328
386
|
</include>
|
329
387
|
<!-- end overrides -->
|
330
388
|
<!--
|
@@ -431,4 +489,26 @@
|
|
431
489
|
<ref name="Clause-Section"/>
|
432
490
|
</element>
|
433
491
|
</define>
|
492
|
+
<define name="ul_li">
|
493
|
+
<element name="li">
|
494
|
+
<optional>
|
495
|
+
<attribute name="id">
|
496
|
+
<data type="ID"/>
|
497
|
+
</attribute>
|
498
|
+
</optional>
|
499
|
+
<optional>
|
500
|
+
<attribute name="uncheckedcheckbox">
|
501
|
+
<data type="boolean"/>
|
502
|
+
</attribute>
|
503
|
+
</optional>
|
504
|
+
<optional>
|
505
|
+
<attribute name="checkedcheckbox">
|
506
|
+
<data type="boolean"/>
|
507
|
+
</attribute>
|
508
|
+
</optional>
|
509
|
+
<oneOrMore>
|
510
|
+
<ref name="paragraph-with-footnote"/>
|
511
|
+
</oneOrMore>
|
512
|
+
</element>
|
513
|
+
</define>
|
434
514
|
</grammar>
|
@@ -17,19 +17,19 @@ module Asciidoctor
|
|
17
17
|
title = c.at("./title")
|
18
18
|
location = c["id"] || c.text[0..60] + "..."
|
19
19
|
location += ":#{title.text}" if c["id"] && !title.nil?
|
20
|
-
|
20
|
+
@log.add("Style", nil, "#{location}: subclause is only child")
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
def isosubgroup_validate(root)
|
25
25
|
root.xpath("//technical-committee/@type").each do |t|
|
26
26
|
unless %w{TC PC JTC JPC}.include? t.text
|
27
|
-
|
27
|
+
@log.add("Document Attributes", nil, "invalid technical committee type #{t}")
|
28
28
|
end
|
29
29
|
end
|
30
30
|
root.xpath("//subcommittee/@type").each do |t|
|
31
31
|
unless %w{SC JSC}.include? t.text
|
32
|
-
|
32
|
+
@log.add("Document Attributes", nil, "invalid subcommittee type #{t}")
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -42,7 +42,7 @@ module Asciidoctor
|
|
42
42
|
next unless !preceding.nil? && /\b(see| refer to)\s*$/mi.match(preceding)
|
43
43
|
(target = root.at("//*[@id = '#{t['target']}']")) || next
|
44
44
|
if target&.at("./ancestor-or-self::*[@obligation = 'normative']")
|
45
|
-
|
45
|
+
@log.add("Style", t, "'see #{t['target']}' is pointing to a normative section")
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -53,12 +53,12 @@ module Asciidoctor
|
|
53
53
|
preceding = t.at("./preceding-sibling::text()[last()]")
|
54
54
|
next unless !preceding.nil? && /\b(see|refer to)\s*$/mi.match(preceding)
|
55
55
|
unless target = root.at("//*[@id = '#{t['bibitemid']}']")
|
56
|
-
|
56
|
+
@log.add("Bibliography", t, "'#{t} is not pointing to a real reference")
|
57
57
|
next
|
58
58
|
end
|
59
59
|
if target.at("./ancestor::references"\
|
60
60
|
"[title = 'Normative References']")
|
61
|
-
|
61
|
+
@log.add("Style", t, "'see #{t}' is pointing to a normative reference")
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -68,15 +68,15 @@ module Asciidoctor
|
|
68
68
|
root.xpath("//eref[locality]").each do |t|
|
69
69
|
if /^(ISO|IEC)/.match t["citeas"]
|
70
70
|
unless /:[ ]?(\d+{4}|–)$/.match t["citeas"]
|
71
|
-
|
72
|
-
"specific elements"
|
71
|
+
@log.add("Style", t, "undated reference #{t['citeas']} should not contain "\
|
72
|
+
"specific elements")
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
def termdef_warn(text, re, term, msg)
|
79
|
-
re.match(text) &&
|
78
|
+
def termdef_warn(text, re, t, term, msg)
|
79
|
+
re.match(text) && @log.add("Style", t, "#{term}: #{msg}")
|
80
80
|
end
|
81
81
|
|
82
82
|
# ISO/IEC DIR 2, 16.5.6
|
@@ -84,9 +84,9 @@ module Asciidoctor
|
|
84
84
|
xmldoc.xpath("//term").each do |t|
|
85
85
|
para = t.at("./definition") || return
|
86
86
|
term = t.at("./preferred").text
|
87
|
-
termdef_warn(para.text, /^(the|a)\b/i, term,
|
87
|
+
termdef_warn(para.text, /^(the|a)\b/i, t, term,
|
88
88
|
"term definition starts with article")
|
89
|
-
termdef_warn(para.text, /\.$/i, term,
|
89
|
+
termdef_warn(para.text, /\.$/i, t, term,
|
90
90
|
"term definition ends with period")
|
91
91
|
end
|
92
92
|
cited_term_style(xmldoc)
|
@@ -107,31 +107,31 @@ module Asciidoctor
|
|
107
107
|
%w(international-standard technical-specification technical-report
|
108
108
|
publicly-available-specification international-workshop-agreement
|
109
109
|
guide).include? doctype or
|
110
|
-
|
110
|
+
@log.add("Document Attributes", nil, "#{doctype} is not a recognised document type")
|
111
111
|
end
|
112
112
|
|
113
113
|
def script_validate(xmldoc)
|
114
114
|
script = xmldoc&.at("//bibdata/script")&.text
|
115
115
|
script == "Latn" or
|
116
|
-
|
116
|
+
@log.add("Document Attributes", nil, "#{script} is not a recognised script")
|
117
117
|
end
|
118
118
|
|
119
119
|
def stage_validate(xmldoc)
|
120
120
|
stage = xmldoc&.at("//bibdata/status/stage")&.text
|
121
121
|
%w(00 10 20 30 40 50 60 90 95).include? stage or
|
122
|
-
|
122
|
+
@log.add("Document Attributes", nil, "#{stage} is not a recognised stage")
|
123
123
|
end
|
124
124
|
|
125
125
|
def substage_validate(xmldoc)
|
126
126
|
substage = xmldoc&.at("//bibdata/status/substage")&.text or return
|
127
127
|
%w(00 20 60 90 92 93 98 99).include? substage or
|
128
|
-
|
128
|
+
@log.add("Document Attributes", nil, "#{substage} is not a recognised substage")
|
129
129
|
end
|
130
130
|
|
131
131
|
def iteration_validate(xmldoc)
|
132
132
|
iteration = xmldoc&.at("//bibdata/status/iteration")&.text or return
|
133
133
|
/^\d+/.match(iteration) or
|
134
|
-
|
134
|
+
@log.add("Document Attributes", nil, "#{iteration} is not a recognised iteration")
|
135
135
|
end
|
136
136
|
|
137
137
|
def bibdata_validate(doc)
|
@@ -163,8 +163,8 @@ module Asciidoctor
|
|
163
163
|
found = true if /^ISO DATE:/.match n.text
|
164
164
|
end
|
165
165
|
found or
|
166
|
-
|
167
|
-
"associated footnote indicating unpublished status"
|
166
|
+
@log.add("Style", b, "Reference #{b&.at("./@id")&.text} does not have an "\
|
167
|
+
"associated footnote indicating unpublished status")
|
168
168
|
end
|
169
169
|
end
|
170
170
|
|
@@ -17,29 +17,29 @@ module Asciidoctor
|
|
17
17
|
def foreword_validate(root)
|
18
18
|
f = root.at("//foreword") || return
|
19
19
|
s = f.at("./clause")
|
20
|
-
|
20
|
+
@log.add("Style", f, "foreword contains subclauses") unless s.nil?
|
21
21
|
end
|
22
22
|
|
23
23
|
# ISO/IEC DIR 2, 15.4
|
24
24
|
def normref_validate(root)
|
25
25
|
f = root.at("//references[title = 'Normative References']") || return
|
26
26
|
f.at("./references | ./clause") &&
|
27
|
-
|
27
|
+
@log.add("Style", f, "normative references contains subclauses")
|
28
28
|
end
|
29
29
|
|
30
|
-
ONE_SYMBOLS_WARNING = "
|
30
|
+
ONE_SYMBOLS_WARNING = "Only one Symbols and Abbreviated "\
|
31
31
|
"Terms section in the standard".freeze
|
32
32
|
|
33
|
-
NON_DL_SYMBOLS_WARNING = "
|
33
|
+
NON_DL_SYMBOLS_WARNING = "Symbols and Abbreviated Terms can "\
|
34
34
|
"only contain a definition list".freeze
|
35
35
|
|
36
36
|
def symbols_validate(root)
|
37
37
|
f = root.xpath("//definitions")
|
38
38
|
f.empty? && return
|
39
|
-
(f.size == 1) ||
|
39
|
+
(f.size == 1) || @log.add("Style", f.first, ONE_SYMBOLS_WARNING)
|
40
40
|
f.first.elements.each do |e|
|
41
41
|
unless e.name == "dl"
|
42
|
-
|
42
|
+
@log.add("Style", f.first, NON_DL_SYMBOLS_WARNING)
|
43
43
|
return
|
44
44
|
end
|
45
45
|
end
|
@@ -48,7 +48,7 @@ module Asciidoctor
|
|
48
48
|
def seqcheck(names, msg, accepted)
|
49
49
|
n = names.shift
|
50
50
|
unless accepted.include? n
|
51
|
-
|
51
|
+
@log.add("Style", nil, msg)
|
52
52
|
names = []
|
53
53
|
end
|
54
54
|
names
|
@@ -109,46 +109,46 @@ module Asciidoctor
|
|
109
109
|
n = names.shift || return
|
110
110
|
end
|
111
111
|
unless n
|
112
|
-
|
112
|
+
@log.add("Style", nil, "Document must contain at least one clause")
|
113
113
|
return
|
114
114
|
end
|
115
115
|
n[:tag] == "clause" ||
|
116
|
-
|
116
|
+
@log.add("Style", nil, "Document must contain clause after "\
|
117
117
|
"Terms and Definitions")
|
118
118
|
n == { tag: "clause", title: "Scope" } &&
|
119
|
-
|
119
|
+
@log.add("Style", nil, "Scope must occur before Terms and Definitions")
|
120
120
|
n = names.shift || return
|
121
121
|
while n[:tag] == "clause"
|
122
122
|
n[:title] == "Scope" &&
|
123
|
-
|
123
|
+
@log.add("Style", nil, "Scope must occur before Terms and Definitions")
|
124
124
|
n = names.shift || return
|
125
125
|
end
|
126
126
|
unless n[:tag] == "annex" || n[:tag] == "references"
|
127
|
-
|
127
|
+
@log.add("Style", nil, "Only annexes and references can follow clauses")
|
128
128
|
end
|
129
129
|
while n[:tag] == "annex"
|
130
130
|
n = names.shift
|
131
131
|
if n.nil?
|
132
|
-
|
132
|
+
@log.add("Style", nil, "Document must include (references) "\
|
133
133
|
"Normative References")
|
134
134
|
return
|
135
135
|
end
|
136
136
|
end
|
137
137
|
n == { tag: "references", title: "Normative References" } ||
|
138
|
-
|
138
|
+
@log.add("Style", nil, "Document must include (references) "\
|
139
139
|
"Normative References")
|
140
140
|
n = names.shift
|
141
141
|
n == { tag: "references", title: "Bibliography" } ||
|
142
|
-
|
142
|
+
@log.add("Style", nil, "Final section must be (references) Bibliography")
|
143
143
|
names.empty? ||
|
144
|
-
|
144
|
+
@log.add("Style", nil, "There are sections after the final Bibliography")
|
145
145
|
end
|
146
146
|
|
147
147
|
def style_warning(node, msg, text = nil)
|
148
148
|
return if @novalid
|
149
|
-
w =
|
149
|
+
w = msg
|
150
150
|
w += ": #{text}" if text
|
151
|
-
|
151
|
+
@log.add("Style", node, w)
|
152
152
|
end
|
153
153
|
|
154
154
|
NORM_ISO_WARN = "non-ISO/IEC reference not expected as normative".freeze
|
@@ -174,7 +174,7 @@ module Asciidoctor
|
|
174
174
|
def norm_bibitem_style(root)
|
175
175
|
root.xpath(NORM_BIBITEMS).each do |b|
|
176
176
|
if b.at(Standoc::Converter::ISO_PUBLISHER_XPATH).nil?
|
177
|
-
|
177
|
+
@log.add("Style", b, "#{NORM_ISO_WARN}: #{b.text}")
|
178
178
|
end
|
179
179
|
end
|
180
180
|
end
|
@@ -7,10 +7,10 @@ module Asciidoctor
|
|
7
7
|
title_intro_en = root.at("//title[@type='title-intro' and @language='en']")
|
8
8
|
title_intro_fr = root.at("//title[@type='title-intro' and @language='fr']")
|
9
9
|
if title_intro_en.nil? && !title_intro_fr.nil?
|
10
|
-
|
10
|
+
@log.add("Style", title_intro_fr, "No English Title Intro!")
|
11
11
|
end
|
12
12
|
if !title_intro_en.nil? && title_intro_fr.nil?
|
13
|
-
|
13
|
+
@log.add("Style", title_intro_en, "No French Title Intro!")
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -18,10 +18,10 @@ module Asciidoctor
|
|
18
18
|
title_main_en = root.at("//title[@type='title-main' and @language='en']")
|
19
19
|
title_main_fr = root.at("//title[@type='title-main' and @language='fr']")
|
20
20
|
if title_main_en.nil? && !title_main_fr.nil?
|
21
|
-
|
21
|
+
@log.add("Style", title_main_fr, "No English Title!")
|
22
22
|
end
|
23
23
|
if !title_main_en.nil? && title_main_fr.nil?
|
24
|
-
|
24
|
+
@log.add("Style", title_main_en, "No French Title!")
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -29,9 +29,9 @@ module Asciidoctor
|
|
29
29
|
title_part_en = root.at("//title[@type='title-part' and @language='en']")
|
30
30
|
title_part_fr = root.at("//title[@type='title-part' and @language='fr']")
|
31
31
|
(title_part_en.nil? && !title_part_fr.nil?) &&
|
32
|
-
|
32
|
+
@log.add("Style", title_part_fr, "No English Title Part!")
|
33
33
|
(!title_part_en.nil? && title_part_fr.nil?) &&
|
34
|
-
|
34
|
+
@log.add("Style", title_part_en, "No French Title Part!")
|
35
35
|
end
|
36
36
|
|
37
37
|
# ISO/IEC DIR 2, 11.4
|
@@ -41,7 +41,7 @@ module Asciidoctor
|
|
41
41
|
iec = root.at("//bibdata/contributor[role/@type = 'publisher']/"\
|
42
42
|
"organization[abbreviation = 'IEC' or "\
|
43
43
|
"name = 'International Electrotechnical Commission']")
|
44
|
-
|
44
|
+
@log.add("Style", docid, "Subpart defined on non-IEC document!") if subpart && !iec
|
45
45
|
end
|
46
46
|
|
47
47
|
# ISO/IEC DIR 2, 11.5.2
|
@@ -50,11 +50,11 @@ module Asciidoctor
|
|
50
50
|
Publicly\sAvailable\sSpecification | Technical\sReport | Guide /xi
|
51
51
|
title_main_en = root.at("//title[@type='title-main' and @language='en']")
|
52
52
|
if !title_main_en.nil? && doctypes.match(title_main_en.text)
|
53
|
-
|
53
|
+
@log.add("Style", title_main_en, "Main Title may name document type")
|
54
54
|
end
|
55
55
|
title_intro_en = root.at("//title[@type='title-intro' and @language='en']")
|
56
56
|
if !title_intro_en.nil? && doctypes.match(title_intro_en.text)
|
57
|
-
|
57
|
+
@log.add("Style", title_intro_en, "Title Intro may name document type")
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -65,7 +65,7 @@ module Asciidoctor
|
|
65
65
|
s.xpath("./clause | ./terms | ./references").each do |ss|
|
66
66
|
subtitle = ss.at("./title")
|
67
67
|
!subtitle.nil? && !subtitle&.text&.empty? ||
|
68
|
-
|
68
|
+
@log.add("Style", ss, "#{title}: each first-level subclause must have a title")
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -82,7 +82,7 @@ module Asciidoctor
|
|
82
82
|
withtitle = withtitle || (subtitle && !subtitle.text.empty?)
|
83
83
|
end
|
84
84
|
notitle && withtitle &&
|
85
|
-
|
85
|
+
@log.add("Style", nil, "#{label}: all subclauses must have a title, or none")
|
86
86
|
end
|
87
87
|
|
88
88
|
def title_validate(root)
|