metanorma-ietf 2.4.0 → 2.4.1

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 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