metanorma-ietf 2.2.1 → 2.2.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.
@@ -0,0 +1,189 @@
1
+ require "jing"
2
+ require "fileutils"
3
+
4
+ module IsoDoc::Ietf
5
+ class RfcConvert < ::IsoDoc::Convert
6
+ def schema_validate(filename)
7
+ begin
8
+ errors = Jing.new(File.join(File.dirname(__FILE__), "v3.rng")).
9
+ validate(filename)
10
+ errors.each do |error|
11
+ warn "RFC XML: Line #{"%06d" % error[:line]}:#{error[:column]} "\
12
+ "#{error[:message]}"
13
+ end
14
+ rescue Jing::Error => e
15
+ abort "Jing failed with error: #{e}"
16
+ end
17
+ end
18
+
19
+ def content_validate(xml, filename)
20
+ err = []
21
+ err += numbered_sections_check(xml)
22
+ err += toc_sections_check(xml)
23
+ err += references_check(xml)
24
+ err += xref_check(xml)
25
+ err += metadata_check(xml)
26
+ return if err.empty?
27
+ FileUtils.mv(filename, "#{filename}.err")
28
+ err.each { |e| warn "RFC XML: #{e}" }
29
+ warn "Cannot continue processing"
30
+ end
31
+
32
+ def label(sect)
33
+ ret = sect&.at("./name")&.text ||
34
+ sect["name"] || sect["anchor"]
35
+ end
36
+
37
+ # 2.46.2. "numbered" Attribute
38
+ def numbered_sections_check(xml)
39
+ ret = []
40
+ xml.xpath("//section[@numbered = 'false']").each do |s1|
41
+ s1.xpath("./section[not(@numbered) or @numbered = 'true']").
42
+ each do |s2|
43
+ ret << "Numbered section #{label(s2)} under unnumbered section "\
44
+ "#{label(s1)}"
45
+ end
46
+ s1.xpath("./following-sibling::*[name() = 'section']"\
47
+ "[not(@numbered) or @numbered = 'true']").each do |s2|
48
+ ret << "Numbered section #{label(s2)} following unnumbered section "\
49
+ "#{label(s1)}"
50
+ end
51
+ end
52
+ ret
53
+ end
54
+
55
+ # 5.2.7. Section "toc" attribute
56
+ def toc_sections_check(xml)
57
+ ret = []
58
+ xml.xpath("//section[@toc = 'exclude']").each do |s1|
59
+ s1.xpath(".//section[@toc = 'include']").each do |s2|
60
+ ret << "Section #{label(s2)} with toc=include is included in "\
61
+ "section #{label(s1)} with toc=exclude"
62
+ end
63
+ end
64
+ ret
65
+ end
66
+
67
+ # 5.4.3 <reference> "target" Insertion
68
+ # 5.4.2.4 "Table of Contents" Insertion
69
+ def references_check(xml)
70
+ ret = []
71
+ xml.xpath("//reference[not(@target)]").each do |s|
72
+ s.xpath(".//seriesInfo[@name = 'RFC' or @name = 'Internet-Draft' "\
73
+ "or @name = 'DOI'][not(@value)]").each do |s1|
74
+ ret << "for reference #{s['anchor']}, the seriesInfo with "\
75
+ "name=#{s1['name']} has been given no value"
76
+ end
77
+ end
78
+ xml.xpath("//references | //section").each do |s|
79
+ s.at("./name") or ret << "Cannot generate table of contents entry "\
80
+ "for #{label(s)}, as it has no title"
81
+ end
82
+ ret
83
+ end
84
+
85
+ # 5.4.8.2. "derivedContent" Insertion (without Content)
86
+ def xref_check(xml)
87
+ ret = []
88
+ xml.xpath("//xref | //relref").each do |x|
89
+ t = xml.at(".//*[@anchor = '#{x['target']}']") ||
90
+ xml.at(".//*[@pn = '#{x['target']}']") or
91
+ ret << "#{x.name} target #{x['target']} does not exist in the document"
92
+ next unless t
93
+ if x["format"] == "title" && t.name == "reference"
94
+ t.at("./front/title") or
95
+ ret << "reference #{t['anchor']} has been referenced by #{x.name} "\
96
+ "with format=title, but the reference has no title"
97
+ end
98
+ if x["format"] == "counter" && !%w(section table figure li
99
+ reference references t dt).include?(t.name)
100
+ ret << "#{x.to_xml} with format=counter is only allowed for "\
101
+ "clauses, tables, figures, list entries, definition terms, "\
102
+ "paragraphs, bibliographies, and bibliographic entries"
103
+ end
104
+ if x["format"] == "counter" && t.name == "reference" && !x["section"]
105
+ ret << "reference #{t['anchor']} has been referenced by xref "\
106
+ "#{x.to_xml} with format=counter, which requires a "\
107
+ "section attribute"
108
+ end
109
+ if x["format"] == "counter" && t.name == "li" && t.parent.name != "ol"
110
+ ret << "#{x.to_xml} with format=counter refers to an unnumbered "\
111
+ "list entry"
112
+ end
113
+ if x["format"] == "title" && %w(u author contact).include?(t.name)
114
+ ret << "#{x.to_xml} with format=title cannot reference a "\
115
+ "<#{t.name}> element"
116
+ end
117
+ if x["relative"] && !x["section"]
118
+ ret << "#{x.to_xml} with relative attribute requires a section "\
119
+ "attribute"
120
+ end
121
+ if (x["section"]) && t.name != "reference"
122
+ ret << "#{x.to_xml} has a section attribute, but #{x['target']} "\
123
+ "points to a #{t.name}"
124
+ end
125
+ if (x["relative"]) && t.name != "reference"
126
+ ret << "#{x.to_xml} has a relative attribute, but #{x['target']} "\
127
+ "points to a #{t.name}"
128
+ end
129
+ if !x["relative"] && x["section"]
130
+ unless t.at(".//seriesInfo[@name = 'RFC' or @name = "\
131
+ "'Internet-Draft']")
132
+ ret << "#{x.to_xml} must use a relative attribute, "\
133
+ "since it does not point to a RFC or Internet-Draft reference"
134
+ end
135
+ end
136
+ if x["relative"]
137
+ unless t.at(".//seriesInfo[@name = 'RFC' or @name = "\
138
+ "'Internet-Draft']") || t["target"]
139
+ ret << "need an explicit target= URL attribute in the reference "\
140
+ "pointed to by #{x.to_xml}"
141
+ end
142
+ end
143
+ end
144
+ ret
145
+ end
146
+
147
+ def metadata_check(xml)
148
+ ret = []
149
+ ret += link_check(xml)
150
+ ret += seriesInfo_check(xml)
151
+ ret += ipr_check(xml)
152
+ ret
153
+ end
154
+
155
+ # 5.6.3. <link> Processing
156
+ def link_check(xml)
157
+ l = xml&.at("//link[@rel = 'convertedFrom']")&.text
158
+ !l || %r{^https://datatracker\.ietf\.org/doc/draft-}.match(l) or
159
+ return ["<link rel='convertedFrom'> (:derived-from: document "\
160
+ "attribute) must start with "\
161
+ "https://datatracker.ietf.org/doc/draft-"]
162
+ []
163
+ end
164
+
165
+ # 5.2.2. "seriesInfo" Insertion
166
+ def seriesInfo_check(xml)
167
+ ret = []
168
+ xml.root["ipr"] == "none" and return []
169
+ rfcinfo = xml.at("//seriesInfo[@name = 'RFC']")
170
+ rfcnumber = xml.root["number"]
171
+ rfcinfo && rfcnumber && rfcnumber != rfcinfo["value"] and
172
+ ret << "Mismatch between <rfc number='#{rfcnumber}'> (:docnumber: NUMBER) "\
173
+ "and <seriesInfo name='RFC' value='#{rfcinfo['value']}'> "\
174
+ "(:intended-series: TYPE NUMBER)"
175
+ rfcinfo && !/^\d+$/.match(rfcnumber) and
176
+ ret << "RFC identifier <rfc number='#{rfcnumber}'> (:docnumber: NUMBER) "\
177
+ "must be a number"
178
+ ret
179
+ end
180
+
181
+ # 5.4.2.3. "Copyright Notice" Insertion
182
+ def ipr_check(xml)
183
+ xml.root["ipr"] or return ["Missing ipr attribute on <rfc> element (:ipr:)"]
184
+ /trust200902$/.match(xml.root["ipr"]) or
185
+ return ["Unknown ipr attribute on <rfc> element (:ipr:): #{xml.root['ipr']}"]
186
+ []
187
+ end
188
+ end
189
+ end
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  module Ietf
3
- VERSION = "2.2.1".freeze
3
+ VERSION = "2.2.2".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-ietf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-14 00:00:00.000000000 Z
11
+ date: 2020-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: metanorma-standoc
@@ -257,6 +257,7 @@ files:
257
257
  - lib/asciidoctor/ietf/isodoc.rng
258
258
  - lib/asciidoctor/ietf/reqt.rng
259
259
  - lib/asciidoctor/ietf/validate.rb
260
+ - lib/isodoc/ietf/SVG-1.2-RFC.rng
260
261
  - lib/isodoc/ietf/blocks.rb
261
262
  - lib/isodoc/ietf/cleanup.rb
262
263
  - lib/isodoc/ietf/footnotes.rb
@@ -269,6 +270,8 @@ files:
269
270
  - lib/isodoc/ietf/section.rb
270
271
  - lib/isodoc/ietf/table.rb
271
272
  - lib/isodoc/ietf/terms.rb
273
+ - lib/isodoc/ietf/v3.rng
274
+ - lib/isodoc/ietf/validation.rb
272
275
  - lib/isodoc/ietf/xref.rb
273
276
  - lib/metanorma-ietf.rb
274
277
  - lib/metanorma/ietf.rb