metanorma-ietf 2.4.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a0a93b0a29195d775f23e2ba37414870b8e708a006bba0498b3113aebe787c9
4
- data.tar.gz: 53a29d58e5c0c601c29de23d0515d43e690458b8b848f67cacf5064403c3b834
3
+ metadata.gz: def69cf551c6c50fcb28fcdf04ab02e0d3d9cf83ba3dcd81114c41f71860599f
4
+ data.tar.gz: 5afc33bb93c93fbc86565d984562a3a61ed02b700e0a1e66a70f47289ef230c9
5
5
  SHA512:
6
- metadata.gz: e89e41ec81886905668543d6f24ad31ef6ea9cf0a38551f56f1fa3e8007bb6068421b221d0d835951054894146d218b47ae0fe9d1cc1a621f7df6f85a7442e3d
7
- data.tar.gz: 11d9d25373f48d7fb3197e5107168c64b8230d519f1e45b410dec5403aab6158f81c8f0e34c2553aff7fa1f32f5974d7a8d7a77a6e5233fb0ef65aa1a300a2c6
6
+ metadata.gz: 4a2c6f8d47d875c1fb896d1fffdc5d5f789c05a679ab474ae7dfbc52795b9df47eb4763164f08c2da964c0de53ad51f91233ea230a8bce9553a31986f19bf4cd
7
+ data.tar.gz: eb7fbd7913907b01e95f07bd2b28058b1d8c953f5f9b8b8a9c81a6c1638319fbb2ce8f593a3d83970b5ea748fbf34b7d0ba60b73ea5fa8f9c1a41e3076aec6ac
@@ -32,6 +32,18 @@
32
32
  <ref name="DocumentType"/>
33
33
  </element>
34
34
  </define>
35
+ <define name="section-title">
36
+ <element name="title">
37
+ <zeroOrMore>
38
+ <ref name="TextElement"/>
39
+ </zeroOrMore>
40
+ </element>
41
+ <zeroOrMore>
42
+ <element name="variant-title">
43
+ <ref name="TypedTitleString"/>
44
+ </element>
45
+ </zeroOrMore>
46
+ </define>
35
47
  <define name="hyperlink">
36
48
  <element name="link">
37
49
  <attribute name="target">
@@ -158,15 +170,17 @@
158
170
  <data type="boolean"/>
159
171
  </attribute>
160
172
  </optional>
161
- <attribute name="type">
162
- <choice>
163
- <value>roman</value>
164
- <value>alphabet</value>
165
- <value>arabic</value>
166
- <value>roman_upper</value>
167
- <value>alphabet_upper</value>
168
- </choice>
169
- </attribute>
173
+ <optional>
174
+ <attribute name="type">
175
+ <choice>
176
+ <value>roman</value>
177
+ <value>alphabet</value>
178
+ <value>arabic</value>
179
+ <value>roman_upper</value>
180
+ <value>alphabet_upper</value>
181
+ </choice>
182
+ </attribute>
183
+ </optional>
170
184
  <oneOrMore>
171
185
  <ref name="li"/>
172
186
  </oneOrMore>
@@ -64,9 +64,9 @@
64
64
  <optional>
65
65
  <ref name="label"/>
66
66
  </optional>
67
- <optional>
67
+ <zeroOrMore>
68
68
  <ref name="subject"/>
69
- </optional>
69
+ </zeroOrMore>
70
70
  <zeroOrMore>
71
71
  <ref name="reqinherit"/>
72
72
  </zeroOrMore>
@@ -80,6 +80,7 @@
80
80
  <ref name="verification"/>
81
81
  <ref name="import"/>
82
82
  <ref name="description"/>
83
+ <ref name="component"/>
83
84
  </choice>
84
85
  </zeroOrMore>
85
86
  <optional>
@@ -105,12 +106,16 @@
105
106
  </define>
106
107
  <define name="subject">
107
108
  <element name="subject">
108
- <text/>
109
+ <oneOrMore>
110
+ <ref name="TextElement"/>
111
+ </oneOrMore>
109
112
  </element>
110
113
  </define>
111
114
  <define name="reqinherit">
112
115
  <element name="inherit">
113
- <text/>
116
+ <oneOrMore>
117
+ <ref name="TextElement"/>
118
+ </oneOrMore>
114
119
  </element>
115
120
  </define>
116
121
  <define name="measurementtarget">
@@ -138,6 +143,12 @@
138
143
  <ref name="RequirementSubpart"/>
139
144
  </element>
140
145
  </define>
146
+ <define name="component">
147
+ <element name="component">
148
+ <attribute name="class"/>
149
+ <ref name="RequirementSubpart"/>
150
+ </element>
151
+ </define>
141
152
  <define name="reqt_references">
142
153
  <element name="references">
143
154
  <oneOrMore>
@@ -1,229 +1,236 @@
1
- module IsoDoc::Ietf
2
- class RfcConvert < ::IsoDoc::Convert
3
- def para_attrs(node)
4
- { keepWithNext: node["keep-with-next"],
5
- keepWithPrevious: node["keep-with-previous"],
6
- anchor: node["id"] }
7
- end
8
-
9
- def para_parse(node, out)
10
- out.t **attr_code(para_attrs(node)) do |p|
11
- unless @termdomain.empty?
12
- p << "&lt;#{@termdomain}&gt; "
13
- @termdomain = ""
1
+ module IsoDoc
2
+ module Ietf
3
+ class RfcConvert < ::IsoDoc::Convert
4
+ def para_attrs(node)
5
+ { keepWithNext: node["keep-with-next"],
6
+ keepWithPrevious: node["keep-with-previous"],
7
+ anchor: node["id"] }
8
+ end
9
+
10
+ def para_parse(node, out)
11
+ out.t **attr_code(para_attrs(node)) do |p|
12
+ unless @termdomain.empty?
13
+ p << "&lt;#{@termdomain}&gt; "
14
+ @termdomain = ""
15
+ end
16
+ node.children.each { |n| parse(n, p) unless n.name == "note" }
14
17
  end
15
- node.children.each { |n| parse(n, p) unless n.name == "note" }
18
+ node.xpath(ns("./note")).each { |n| parse(n, out) }
16
19
  end
17
- node.xpath(ns("./note")).each { |n| parse(n, out) }
18
- end
19
20
 
20
- # NOTE ignoring "bare" attribute, which is tantamount to "empty"
21
- def ul_attrs(node)
22
- { anchor: node["id"],
23
- empty: node["nobullet"],
24
- spacing: node["spacing"] }
25
- end
21
+ # NOTE ignoring "bare" attribute, which is tantamount to "empty"
22
+ def ul_attrs(node)
23
+ { anchor: node["id"],
24
+ empty: node["nobullet"],
25
+ spacing: node["spacing"] }
26
+ end
26
27
 
27
- def ul_parse(node, out)
28
- out.ul **attr_code(ul_attrs(node)) do |ul|
29
- node.children.each { |n| parse(n, ul) }
28
+ def ul_parse(node, out)
29
+ out.ul **attr_code(ul_attrs(node)) do |ul|
30
+ node.children.each { |n| parse(n, ul) }
31
+ end
30
32
  end
31
- end
32
33
 
33
- OL_STYLE = {
34
- arabic: "1",
35
- roman: "i",
36
- alphabet: "a",
37
- roman_upper: "I",
38
- alphabet_upper: "A",
39
- }.freeze
34
+ OL_STYLE = {
35
+ arabic: "1",
36
+ roman: "i",
37
+ alphabet: "a",
38
+ roman_upper: "I",
39
+ alphabet_upper: "A",
40
+ }.freeze
40
41
 
41
- def ol_style(type)
42
- OL_STYLE[type&.to_sym] || type
43
- end
42
+ def ol_style(type)
43
+ OL_STYLE[type&.to_sym] || type
44
+ end
44
45
 
45
- def ol_attrs(node)
46
- { anchor: node["id"],
47
- spacing: node["spacing"],
48
- type: ol_style(node["type"]),
49
- group: node["group"],
50
- start: node["start"] }
51
- end
46
+ def ol_attrs(node)
47
+ { anchor: node["id"],
48
+ spacing: node["spacing"],
49
+ type: ol_style(node["type"]),
50
+ group: node["group"],
51
+ start: node["start"] }
52
+ end
52
53
 
53
- def ol_parse(node, out)
54
- out.ol **attr_code(ol_attrs(node)) do |ol|
55
- node.children.each { |n| parse(n, ol) }
54
+ def ol_parse(node, out)
55
+ out.ol **attr_code(ol_attrs(node)) do |ol|
56
+ node.children.each { |n| parse(n, ol) }
57
+ end
56
58
  end
57
- end
58
59
 
59
- def dl_attrs(node)
60
- attr_code(anchor: node["id"],
61
- newline: node["newline"],
62
- indent: node["indent"],
63
- spacing: node["spacing"])
64
- end
60
+ def dl_attrs(node)
61
+ attr_code(anchor: node["id"],
62
+ newline: node["newline"],
63
+ indent: node["indent"],
64
+ spacing: node["spacing"])
65
+ end
65
66
 
66
- def dt_parse(dt, term)
67
- if dt.elements.empty?
68
- term << dt.text
69
- else
70
- dt.children.each { |n| parse(n, term) }
67
+ def dt_parse(dt, term)
68
+ if dt.elements.empty?
69
+ term << dt.text
70
+ else
71
+ dt.children.each { |n| parse(n, term) }
72
+ end
71
73
  end
72
- end
73
74
 
74
- def note_label(node)
75
- n = @xrefs.get[node["id"]]
76
- return l10n("#{@i18n.note}: ") if n.nil? || n[:label].nil? ||
77
- n[:label].empty?
75
+ def note_label(node)
76
+ n = @xrefs.get[node["id"]]
77
+ return l10n("#{@i18n.note}: ") if n.nil? || n[:label].nil? ||
78
+ n[:label].empty?
78
79
 
79
- l10n("#{@i18n.note} #{n[:label]}: ")
80
- end
80
+ l10n("#{@i18n.note} #{n[:label]}: ")
81
+ end
81
82
 
82
- def note_parse(node, out)
83
- first = node.first_element_child
84
- out.aside **attr_code(anchor: node["id"] || first["id"]) do |a|
85
- a.t do |p|
86
- p << note_label(node)
87
- first.name == "p" and first.children.each { |n| parse(n, p) }
83
+ def note_parse(node, out)
84
+ first = node.first_element_child
85
+ out.aside **attr_code(anchor: node["id"] || first["id"]) do |a|
86
+ a.t do |p|
87
+ p << note_label(node)
88
+ first.name == "p" and first.children.each { |n| parse(n, p) }
89
+ end
90
+ first.name == "p" and
91
+ node.elements.drop(1).each { |n| parse(n, out) } or
92
+ node.children.each { |n| parse(n, out) }
88
93
  end
89
- first.name == "p" and
90
- node.elements.drop(1).each { |n| parse(n, out) } or
91
- node.children.each { |n| parse(n, out) }
92
94
  end
93
- end
94
95
 
95
- def example_parse(node, out)
96
- example_label(node, out, node.at(ns("./name")))
97
- node.elements.each { |n| parse(n, out) unless n.name == "name" }
98
- end
96
+ def example_parse(node, out)
97
+ example_label(node, out, node.at(ns("./name")))
98
+ node.elements.each { |n| parse(n, out) unless n.name == "name" }
99
+ end
99
100
 
100
- def example_label(node, div, name)
101
- n = @xrefs.get[node["id"]]
102
- div.t **attr_code(anchor: node["id"], keepWithNext: "true") do |p|
103
- lbl = n.nil? || n[:label].nil? || n[:label].empty? ? @i18n.example :
104
- l10n("#{@i18n.example} #{n[:label]}")
105
- p << lbl
106
- name and !lbl.nil? and p << ": "
107
- name and name.children.each { |n| parse(n, p) }
101
+ def example_label(node, div, name)
102
+ n = @xrefs.get[node["id"]]
103
+ div.t **attr_code(anchor: node["id"], keepWithNext: "true") do |p|
104
+ lbl = if n.nil? || n[:label].nil? || n[:label].empty?
105
+ @i18n.example
106
+ else
107
+ l10n("#{@i18n.example} #{n[:label]}")
108
+ end
109
+ p << lbl
110
+ name and !lbl.nil? and p << ": "
111
+ name and name.children.each { |n| parse(n, p) }
112
+ end
108
113
  end
109
- end
110
114
 
111
- def sourcecode_parse(node, out)
112
- out.sourcecode **attr_code(
113
- anchor: node["id"], type: node["lang"], name: node["filename"],
114
- markers: node["markers"], src: node["src"]
115
- ) do |s|
116
- node.children.each { |x| parse(x, s) unless x.name == "name" }
115
+ def sourcecode_parse(node, out)
116
+ out.sourcecode **attr_code(
117
+ anchor: node["id"], type: node["lang"], name: node["filename"],
118
+ markers: node["markers"], src: node["src"]
119
+ ) do |s|
120
+ node.children.each { |x| parse(x, s) unless x.name == "name" }
121
+ end
117
122
  end
118
- end
119
123
 
120
- def pre_parse(node, out)
121
- out.artwork **attr_code(anchor: node["id"], align: node["align"],
122
- alt: node["alt"], type: "ascii-art") do |s|
123
- s.cdata node.text.sub(/^\n/, "").gsub(/\t/, " ")
124
+ def pre_parse(node, out)
125
+ out.artwork **attr_code(anchor: node["id"], align: node["align"],
126
+ alt: node["alt"], type: "ascii-art") do |s|
127
+ s.cdata node.text.sub(/^\n/, "").gsub(/\t/, " ")
128
+ end
124
129
  end
125
- end
126
130
 
127
- def annotation_parse(node, out)
128
- @sourcecode = false
129
- @annotation = true
130
- node.at("./preceding-sibling::*[local-name() = 'annotation']") or
131
- out << "\n\n"
132
- callout = node.at(ns("//callout[@target='#{node['id']}']"))
133
- out << "\n&lt;#{callout.text}&gt; "
134
- out << node&.children&.text&.strip
135
- @annotation = false
136
- end
131
+ def annotation_parse(node, out)
132
+ @sourcecode = false
133
+ @annotation = true
134
+ node.at("./preceding-sibling::*[local-name() = 'annotation']") or
135
+ out << "\n\n"
136
+ callout = node.at(ns("//callout[@target='#{node['id']}']"))
137
+ out << "\n&lt;#{callout.text}&gt; "
138
+ out << node&.children&.text&.strip
139
+ @annotation = false
140
+ end
137
141
 
138
- def formula_where(dl, out)
139
- return unless dl
142
+ def formula_where(dl, out)
143
+ return unless dl
140
144
 
141
- out.t { |p| p << @i18n.where }
142
- parse(dl, out)
143
- end
145
+ out.t { |p| p << @i18n.where }
146
+ parse(dl, out)
147
+ end
144
148
 
145
- def formula_parse1(node, out)
146
- out.t **attr_code(anchor: node["id"]) do |p|
147
- parse(node.at(ns("./stem")), p)
148
- lbl = @xrefs.anchor(node["id"], :label, false)
149
- lbl.nil? or
150
- p << " (#{lbl})"
149
+ def formula_parse1(node, out)
150
+ out.t **attr_code(anchor: node["id"]) do |p|
151
+ parse(node.at(ns("./stem")), p)
152
+ lbl = @xrefs.anchor(node["id"], :label, false)
153
+ lbl.nil? or
154
+ p << " (#{lbl})"
155
+ end
151
156
  end
152
- end
153
157
 
154
- def formula_parse(node, out)
155
- formula_parse1(node, out)
156
- formula_where(node.at(ns("./dl")), out)
157
- node.children.each do |n|
158
- next if %w(stem dl).include? n.name
158
+ def formula_parse(node, out)
159
+ formula_parse1(node, out)
160
+ formula_where(node.at(ns("./dl")), out)
161
+ node.children.each do |n|
162
+ next if %w(stem dl).include? n.name
159
163
 
160
- parse(n, out)
164
+ parse(n, out)
165
+ end
161
166
  end
162
- end
163
167
 
164
- def quote_attribution(node)
165
- author = node&.at(ns("./author"))&.text
166
- source = node&.at(ns("./source/@uri"))&.text
167
- attr_code(quotedFrom: author, cite: source)
168
- end
168
+ def quote_attribution(node)
169
+ author = node&.at(ns("./author"))&.text
170
+ source = node&.at(ns("./source/@uri"))&.text
171
+ attr_code(quotedFrom: author, cite: source)
172
+ end
169
173
 
170
- def quote_parse(node, out)
171
- out.blockquote **quote_attribution(node) do |p|
172
- node.children.each do |n|
173
- parse(n, p) unless ["author", "source"].include? n.name
174
+ def quote_parse(node, out)
175
+ out.blockquote **quote_attribution(node) do |p|
176
+ node.children.each do |n|
177
+ parse(n, p) unless ["author", "source"].include? n.name
178
+ end
174
179
  end
175
180
  end
176
- end
177
181
 
178
- def admonition_name_parse(_node, div, name)
179
- div.t **{ keepWithNext: "true" } do |p|
180
- name.children.each { |n| parse(n, p) }
182
+ def admonition_name_parse(_node, div, name)
183
+ div.t **{ keepWithNext: "true" } do |p|
184
+ name.children.each { |n| parse(n, p) }
185
+ end
181
186
  end
182
- end
183
187
 
184
- def admonition_parse(node, out)
185
- type = node["type"]
186
- name = admonition_name(node, type)
187
- out.aside **{ anchor: node["id"] } do |t|
188
- admonition_name_parse(node, t, name) if name
189
- node.children.each { |n| parse(n, t) unless n.name == "name" }
188
+ def admonition_parse(node, out)
189
+ type = node["type"]
190
+ name = admonition_name(node, type)
191
+ out.aside **{ anchor: node["id"] } do |t|
192
+ admonition_name_parse(node, t, name) if name
193
+ node.children.each { |n| parse(n, t) unless n.name == "name" }
194
+ end
190
195
  end
191
- end
192
196
 
193
- def review_note_parse(node, out)
194
- out.cref **attr_code(anchor: node["id"], display: node["display"],
195
- source: node["reviewer"]) do |c|
196
- name = node.at(ns("./name")) and c.name do |div|
197
- name.children.each { |n| parse(n, div) }
197
+ def review_note_parse(node, out)
198
+ out.cref **attr_code(anchor: node["id"], display: node["display"],
199
+ source: node["reviewer"]) do |c|
200
+ name = node.at(ns("./name")) and c.name do |div|
201
+ name.children.each { |n| parse(n, div) }
202
+ end
203
+ node.children.each { |n| parse(n, c) unless n.name == "name" }
198
204
  end
199
- node.children.each { |n| parse(n, c) unless n.name == "name" }
200
205
  end
201
- end
202
206
 
203
- def figure_name_parse(_node, div, name)
204
- return if name.nil?
207
+ def figure_name_parse(_node, div, name)
208
+ return if name.nil?
205
209
 
206
- div.name do |n|
207
- name.children.each { |n| parse(n, div) }
210
+ div.name do |_n|
211
+ name.children.each { |n| parse(n, div) }
212
+ end
208
213
  end
209
- end
210
214
 
211
- def pseudocode_parse(node, out)
212
- sourcecode_parse(node, out)
213
- end
215
+ def pseudocode_parse(node, out)
216
+ sourcecode_parse(node, out)
217
+ end
214
218
 
215
- def figure_parse(node, out)
216
- return pseudocode_parse(node, out) if node["class"] == "pseudocode" ||
217
- node["type"] == "pseudocode"
219
+ def figure_parse(node, out)
220
+ return pseudocode_parse(node, out) if node["class"] == "pseudocode" ||
221
+ node["type"] == "pseudocode"
218
222
 
219
- @in_figure = true
220
- out.figure **attr_code(anchor: node["id"]) do |div|
221
- figure_name_parse(node, div, node.at(ns("./name")))
222
- node.children.each do |n|
223
- parse(n, div) unless n.name == "name"
223
+ @in_figure = true
224
+ out.figure **attr_code(anchor: node["id"]) do |div|
225
+ figure_name_parse(node, div, node.at(ns("./name")))
226
+ node.children.each do |n|
227
+ parse(n, div) unless n.name == "name"
228
+ end
224
229
  end
230
+ @in_figure = false
225
231
  end
226
- @in_figure = false
232
+
233
+ def toc_parse(_node, _out); end
227
234
  end
228
235
  end
229
236
  end
@@ -1,164 +1,174 @@
1
- module IsoDoc::Ietf
2
- class RfcConvert < ::IsoDoc::Convert
3
- # TODO displayreference will be implemented as combination of autofetch and user-provided citations
4
-
5
- def bibliography(isoxml, out)
6
- isoxml.xpath(ns("//references/bibitem/docidentifier")).each do |i|
7
- i.children = docid_prefix(i["type"], i.text)
8
- end
9
- isoxml.xpath(ns("//bibliography/references | "\
10
- "//bibliography/clause[.//references] | "\
11
- "//annex/clause[.//references] | "\
12
- "//annex/references | "\
13
- "//sections/clause[.//references]")).each do |f|
14
- bibliography1(f, out)
1
+ module IsoDoc
2
+ module Ietf
3
+ class RfcConvert < ::IsoDoc::Convert
4
+ # TODO displayreference will be implemented as combination of autofetch and user-provided citations
5
+
6
+ def bibliography(isoxml, out)
7
+ isoxml.xpath(ns("//references/bibitem/docidentifier")).each do |i|
8
+ i.children = docid_prefix(i["type"], i.text)
9
+ end
10
+ isoxml.xpath(ns("//bibliography/references | "\
11
+ "//bibliography/clause[.//references] | "\
12
+ "//annex/clause[.//references] | "\
13
+ "//annex/references | "\
14
+ "//sections/clause[.//references]")).each do |f|
15
+ bibliography1(f, out)
16
+ end
15
17
  end
16
- end
17
18
 
18
- def bibliography1(f, out)
19
- out.references **attr_code(anchor: f["id"]) do |div|
20
- title = f.at(ns("./title")) and div.name do |name|
21
- title.children.each { |n| parse(n, name) }
19
+ def bibliography1(node, out)
20
+ out.references **attr_code(anchor: node["id"]) do |div|
21
+ title = node.at(ns("./title")) and div.name do |name|
22
+ title.children.each { |n| parse(n, name) }
23
+ end
24
+ node.elements.select do |e|
25
+ %w(references clause).include? e.name
26
+ end.each { |e| bibliography1(e, out) }
27
+ node.elements.reject do |e|
28
+ %w(references title bibitem note).include? e.name
29
+ end.each { |e| parse(e, div) }
30
+ biblio_list(node, div, true)
22
31
  end
23
- f.elements.select do |e|
24
- %w(references clause).include? e.name
25
- end.each { |e| bibliography1(e, out) }
26
- f.elements.reject do |e|
27
- %w(references title bibitem note).include? e.name
28
- end.each { |e| parse(e, div) }
29
- biblio_list(f, div, true)
30
32
  end
31
- end
32
33
 
33
- def biblio_list(f, div, biblio)
34
- i = 0
35
- f.xpath(ns("./bibitem | ./note")).each do |b|
36
- next if implicit_reference(b)
34
+ def biblio_list(node, div, biblio)
35
+ i = 0
36
+ node.xpath(ns("./bibitem | ./note")).each do |b|
37
+ next if implicit_reference(b)
37
38
 
38
- i += 1 if b.name == "bibitem"
39
- if b.name == "note" then note_parse(b, div)
40
- elsif is_ietf(b) then ietf_bibitem_entry(div, b, i)
41
- else
42
- nonstd_bibitem(div, b, i, biblio)
39
+ i += 1 if b.name == "bibitem"
40
+ if b.name == "note" then note_parse(b, div)
41
+ elsif ietf?(b) then ietf_bibitem_entry(div, b, i)
42
+ else
43
+ nonstd_bibitem(div, b, i, biblio)
44
+ end
43
45
  end
44
46
  end
45
- end
46
47
 
47
- def nonstd_bibitem(list, b, _ordinal, _bibliography)
48
- uris = b.xpath(ns("./uri"))
49
- target = nil
50
- uris&.each do |u|
51
- target = u.text if u["type"] == "src"
52
- end
53
- list.reference **attr_code(target: target,
54
- anchor: b["id"]) do |r|
55
- r.front do |f|
56
- relaton_to_title(b, f)
57
- relaton_to_author(b, f)
58
- relaton_to_date(b, f)
59
- relaton_to_keyword(b, f)
60
- relaton_to_abstract(b, f)
61
- end
62
- uris&.each do |u|
63
- r.format nil, **attr_code(target: u.text, type: u["type"])
64
- end
65
- docidentifiers = b.xpath(ns("./docidentifier"))
66
- id = render_identifier(bibitem_ref_code(b))
67
- !id[1].nil? and id[1] != "(NO ID)" and
68
- r.refcontent id[1]
69
- docidentifiers&.each do |u|
70
- if %w(DOI IETF).include? u["type"]
71
- r.seriesInfo nil, **attr_code(value: u.text.sub(/^DOI /, ""),
72
- name: u["type"])
48
+ def nonstd_bibitem(list, bib, _ordinal, _bibliography)
49
+ uris = bib.xpath(ns("./uri"))
50
+ target = nil
51
+ uris&.each { |u| target = u.text if u["type"] == "src" }
52
+ list.reference **attr_code(target: target,
53
+ anchor: bib["id"]) do |r|
54
+ nonstd_bibitem_front(r, bib)
55
+ uris&.each do |u|
56
+ r.format nil, **attr_code(target: u.text, type: u["type"])
57
+ end
58
+ docidentifiers = bib.xpath(ns("./docidentifier"))
59
+ id = render_identifier(bibitem_ref_code(bib))
60
+ !id[1].nil? && id[1] != "(NO ID)" and r.refcontent id[1]
61
+ docidentifiers&.each do |u|
62
+ if %w(DOI IETF).include? u["type"]
63
+ r.seriesInfo nil, **attr_code(value: u.text.sub(/^DOI /, ""),
64
+ name: u["type"])
65
+ end
73
66
  end
74
67
  end
75
68
  end
76
- end
77
69
 
78
- def relaton_to_title(b, f)
79
- title = b&.at(ns("./title")) || b&.at(ns("./formattedref")) or return
80
- f.title do |t|
81
- title.children.each { |n| parse(n, t) }
70
+ def nonstd_bibitem_front(ref, bib)
71
+ ref.front do |f|
72
+ relaton_to_title(bib, f)
73
+ relaton_to_author(bib, f)
74
+ relaton_to_date(bib, f)
75
+ relaton_to_keyword(bib, f)
76
+ relaton_to_abstract(bib, f)
77
+ end
82
78
  end
83
- end
84
79
 
85
- def relaton_to_author(b, f)
86
- auths = b.xpath(ns("./contributor[xmlns:role/@type = 'author' or "\
87
- "xmlns:role/@type = 'editor']"))
88
- auths.empty? and auths = b.xpath(ns("./contributor[xmlns:role/@type = "\
89
- "'publisher']"))
90
- auths.each do |a|
91
- role = a.at(ns("./role[@type = 'editor']")) ? "editor" : nil
92
- p = a&.at(ns("./person/name")) and
93
- relaton_person_to_author(p, role, f) or
94
- relaton_org_to_author(a&.at(ns("./organization")), role, f)
80
+ def relaton_to_title(bib, node)
81
+ title = bib&.at(ns("./title")) || bib&.at(ns("./formattedref")) or
82
+ return
83
+ node.title do |t|
84
+ title.children.each { |n| parse(n, t) }
85
+ end
95
86
  end
96
- end
97
87
 
98
- def relaton_person_to_author(p, role, f)
99
- fullname = p&.at(ns("./completename"))&.text
100
- surname = p&.at(ns("./surname"))&.text
101
- initials = p&.xpath(ns("./initial"))&.map { |i| i.text }&.join(" ") ||
102
- p&.xpath(ns("./forename"))&.map { |i| i.text[0] }&.join(" ")
103
- initials = nil if initials.empty?
104
- f.author nil,
105
- **attr_code(fullname: fullname, asciiFullname: fullname&.transliterate,
106
- role: role, surname: surname, initials: initials,
107
- asciiSurname: fullname ? surname&.transliterate : nil,
108
- asciiInitials: fullname ? initials&.transliterate : nil)
109
- end
88
+ def relaton_to_author(bib, node)
89
+ auths = bib.xpath(ns("./contributor[xmlns:role/@type = 'author' or "\
90
+ "xmlns:role/@type = 'editor']"))
91
+ auths.empty? and
92
+ auths = bib.xpath(ns("./contributor[xmlns:role/@type = "\
93
+ "'publisher']"))
94
+ auths.each do |a|
95
+ role = a.at(ns("./role[@type = 'editor']")) ? "editor" : nil
96
+ p = a&.at(ns("./person/name")) and
97
+ relaton_person_to_author(p, role, node) or
98
+ relaton_org_to_author(a&.at(ns("./organization")), role, node)
99
+ end
100
+ end
110
101
 
111
- def relaton_org_to_author(o, _role, f)
112
- name = o&.at(ns("./name"))&.text
113
- abbrev = o&.at(ns("./abbreviation"))&.text
114
- f.author do |_a|
115
- f.organization name, **attr_code(ascii: name&.transliterate,
116
- abbrev: abbrev)
102
+ def relaton_person_to_author(pers, role, node)
103
+ full = pers&.at(ns("./completename"))&.text
104
+ surname = pers&.at(ns("./surname"))&.text
105
+ initials = pers&.xpath(ns("./initial"))&.map do |i|
106
+ i.text
107
+ end&.join(" ") ||
108
+ pers&.xpath(ns("./forename"))&.map { |i| i.text[0] }&.join(" ")
109
+ initials = nil if initials.empty?
110
+ node.author nil, **attr_code(
111
+ fullname: full,
112
+ asciiFullname: full&.transliterate,
113
+ role: role, surname: surname,
114
+ initials: initials,
115
+ asciiSurname: full ? surname&.transliterate : nil,
116
+ asciiInitials: full ? initials&.transliterate : nil
117
+ )
117
118
  end
118
- end
119
119
 
120
- def relaton_to_date(b, f)
121
- date = b.at(ns("./date[@type = 'published']")) ||
122
- b.at(ns("./date[@type = 'issued']")) ||
123
- b.at(ns("./date[@type = 'circulated']"))
124
- return unless date
120
+ def relaton_org_to_author(org, _role, node)
121
+ name = org&.at(ns("./name"))&.text
122
+ abbrev = org&.at(ns("./abbreviation"))&.text
123
+ node.author do |_a|
124
+ node.organization name, **attr_code(ascii: name&.transliterate,
125
+ abbrev: abbrev)
126
+ end
127
+ end
125
128
 
126
- attr = date_attr(date&.at(ns("./on | ./from"))&.text) || return
127
- f.date **attr_code(attr)
128
- end
129
+ def relaton_to_date(bib, node)
130
+ date = bib.at(ns("./date[@type = 'published']")) ||
131
+ bib.at(ns("./date[@type = 'issued']")) ||
132
+ bib.at(ns("./date[@type = 'circulated']"))
133
+ return unless date
129
134
 
130
- def relaton_to_keyword(b, f)
131
- b.xpath(ns("./keyword")).each do |k|
132
- f.keyword do |keyword|
133
- k.children.each { |n| parse(n, keyword) }
135
+ attr = date_attr(date&.at(ns("./on | ./from"))&.text) || return
136
+ node.date **attr_code(attr)
137
+ end
138
+
139
+ def relaton_to_keyword(bib, node)
140
+ bib.xpath(ns("./keyword")).each do |k|
141
+ node.keyword do |keyword|
142
+ k.children.each { |n| parse(n, keyword) }
143
+ end
134
144
  end
135
145
  end
136
- end
137
146
 
138
- def relaton_to_abstract(b, f)
139
- b.xpath(ns("./abstract")).each do |k|
140
- f.abstract do |abstract|
141
- if k.at(ns("./p"))
142
- k.children.each { |n| parse(n, abstract) }
143
- else
144
- abstract.t do |t|
145
- k.children.each { |n| parse(n, t) }
147
+ def relaton_to_abstract(bib, node)
148
+ bib.xpath(ns("./abstract")).each do |k|
149
+ node.abstract do |abstract|
150
+ if k.at(ns("./p"))
151
+ k.children.each { |n| parse(n, abstract) }
152
+ else
153
+ abstract.t do |t|
154
+ k.children.each { |n| parse(n, t) }
155
+ end
146
156
  end
147
157
  end
148
158
  end
149
159
  end
150
- end
151
160
 
152
- def ietf_bibitem_entry(div, b, _i)
153
- url = b&.at(ns("./uri[@type = 'xml']"))&.text
154
- div << "<xi:include href='#{url}'/>"
155
- end
161
+ def ietf_bibitem_entry(div, bib, _idx)
162
+ url = bib&.at(ns("./uri[@type = 'xml']"))&.text
163
+ div << "<xi:include href='#{url}'/>"
164
+ end
156
165
 
157
- def is_ietf(b)
158
- return false if !@xinclude
166
+ def ietf?(bib)
167
+ return false if !@xinclude
159
168
 
160
- url = b.at(ns("./uri[@type = 'xml']")) or return false
161
- /xml2rfc\.tools\.ietf\.org/.match(url)
169
+ url = bib.at(ns("./uri[@type = 'xml']")) or return false
170
+ /xml2rfc\.tools\.ietf\.org/.match(url)
171
+ end
162
172
  end
163
173
  end
164
174
  end
@@ -1,191 +1,192 @@
1
1
  require "jing"
2
2
  require "fileutils"
3
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)
4
+ module IsoDoc
5
+ module Ietf
6
+ class RfcConvert < ::IsoDoc::Convert
7
+ def schema_validate(filename)
8
+ errors = Jing.new(File.join(File.dirname(__FILE__), "v3.rng"))
9
+ .validate(filename)
10
10
  errors.each do |error|
11
- warn "RFC XML: Line #{"%06d" % error[:line]}:#{error[:column]} "\
12
- "#{error[:message]}"
11
+ warn "RFC XML: Line #{'%06d' % error[:line]}:#{error[:column]} "\
12
+ "#{error[:message]}"
13
13
  end
14
14
  rescue Jing::Error => e
15
15
  abort "Jing failed with error: #{e}"
16
16
  end
17
- end
18
17
 
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
18
+ def content_validate(xml, filename)
19
+ err = []
20
+ err += numbered_sections_check(xml)
21
+ err += toc_sections_check(xml)
22
+ err += references_check(xml)
23
+ err += xref_check(xml)
24
+ err += metadata_check(xml)
25
+ return if err.empty?
31
26
 
32
- def label(sect)
33
- ret = sect&.at("./name")&.text ||
34
- sect["name"] || sect["anchor"]
35
- end
27
+ FileUtils.mv(filename, "#{filename}.err")
28
+ err.each { |e| warn "RFC XML: #{e}" }
29
+ warn "Cannot continue processing"
30
+ end
36
31
 
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
32
+ def label(sect)
33
+ sect&.at("./name")&.text ||
34
+ sect["name"] || sect["anchor"]
51
35
  end
52
- ret
53
- end
54
36
 
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"
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 "\
49
+ "section #{label(s1)}"
50
+ end
62
51
  end
52
+ ret
63
53
  end
64
- ret
65
- end
66
54
 
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"
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
76
63
  end
64
+ ret
77
65
  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
66
 
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
- x.delete("relative") if x["relative"]&.empty?
94
- x.delete("section") if x["section"]&.empty?
95
- if x["format"] == "title" && t.name == "reference"
96
- t.at("./front/title") or
97
- ret << "reference #{t['anchor']} has been referenced by #{x.name} "\
98
- "with format=title, but the reference has no title"
99
- end
100
- if x["format"] == "counter" && !%w(section table figure li
101
- reference references t dt).include?(t.name)
102
- ret << "#{x.to_xml} with format=counter is only allowed for "\
103
- "clauses, tables, figures, list entries, definition terms, "\
104
- "paragraphs, bibliographies, and bibliographic entries"
105
- end
106
- if x["format"] == "counter" && t.name == "reference" && !x["section"]
107
- ret << "reference #{t['anchor']} has been referenced by xref "\
108
- "#{x.to_xml} with format=counter, which requires a "\
109
- "section attribute"
110
- end
111
- if x["format"] == "counter" && t.name == "li" && t.parent.name != "ol"
112
- ret << "#{x.to_xml} with format=counter refers to an unnumbered "\
113
- "list entry"
114
- end
115
- if x["format"] == "title" && %w(u author contact).include?(t.name)
116
- ret << "#{x.to_xml} with format=title cannot reference a "\
117
- "<#{t.name}> element"
118
- end
119
- if x["relative"] && !x["section"]
120
- ret << "#{x.to_xml} with relative attribute requires a section "\
121
- "attribute"
122
- end
123
- if (x["section"]) && t.name != "reference"
124
- ret << "#{x.to_xml} has a section attribute, but #{x['target']} "\
125
- "points to a #{t.name}"
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
126
77
  end
127
- if (x["relative"]) && t.name != "reference"
128
- ret << "#{x.to_xml} has a relative attribute, but #{x['target']} "\
129
- "points to a #{t.name}"
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"
130
81
  end
131
- if !x["relative"] && x["section"]
132
- unless t.at(".//seriesInfo[@name = 'RFC' or @name = "\
133
- "'Internet-Draft']")
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
+
94
+ x.delete("relative") if x["relative"] && x["relative"].empty?
95
+ x.delete("section") if x["section"] && x["section"].empty?
96
+ if x["format"] == "title" && t.name == "reference"
97
+ t.at("./front/title") or
98
+ ret << "reference #{t['anchor']} has been referenced by #{x.name} "\
99
+ "with format=title, but the reference has no title"
100
+ end
101
+ if x["format"] == "counter" && !%w(section table figure li
102
+ reference references t dt).include?(t.name)
103
+ ret << "#{x.to_xml} with format=counter is only allowed for "\
104
+ "clauses, tables, figures, list entries, definition terms, "\
105
+ "paragraphs, bibliographies, and bibliographic entries"
106
+ end
107
+ if x["format"] == "counter" && t.name == "reference" && !x["section"]
108
+ ret << "reference #{t['anchor']} has been referenced by xref "\
109
+ "#{x.to_xml} with format=counter, which requires a "\
110
+ "section attribute"
111
+ end
112
+ if x["format"] == "counter" && t.name == "li" && t.parent.name != "ol"
113
+ ret << "#{x.to_xml} with format=counter refers to an unnumbered "\
114
+ "list entry"
115
+ end
116
+ if x["format"] == "title" && %w(u author contact).include?(t.name)
117
+ ret << "#{x.to_xml} with format=title cannot reference a "\
118
+ "<#{t.name}> element"
119
+ end
120
+ if x["relative"] && !x["section"]
121
+ ret << "#{x.to_xml} with relative attribute requires a section "\
122
+ "attribute"
123
+ end
124
+ if (x["section"]) && t.name != "reference"
125
+ ret << "#{x.to_xml} has a section attribute, but #{x['target']} "\
126
+ "points to a #{t.name}"
127
+ end
128
+ if (x["relative"]) && t.name != "reference"
129
+ ret << "#{x.to_xml} has a relative attribute, but #{x['target']} "\
130
+ "points to a #{t.name}"
131
+ end
132
+ if !x["relative"] && x["section"] && !t.at(".//seriesInfo[@name = 'RFC' or @name = "\
133
+ "'Internet-Draft']")
134
134
  ret << "#{x.to_xml} must use a relative attribute, "\
135
- "since it does not point to a RFC or Internet-Draft reference"
135
+ "since it does not point to a RFC or Internet-Draft reference"
136
136
  end
137
- end
138
- if x["relative"]
139
- unless t.at(".//seriesInfo[@name = 'RFC' or @name = "\
140
- "'Internet-Draft']") || t["target"]
137
+ if x["relative"] && !(t.at(".//seriesInfo[@name = 'RFC' or @name = "\
138
+ "'Internet-Draft']") || t["target"])
141
139
  ret << "need an explicit target= URL attribute in the reference "\
142
- "pointed to by #{x.to_xml}"
140
+ "pointed to by #{x.to_xml}"
143
141
  end
144
142
  end
143
+ ret
145
144
  end
146
- ret
147
- end
148
145
 
149
- def metadata_check(xml)
150
- ret = []
151
- ret += link_check(xml)
152
- ret += seriesInfo_check(xml)
153
- ret += ipr_check(xml)
154
- ret
155
- end
146
+ def metadata_check(xml)
147
+ ret = []
148
+ ret += link_check(xml)
149
+ ret += seriesInfo_check(xml)
150
+ ret += ipr_check(xml)
151
+ ret
152
+ end
156
153
 
157
- # 5.6.3. <link> Processing
158
- def link_check(xml)
159
- l = xml&.at("//link[@rel = 'convertedFrom']")&.text
160
- !l || %r{^https://datatracker\.ietf\.org/doc/draft-}.match(l) or
161
- return ["<link rel='convertedFrom'> (:derived-from: document "\
162
- "attribute) must start with "\
163
- "https://datatracker.ietf.org/doc/draft-"]
164
- []
165
- end
154
+ # 5.6.3. <link> Processing
155
+ def link_check(xml)
156
+ l = xml&.at("//link[@rel = 'convertedFrom']")&.text
157
+ !l || %r{^https://datatracker\.ietf\.org/doc/draft-}.match(l) or
158
+ return ["<link rel='convertedFrom'> (:derived-from: document "\
159
+ "attribute) must start with "\
160
+ "https://datatracker.ietf.org/doc/draft-"]
161
+ []
162
+ end
166
163
 
167
- # 5.2.2. "seriesInfo" Insertion
168
- def seriesInfo_check(xml)
169
- ret = []
170
- xml.root["ipr"] == "none" and return []
171
- rfcinfo = xml.at("//seriesInfo[@name = 'RFC']")
172
- rfcnumber = xml.root["number"]
173
- rfcinfo && rfcnumber && rfcnumber != rfcinfo["value"] and
174
- ret << "Mismatch between <rfc number='#{rfcnumber}'> (:docnumber: NUMBER) "\
175
- "and <seriesInfo name='RFC' value='#{rfcinfo['value']}'> "\
176
- "(:intended-series: TYPE NUMBER)"
177
- rfcinfo && !/^\d+$/.match(rfcnumber) and
178
- ret << "RFC identifier <rfc number='#{rfcnumber}'> (:docnumber: NUMBER) "\
179
- "must be a number"
180
- ret
181
- end
164
+ # 5.2.2. "seriesInfo" Insertion
165
+ def seriesInfo_check(xml)
166
+ ret = []
167
+ xml.root["ipr"] == "none" and return []
168
+ rfcinfo = xml.at("//seriesInfo[@name = 'RFC']")
169
+ rfcnumber = xml.root["number"]
170
+ rfcinfo && rfcnumber && rfcnumber != rfcinfo["value"] and
171
+ ret << "Mismatch between <rfc number='#{rfcnumber}'> "\
172
+ "(: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}'> "\
177
+ "(:docnumber: NUMBER) must be a number"
178
+ ret
179
+ end
182
180
 
183
- # 5.4.2.3. "Copyright Notice" Insertion
184
- def ipr_check(xml)
185
- xml.root["ipr"] or return ["Missing ipr attribute on <rfc> element (:ipr:)"]
186
- /trust200902$/.match(xml.root["ipr"]) or
187
- return ["Unknown ipr attribute on <rfc> element (:ipr:): #{xml.root['ipr']}"]
188
- []
181
+ # 5.4.2.3. "Copyright Notice" Insertion
182
+ def ipr_check(xml)
183
+ xml.root["ipr"] or
184
+ return ["Missing ipr attribute on <rfc> element (:ipr:)"]
185
+ /trust200902$/.match(xml.root["ipr"]) or
186
+ return ["Unknown ipr attribute on <rfc> element (:ipr:): "\
187
+ "#{xml.root['ipr']}"]
188
+ []
189
+ end
189
190
  end
190
191
  end
191
192
  end
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  module Ietf
3
- VERSION = "2.4.0".freeze
3
+ VERSION = "2.4.1".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.4.0
4
+ version: 2.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-02 00:00:00.000000000 Z
11
+ date: 2021-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: isodoc