metanorma-iso 1.10.6 → 2.0.3
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/.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/htmlstyle.css +47 -0
- data/lib/isodoc/iso/html/isodoc.css +1326 -0
- data/lib/isodoc/iso/html/isodoc.scss +0 -1
- data/lib/isodoc/iso/html/style-human.css +1015 -0
- data/lib/isodoc/iso/html/style-human.scss +8 -2
- data/lib/isodoc/iso/html/style-iso.css +1042 -0
- data/lib/isodoc/iso/html/style-iso.scss +9 -2
- data/lib/isodoc/iso/html/wordstyle.css +1701 -0
- data/lib/isodoc/iso/html_convert.rb +6 -4
- data/lib/isodoc/iso/iso.amendment.xsl +2142 -1565
- data/lib/isodoc/iso/iso.international-standard.xsl +2142 -1565
- data/lib/isodoc/iso/word_convert.rb +2 -0
- data/lib/metanorma/iso/base.rb +70 -0
- data/lib/{asciidoctor → metanorma}/iso/basicdoc.rng +5 -3
- data/lib/{asciidoctor → metanorma}/iso/biblio.rng +7 -5
- 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 +248 -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 +1 -1
- data/spec/isodoc/ref_spec.rb +4 -2
- data/spec/isodoc/xref_spec.rb +18 -18
- data/spec/{asciidoctor → metanorma}/amd_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/base_spec.rb +158 -197
- 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/{asciidoctor → metanorma}/refs_spec.rb +2 -5
- 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 +28 -3
- data/spec/spec_helper.rb +1 -1
- metadata +46 -30
- data/spec/vcr_cassettes/docrels.yml +0 -393
- data/spec/vcr_cassettes/sortrefs.yml +0 -599
@@ -0,0 +1,225 @@
|
|
1
|
+
require "date"
|
2
|
+
require "nokogiri"
|
3
|
+
require "htmlentities"
|
4
|
+
require "json"
|
5
|
+
require "pathname"
|
6
|
+
require "open-uri"
|
7
|
+
require "twitter_cldr"
|
8
|
+
|
9
|
+
module Metanorma
|
10
|
+
module ISO
|
11
|
+
class Converter < Standoc::Converter
|
12
|
+
STAGE_ABBRS = {
|
13
|
+
"00": "PWI",
|
14
|
+
"10": "NP",
|
15
|
+
"20": "WD",
|
16
|
+
"30": "CD",
|
17
|
+
"40": "DIS",
|
18
|
+
"50": "FDIS",
|
19
|
+
"60": "IS",
|
20
|
+
"90": "(Review)",
|
21
|
+
"95": "(Withdrawal)",
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
STAGE_NAMES = {
|
25
|
+
"00": "Preliminary work item",
|
26
|
+
"10": "New work item proposal",
|
27
|
+
"20": "Working draft",
|
28
|
+
"30": "Committee draft",
|
29
|
+
"40": "Draft",
|
30
|
+
"50": "Final draft",
|
31
|
+
"60": "International standard",
|
32
|
+
"90": "Review",
|
33
|
+
"95": "Withdrawal",
|
34
|
+
}.freeze
|
35
|
+
|
36
|
+
def stage_abbr(stage, substage, doctype)
|
37
|
+
return nil if stage.to_i > 60
|
38
|
+
|
39
|
+
ret = STAGE_ABBRS[stage.to_sym]
|
40
|
+
ret = "PRF" if stage == "60" && substage == "00"
|
41
|
+
ret = "AWI" if stage == "10" && substage == "99"
|
42
|
+
if %w(amendment technical-corrigendum technical-report
|
43
|
+
technical-specification).include?(doctype)
|
44
|
+
ret = "D" if stage == "40" && doctype == "amendment"
|
45
|
+
ret = "FD" if stage == "50" && %w(amendment technical-corrigendum)
|
46
|
+
.include?(doctype)
|
47
|
+
end
|
48
|
+
ret
|
49
|
+
end
|
50
|
+
|
51
|
+
def stage_name(stage, substage, _doctype, iteration = nil)
|
52
|
+
return "Proof" if stage == "60" && substage == "00"
|
53
|
+
|
54
|
+
ret = STAGE_NAMES[stage.to_sym]
|
55
|
+
if iteration && %w(20 30).include?(stage)
|
56
|
+
prefix = iteration.to_i.localize(@lang.to_sym)
|
57
|
+
.to_rbnf_s("SpelloutRules", "spellout-ordinal")
|
58
|
+
ret = "#{prefix.capitalize} #{ret.downcase}"
|
59
|
+
end
|
60
|
+
ret
|
61
|
+
end
|
62
|
+
|
63
|
+
def metadata_id(node, xml)
|
64
|
+
iso_id(node, xml)
|
65
|
+
node&.attr("tc-docnumber")&.split(/,\s*/)&.each do |n|
|
66
|
+
xml.docidentifier(n, **attr_code(type: "iso-tc"))
|
67
|
+
end
|
68
|
+
xml.docnumber node&.attr("docnumber")
|
69
|
+
end
|
70
|
+
|
71
|
+
def iso_id(node, xml)
|
72
|
+
(!@amd && node.attr("docnumber")) || (@amd && node.attr("updates")) or
|
73
|
+
return
|
74
|
+
|
75
|
+
dn = iso_id1(node)
|
76
|
+
dn1 = id_stage_prefix(dn, node, false)
|
77
|
+
dn2 = id_stage_prefix(dn, node, true)
|
78
|
+
xml.docidentifier dn1, **attr_code(type: "ISO")
|
79
|
+
xml.docidentifier(id_langsuffix(dn1, node),
|
80
|
+
**attr_code(type: "iso-with-lang"))
|
81
|
+
xml.docidentifier(id_langsuffix(dn2, node),
|
82
|
+
**attr_code(type: "iso-reference"))
|
83
|
+
end
|
84
|
+
|
85
|
+
def iso_id1(node)
|
86
|
+
if @amd
|
87
|
+
dn = node.attr("updates")
|
88
|
+
add_amd_parts(dn, node)
|
89
|
+
else
|
90
|
+
part, subpart = node&.attr("partnumber")&.split(/-/)
|
91
|
+
add_id_parts(node.attr("docnumber"), part, subpart)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_amd_parts(docnum, node)
|
96
|
+
case doctype(node)
|
97
|
+
when "amendment"
|
98
|
+
"#{docnum}/Amd #{node.attr('amendment-number')}"
|
99
|
+
when "technical-corrigendum"
|
100
|
+
"#{docnum}/Cor.#{node.attr('corrigendum-number')}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def id_langsuffix(docnum, node)
|
105
|
+
lang = node.attr("language") || "en"
|
106
|
+
suffix = case lang
|
107
|
+
when "en" then "(E)"
|
108
|
+
when "fr" then "(F)"
|
109
|
+
else
|
110
|
+
"(X)"
|
111
|
+
end
|
112
|
+
"#{docnum}#{suffix}"
|
113
|
+
end
|
114
|
+
|
115
|
+
def structured_id(node, xml)
|
116
|
+
return unless node.attr("docnumber")
|
117
|
+
|
118
|
+
part, subpart = node&.attr("partnumber")&.split(/-/)
|
119
|
+
xml.structuredidentifier do |i|
|
120
|
+
i.project_number(node.attr("docnumber"), **attr_code(
|
121
|
+
part: part, subpart: subpart,
|
122
|
+
amendment: node.attr("amendment-number"),
|
123
|
+
corrigendum: node.attr("corrigendum-number"),
|
124
|
+
origyr: node.attr("created-date")
|
125
|
+
))
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def add_id_parts(docnum, part, subpart)
|
130
|
+
docnum += "-#{part}" if part
|
131
|
+
docnum += "-#{subpart}" if subpart
|
132
|
+
docnum
|
133
|
+
end
|
134
|
+
|
135
|
+
def id_stage_abbr(stage, substage, node, bare = false)
|
136
|
+
ret = id_stage_abbr1(stage, substage, node, bare)
|
137
|
+
if %w(amendment technical-corrigendum technical-report
|
138
|
+
technical-specification).include?(doctype(node)) &&
|
139
|
+
!%w(D FD).include?(ret)
|
140
|
+
ret = "#{ret} "
|
141
|
+
end
|
142
|
+
ret
|
143
|
+
end
|
144
|
+
|
145
|
+
def id_stage_abbr1(stage, substage, node, bare)
|
146
|
+
if bare
|
147
|
+
IsoDoc::Iso::Metadata.new("en", "Latn", @i18n)
|
148
|
+
.status_abbrev(stage_abbr(stage, substage, doctype(node)),
|
149
|
+
substage, nil, nil, doctype(node))
|
150
|
+
else
|
151
|
+
IsoDoc::Iso::Metadata.new("en", "Latn", @i18n)
|
152
|
+
.status_abbrev(stage_abbr(stage, substage, doctype(node)),
|
153
|
+
substage, node.attr("iteration"),
|
154
|
+
node.attr("draft"), doctype(node))
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def cover_stage_abbr(node)
|
159
|
+
stage = get_stage(node)
|
160
|
+
abbr = id_stage_abbr(get_stage(node), get_substage(node), node, true)
|
161
|
+
typeabbr = get_typeabbr(node, true)
|
162
|
+
if stage.to_i > 50 || (stage.to_i == 60 && get_substage(node).to_i < 60)
|
163
|
+
typeabbr = ""
|
164
|
+
end
|
165
|
+
"#{abbr}#{typeabbr}".strip
|
166
|
+
end
|
167
|
+
|
168
|
+
def id_stage_prefix(docnum, node, force_year)
|
169
|
+
stage = get_stage(node)
|
170
|
+
typeabbr = get_typeabbr(node)
|
171
|
+
if stage && (stage.to_i < 60)
|
172
|
+
docnum = unpub_stage_prefix(docnum, stage, typeabbr, node)
|
173
|
+
elsif typeabbr == "DIR " then docnum = "#{typeabbr}#{docnum}"
|
174
|
+
elsif typeabbr && !@amd then docnum = "/#{typeabbr}#{docnum}"
|
175
|
+
end
|
176
|
+
(force_year || !(stage && (stage.to_i < 60))) and
|
177
|
+
docnum = id_add_year(docnum, node)
|
178
|
+
docnum
|
179
|
+
end
|
180
|
+
|
181
|
+
def unpub_stage_prefix(docnum, stage, typeabbr, node)
|
182
|
+
abbr = id_stage_abbr(stage, get_substage(node), node)
|
183
|
+
%w(40 50).include?(stage) && i = node.attr("iteration") and
|
184
|
+
itersuffix = ".#{i}"
|
185
|
+
return docnum if abbr.nil? || abbr.empty? # prefixes added in cleanup
|
186
|
+
return "/#{abbr}#{typeabbr} #{docnum}#{itersuffix}" unless @amd
|
187
|
+
|
188
|
+
a = docnum.split(%r{/})
|
189
|
+
a[-1] = "#{abbr}#{a[-1]}#{itersuffix}"
|
190
|
+
a.join("/")
|
191
|
+
end
|
192
|
+
|
193
|
+
def id_add_year(docnum, node)
|
194
|
+
year = node.attr("copyright-year")
|
195
|
+
@amd and year ||= node.attr("updated-date")&.sub(/-.*$/, "")
|
196
|
+
docnum += ":#{year}" if year
|
197
|
+
docnum
|
198
|
+
end
|
199
|
+
|
200
|
+
def get_stage(node)
|
201
|
+
a = node.attr("status")
|
202
|
+
a = node.attr("docstage") if a.nil? || a.empty?
|
203
|
+
a = "60" if a.nil? || a.empty?
|
204
|
+
a
|
205
|
+
end
|
206
|
+
|
207
|
+
def get_substage(node)
|
208
|
+
stage = get_stage(node)
|
209
|
+
ret = node.attr("docsubstage")
|
210
|
+
ret = (stage == "60" ? "60" : "00") if ret.nil? || ret.empty?
|
211
|
+
ret
|
212
|
+
end
|
213
|
+
|
214
|
+
def get_typeabbr(node, amd = false)
|
215
|
+
case doctype(node)
|
216
|
+
when "directive" then "DIR "
|
217
|
+
when "technical-report" then "TR "
|
218
|
+
when "technical-specification" then "TS "
|
219
|
+
when "amendment" then (amd ? "Amd " : "")
|
220
|
+
when "technical-corrigendum" then (amd ? "Cor " : "")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -32,6 +32,56 @@
|
|
32
32
|
<ref name="DocumentType"/>
|
33
33
|
</element>
|
34
34
|
</define>
|
35
|
+
<define name="index">
|
36
|
+
<element name="index">
|
37
|
+
<optional>
|
38
|
+
<attribute name="to">
|
39
|
+
<data type="IDREF"/>
|
40
|
+
</attribute>
|
41
|
+
</optional>
|
42
|
+
<element name="primary">
|
43
|
+
<oneOrMore>
|
44
|
+
<choice>
|
45
|
+
<ref name="PureTextElement"/>
|
46
|
+
<ref name="stem"/>
|
47
|
+
</choice>
|
48
|
+
</oneOrMore>
|
49
|
+
</element>
|
50
|
+
<optional>
|
51
|
+
<element name="secondary">
|
52
|
+
<oneOrMore>
|
53
|
+
<choice>
|
54
|
+
<ref name="PureTextElement"/>
|
55
|
+
<ref name="stem"/>
|
56
|
+
</choice>
|
57
|
+
</oneOrMore>
|
58
|
+
</element>
|
59
|
+
</optional>
|
60
|
+
<optional>
|
61
|
+
<element name="tertiary">
|
62
|
+
<oneOrMore>
|
63
|
+
<choice>
|
64
|
+
<ref name="PureTextElement"/>
|
65
|
+
<ref name="stem"/>
|
66
|
+
</choice>
|
67
|
+
</oneOrMore>
|
68
|
+
</element>
|
69
|
+
</optional>
|
70
|
+
</element>
|
71
|
+
</define>
|
72
|
+
<define name="bibitem">
|
73
|
+
<element name="bibitem">
|
74
|
+
<attribute name="id">
|
75
|
+
<data type="ID"/>
|
76
|
+
</attribute>
|
77
|
+
<optional>
|
78
|
+
<attribute name="hidden">
|
79
|
+
<data type="boolean"/>
|
80
|
+
</attribute>
|
81
|
+
</optional>
|
82
|
+
<ref name="BibliographicItem"/>
|
83
|
+
</element>
|
84
|
+
</define>
|
35
85
|
<define name="section-title">
|
36
86
|
<element name="title">
|
37
87
|
<zeroOrMore>
|
@@ -690,6 +740,7 @@
|
|
690
740
|
<ref name="terms"/>
|
691
741
|
<ref name="term-clause"/>
|
692
742
|
<ref name="definitions"/>
|
743
|
+
<ref name="floating-title"/>
|
693
744
|
</choice>
|
694
745
|
</oneOrMore>
|
695
746
|
</element>
|
@@ -1013,6 +1064,26 @@
|
|
1013
1064
|
</zeroOrMore>
|
1014
1065
|
</element>
|
1015
1066
|
</define>
|
1067
|
+
<define name="sub">
|
1068
|
+
<element name="sub">
|
1069
|
+
<zeroOrMore>
|
1070
|
+
<choice>
|
1071
|
+
<ref name="PureTextElement"/>
|
1072
|
+
<ref name="stem"/>
|
1073
|
+
</choice>
|
1074
|
+
</zeroOrMore>
|
1075
|
+
</element>
|
1076
|
+
</define>
|
1077
|
+
<define name="sup">
|
1078
|
+
<element name="sup">
|
1079
|
+
<zeroOrMore>
|
1080
|
+
<choice>
|
1081
|
+
<ref name="PureTextElement"/>
|
1082
|
+
<ref name="stem"/>
|
1083
|
+
</choice>
|
1084
|
+
</zeroOrMore>
|
1085
|
+
</element>
|
1086
|
+
</define>
|
1016
1087
|
<define name="pagebreak">
|
1017
1088
|
<element name="pagebreak">
|
1018
1089
|
<optional>
|
@@ -1680,6 +1751,7 @@
|
|
1680
1751
|
<ref name="clause-subsection"/>
|
1681
1752
|
<ref name="terms"/>
|
1682
1753
|
<ref name="definitions"/>
|
1754
|
+
<ref name="floating-title"/>
|
1683
1755
|
</choice>
|
1684
1756
|
</oneOrMore>
|
1685
1757
|
</choice>
|
@@ -1722,6 +1794,7 @@
|
|
1722
1794
|
<ref name="terms"/>
|
1723
1795
|
<ref name="definitions"/>
|
1724
1796
|
<ref name="references"/>
|
1797
|
+
<ref name="floating-title"/>
|
1725
1798
|
</choice>
|
1726
1799
|
</zeroOrMore>
|
1727
1800
|
</group>
|
@@ -2200,7 +2273,18 @@
|
|
2200
2273
|
<ref name="MultilingualRenderingType"/>
|
2201
2274
|
</attribute>
|
2202
2275
|
</optional>
|
2203
|
-
<
|
2276
|
+
<oneOrMore>
|
2277
|
+
<choice>
|
2278
|
+
<ref name="formula"/>
|
2279
|
+
<ref name="ul"/>
|
2280
|
+
<ref name="ol"/>
|
2281
|
+
<ref name="dl"/>
|
2282
|
+
<ref name="quote"/>
|
2283
|
+
<ref name="sourcecode"/>
|
2284
|
+
<ref name="paragraph"/>
|
2285
|
+
<ref name="figure"/>
|
2286
|
+
</choice>
|
2287
|
+
</oneOrMore>
|
2204
2288
|
</element>
|
2205
2289
|
</define>
|
2206
2290
|
<define name="termsource">
|
@@ -2534,4 +2618,17 @@
|
|
2534
2618
|
</oneOrMore>
|
2535
2619
|
</element>
|
2536
2620
|
</define>
|
2621
|
+
<define name="floating-title">
|
2622
|
+
<element name="floating-title">
|
2623
|
+
<attribute name="id">
|
2624
|
+
<data type="ID"/>
|
2625
|
+
</attribute>
|
2626
|
+
<attribute name="depth">
|
2627
|
+
<data type="int"/>
|
2628
|
+
</attribute>
|
2629
|
+
<zeroOrMore>
|
2630
|
+
<ref name="TextElement"/>
|
2631
|
+
</zeroOrMore>
|
2632
|
+
</element>
|
2633
|
+
</define>
|
2537
2634
|
</grammar>
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "htmlentities"
|
2
|
+
require "uri" if /^2\./.match?(RUBY_VERSION)
|
3
|
+
|
4
|
+
module Metanorma
|
5
|
+
module ISO
|
6
|
+
class Converter < Standoc::Converter
|
7
|
+
def clause_parse(attrs, xml, node)
|
8
|
+
node.option? "appendix" and return appendix_parse(attrs, xml, node)
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def scope_parse(attrs, xml, node)
|
13
|
+
attrs = attrs.merge(type: "scope") unless @amd
|
14
|
+
clause_parse(attrs, xml, node)
|
15
|
+
end
|
16
|
+
|
17
|
+
def appendix_parse(attrs, xml, node)
|
18
|
+
attrs[:"inline-header"] = node.option? "inline-header"
|
19
|
+
set_obligation(attrs, node)
|
20
|
+
xml.appendix **attr_code(attrs) do |xml_section|
|
21
|
+
xml_section.title { |name| name << node.title }
|
22
|
+
xml_section << node.content
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def patent_notice_parse(xml, node)
|
27
|
+
# xml.patent_notice do |xml_section|
|
28
|
+
# xml_section << node.content
|
29
|
+
# end
|
30
|
+
xml << node.content
|
31
|
+
end
|
32
|
+
|
33
|
+
def sectiontype(node, level = true)
|
34
|
+
return nil if @amd
|
35
|
+
|
36
|
+
ret = sectiontype_streamline(sectiontype1(node))
|
37
|
+
return ret if ret == "terms and definitions" && @vocab
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
def term_def_subclause_parse(attrs, xml, node)
|
43
|
+
node.role == "term" and
|
44
|
+
return term_def_subclause_parse1(attrs, xml, node)
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require "metanorma-standoc"
|
2
|
+
require_relative "./validate_style"
|
3
|
+
require_relative "./validate_requirements"
|
4
|
+
require_relative "./validate_section"
|
5
|
+
require_relative "./validate_title"
|
6
|
+
require_relative "./validate_image"
|
7
|
+
require "nokogiri"
|
8
|
+
require "jing"
|
9
|
+
require "iev"
|
10
|
+
|
11
|
+
module Metanorma
|
12
|
+
module ISO
|
13
|
+
class Converter < Standoc::Converter
|
14
|
+
def isosubgroup_validate(root)
|
15
|
+
root.xpath("//technical-committee/@type").each do |t|
|
16
|
+
unless %w{TC PC JTC JPC}.include? t.text
|
17
|
+
@log.add("Document Attributes", nil,
|
18
|
+
"invalid technical committee type #{t}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
root.xpath("//subcommittee/@type").each do |t|
|
22
|
+
unless %w{SC JSC}.include? t.text
|
23
|
+
@log.add("Document Attributes", nil,
|
24
|
+
"invalid subcommittee type #{t}")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# ISO/IEC DIR 2, 15.5.3
|
30
|
+
# does not deal with preceding text marked up
|
31
|
+
def see_xrefs_validate(root)
|
32
|
+
root.xpath("//xref").each do |t|
|
33
|
+
preceding = t.at("./preceding-sibling::text()[last()]")
|
34
|
+
next unless !preceding.nil? &&
|
35
|
+
/\b(see| refer to)\s*\Z/mi.match(preceding)
|
36
|
+
|
37
|
+
(target = root.at("//*[@id = '#{t['target']}']")) || next
|
38
|
+
if target&.at("./ancestor-or-self::*[@obligation = 'normative']")
|
39
|
+
@log.add("Style", t,
|
40
|
+
"'see #{t['target']}' is pointing to a normative section")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# ISO/IEC DIR 2, 15.5.3
|
46
|
+
def see_erefs_validate(root)
|
47
|
+
root.xpath("//eref").each do |t|
|
48
|
+
prec = t.at("./preceding-sibling::text()[last()]")
|
49
|
+
next unless !prec.nil? && /\b(see|refer to)\s*\Z/mi.match(prec)
|
50
|
+
|
51
|
+
unless target = root.at("//*[@id = '#{t['bibitemid']}']")
|
52
|
+
@log.add("Bibliography", t,
|
53
|
+
"'#{t} is not pointing to a real reference")
|
54
|
+
next
|
55
|
+
end
|
56
|
+
target.at("./ancestor::references[@normative = 'true']") and
|
57
|
+
@log.add("Style", t,
|
58
|
+
"'see #{t}' is pointing to a normative reference")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# ISO/IEC DIR 2, 10.4
|
63
|
+
def locality_erefs_validate(root)
|
64
|
+
root.xpath("//eref[descendant::locality]").each do |t|
|
65
|
+
if /^(ISO|IEC)/.match?(t["citeas"]) &&
|
66
|
+
!/: ?(\d+{4}|–)$/.match?(t["citeas"])
|
67
|
+
@log.add("Style", t,
|
68
|
+
"undated reference #{t['citeas']} should not contain "\
|
69
|
+
"specific elements")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def termdef_warn(text, regex, elem, term, msg)
|
75
|
+
regex.match(text) && @log.add("Style", elem, "#{term}: #{msg}")
|
76
|
+
end
|
77
|
+
|
78
|
+
# ISO/IEC DIR 2, 16.5.6
|
79
|
+
def termdef_style(xmldoc)
|
80
|
+
xmldoc.xpath("//term").each do |t|
|
81
|
+
para = t.at("./definition/verbal-definition") || return
|
82
|
+
term = t.at("./preferred//name").text
|
83
|
+
termdef_warn(para.text, /\A(the|a)\b/i, t, term,
|
84
|
+
"term definition starts with article")
|
85
|
+
termdef_warn(para.text, /\.\Z/i, t, term,
|
86
|
+
"term definition ends with period")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def doctype_validate(xmldoc)
|
91
|
+
doctype = xmldoc&.at("//bibdata/ext/doctype")&.text
|
92
|
+
%w(international-standard technical-specification technical-report
|
93
|
+
publicly-available-specification international-workshop-agreement
|
94
|
+
guide amendment technical-corrigendum).include? doctype or
|
95
|
+
@log.add("Document Attributes", nil,
|
96
|
+
"#{doctype} is not a recognised document type")
|
97
|
+
end
|
98
|
+
|
99
|
+
def script_validate(xmldoc)
|
100
|
+
script = xmldoc&.at("//bibdata/script")&.text
|
101
|
+
script == "Latn" or
|
102
|
+
@log.add("Document Attributes", nil,
|
103
|
+
"#{script} is not a recognised script")
|
104
|
+
end
|
105
|
+
|
106
|
+
def stage_validate(xmldoc)
|
107
|
+
stage = xmldoc&.at("//bibdata/status/stage")&.text
|
108
|
+
%w(00 10 20 30 40 50 60 90 95).include? stage or
|
109
|
+
@log.add("Document Attributes", nil,
|
110
|
+
"#{stage} is not a recognised stage")
|
111
|
+
end
|
112
|
+
|
113
|
+
def substage_validate(xmldoc)
|
114
|
+
substage = xmldoc&.at("//bibdata/status/substage")&.text or return
|
115
|
+
%w(00 20 60 90 92 93 98 99).include? substage or
|
116
|
+
@log.add("Document Attributes", nil,
|
117
|
+
"#{substage} is not a recognised substage")
|
118
|
+
end
|
119
|
+
|
120
|
+
def iteration_validate(xmldoc)
|
121
|
+
iteration = xmldoc&.at("//bibdata/status/iteration")&.text or return
|
122
|
+
/^\d+/.match(iteration) or
|
123
|
+
@log.add("Document Attributes", nil,
|
124
|
+
"#{iteration} is not a recognised iteration")
|
125
|
+
end
|
126
|
+
|
127
|
+
def bibdata_validate(doc)
|
128
|
+
doctype_validate(doc)
|
129
|
+
script_validate(doc)
|
130
|
+
stage_validate(doc)
|
131
|
+
substage_validate(doc)
|
132
|
+
iteration_validate(doc)
|
133
|
+
end
|
134
|
+
|
135
|
+
def content_validate(doc)
|
136
|
+
super
|
137
|
+
title_validate(doc.root)
|
138
|
+
isosubgroup_validate(doc.root)
|
139
|
+
onlychild_clause_validate(doc.root)
|
140
|
+
termdef_style(doc.root)
|
141
|
+
see_xrefs_validate(doc.root)
|
142
|
+
see_erefs_validate(doc.root)
|
143
|
+
locality_erefs_validate(doc.root)
|
144
|
+
bibdata_validate(doc.root)
|
145
|
+
bibitem_validate(doc.root)
|
146
|
+
figure_validate(doc.root)
|
147
|
+
end
|
148
|
+
|
149
|
+
def bibitem_validate(xmldoc)
|
150
|
+
xmldoc.xpath("//bibitem[date/on = '–']").each do |b|
|
151
|
+
b.at("./note[@type = 'Unpublished-Status']") or
|
152
|
+
@log.add("Style", b,
|
153
|
+
"Reference #{b&.at('./@id')&.text} does not have an "\
|
154
|
+
"associated footnote indicating unpublished status")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def validate(doc)
|
159
|
+
content_validate(doc)
|
160
|
+
doctype = doc&.at("//bibdata/ext/doctype")&.text
|
161
|
+
schema = case doctype
|
162
|
+
when "amendment", "technical-corrigendum" # @amd
|
163
|
+
"isostandard-amd.rng"
|
164
|
+
else
|
165
|
+
"isostandard.rng"
|
166
|
+
end
|
167
|
+
schema_validate(formattedstr_strip(doc.dup),
|
168
|
+
File.join(File.dirname(__FILE__), schema))
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|