relaton-ietf 1.9.0 → 1.9.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: de34f43de3864f7494ab3931162ecff103d9f2f66828374bc26ccc91da3c3295
4
- data.tar.gz: 84f76c4b573041e55f60efdf208480c6832129a9a094bc3c12205bc19ba42552
3
+ metadata.gz: 5ed659b3ac3a91f53fa5872cb839be97adeba30e6eba56f211f140e55b5836d8
4
+ data.tar.gz: 8b1c58e40158c126f11ab25c92ca99230a3e00064b8d0fb20ad250c51c01e7b8
5
5
  SHA512:
6
- metadata.gz: d6f0c509201f46a402655f2ea4d75b678cb6c4638715a07cd637c8b5c8fa3dc04254ea914dfcd27eebe024231b8caec5b2435f944bc5d8185622b1b515dff3ab
7
- data.tar.gz: bd93874e76dad53e998abd0988aba64354a7a5d011141f57e945bb2a2e7c690e0b790c58a343070160bee77d2e8cb7332fe5b2a59d2c983b3222e9bc55db09f7
6
+ metadata.gz: 163f11e5a49d8dd44d6592c1741281b8756f505ac49feb59d3a508ec2ad7340498db0a5d71a1ccfbbc8c4de385ee967388119238f0c4f94641a839623fe19c65
7
+ data.tar.gz: 0a86ac885aca2d200e5d64cdee74e0b4b5e6d42f77a5e9fb60c233e77e19c176137ebc8220a7397e56e6564edcd58c09933553810a4265597fbc7e64c02a173b
data/README.adoc CHANGED
@@ -90,6 +90,21 @@ item.to_xml bibdata: true
90
90
  </bibdata>"
91
91
  ----
92
92
 
93
+ === Typed links
94
+
95
+ IETF documents may have `src`, `xml`, and `doi` link type.
96
+
97
+ * `src` - web pulication
98
+ * `xml` - BibXML publication
99
+ * `doi` - DOI reference
100
+
101
+ [source,ruby]
102
+ ----
103
+ item.link
104
+ => [#<RelatonBib::TypedUri:0x00007fe8b287a120 @content=#<Addressable::URI:0x7e4 URI:https://raw.githubusercontent.com/relaton/relaton-data-ietf/master/data/reference.RFC.8341.xml>, @type="xml">,
105
+ #<RelatonBib::TypedUri:0x00007fe8b2237ec0 @content=#<Addressable::URI:0x7f8 URI:https://www.rfc-editor.org/info/rfc8341>, @type="src">]
106
+ ----
107
+
93
108
  === Parse a file locally
94
109
 
95
110
  [source,ruby]
@@ -0,0 +1,8 @@
1
+ module RelatonIetf
2
+ class Committee < RelatonBib::TechnicalCommittee
3
+ # @param builder [Nokogiri::XML::Builder]
4
+ def to_xml(builder)
5
+ builder.committee { |b| workgroup.to_xml b }
6
+ end
7
+ end
8
+ end
@@ -21,7 +21,7 @@ module RelatonIetf
21
21
  # @return [RelatonIetf::IetfBibliographicItem]
22
22
  def self.from_hash(hash)
23
23
  item_hash = ::RelatonIetf::HashConverter.hash_to_bib(hash)
24
- new **item_hash
24
+ new(**item_hash)
25
25
  end
26
26
 
27
27
  # @param opts [Hash]
@@ -32,7 +32,7 @@ module RelatonIetf
32
32
  # @return [String] XML
33
33
  def to_xml(**opts)
34
34
  opts[:date_format] ||= :short
35
- super **opts
35
+ super(**opts)
36
36
  end
37
37
  end
38
38
  end
@@ -5,365 +5,372 @@ require "relaton_bib"
5
5
  require "relaton_ietf/ietf_bibliographic_item"
6
6
 
7
7
  module RelatonIetf
8
- # rubocop:disable Metrics/ModuleLength
9
-
10
8
  # Scrapper module
11
9
  module Scrapper
12
- GH_URL = "https://raw.githubusercontent.com/relaton/relaton-data-ietf/master/data/reference."
13
- BCP_URI_PATTERN = "https://www.rfc-editor.org/info/CODE"
14
-
15
- class << self
16
- # @param text [String]
17
- # @param is_relation [TrueClass, FalseClass]
18
- # @return [RelatonIetf::IetfBibliographicItem]
19
- def scrape_page(text, is_relation: false)
20
- # Remove initial "IETF " string if specified
21
- ref = text.gsub(/^IETF /, "")
22
- /^(?:RFC|BCP|FYI|STD)\s(?<num>\d+)/ =~ ref
23
- ref.sub! /(?<=^(?:RFC|BCP|FYI|STD)\s)(\d+)/, num.rjust(4, "0") if num
24
- rfc_item ref, is_relation
25
- rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
26
- Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
27
- Net::ProtocolError, SocketError
28
- raise RelatonBib::RequestError, "No document found for #{ref} reference"
29
- end
30
-
31
- # @param reference [Nokogiri::XML::Element, nil]
32
- # @param is_relation [TrueClass, FalseClass]
33
- # @param url [String, NilClass]
34
- # @param ver [String, NilClass] Internet Draft version
35
- # @return [RelatonIetf::IetfBibliographicItem]
36
- def fetch_rfc(reference, is_relation: false, url: nil, ver: nil) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
37
- return unless reference
38
-
39
- ietf_item(
40
- is_relation: is_relation,
41
- id: reference[:anchor],
42
- type: "standard",
43
- docid: docids(reference, ver),
44
- status: status(reference),
45
- language: [language(reference)],
46
- link: link(reference, url, ver),
47
- title: titles(reference),
48
- formattedref: formattedref(reference),
49
- abstract: abstracts(reference),
50
- contributor: contributors(reference),
51
- relation: relations(reference),
52
- date: dates(reference),
53
- series: series(reference),
54
- place: ["Fremont, CA"],
55
- keyword: reference.xpath("front/keyword").map(&:text),
56
- doctype: doctype(reference[:anchor]),
57
- )
58
- end
59
-
60
- private
61
-
62
- # @param anchor [String]
63
- # @return [String]
64
- def doctype(anchor)
65
- anchor&.include?("I-D") ? "internet-draft" : "rfc"
66
- end
67
-
68
- # @param reference [Nokogiri::XML::Element]
69
- # @param url [String]
70
- # @param ver [String, NilClass] Internet Draft version
71
- # @return [Array<Hash>]
72
- def link(reference, url, ver)
73
- l = []
74
- l << { type: "xml", content: url } if url
75
- l << { type: "src", content: reference[:target] } if reference[:target]
76
- if /^I-D/.match? reference[:anchor]
77
- reference.xpath("format").each do |f|
78
- c = ver ? f[:target].sub(/(?<=-)\d{2}(?=\.)/, ver) : f[:target]
79
- l << { type: f[:type], content: c }
80
- end
81
- end
82
- l
83
- end
84
-
85
- # @param attrs [Hash]
86
- # @return [RelatonIetf::IetfBibliographicItem]
87
- def ietf_item(**attrs)
88
- attrs[:fetched] = Date.today.to_s unless attrs.delete(:is_relation)
89
- attrs[:script] = ["Latn"]
90
- RelatonIetf::IetfBibliographicItem.new **attrs
91
- end
92
-
93
- # @param ref [String]
94
- # @param is_relation [Boolen, nil]
95
- # @return [RelatonIetf::IetfBibliographicItem]
96
- def rfc_item(ref, is_relation)
97
- /(?<=-)(?<ver>\d{2})$/ =~ ref
98
- if /^I-D/.match? ref
99
- ref.sub! /-\d{2}/, "" if ver
100
- ref.sub! /(?<=I-D\.)draft-/, ""
101
- end
102
-
103
- uri = "#{GH_URL}#{ref.sub(/\s|\u00a0/, '.')}.xml"
104
- doc = Nokogiri::XML get_page(uri)
105
- r = doc.at("/referencegroup", "/reference")
106
- fetch_rfc r, is_relation: is_relation, url: uri, ver: ver
107
- end
108
-
109
- # @param reference [Nokogiri::XML::Element]
110
- # @return [Hash]
111
- def relations(reference)
112
- reference.xpath("reference").map do |ref|
113
- { type: "includes", bibitem: fetch_rfc(ref, is_relation: true) }
114
- end
115
- end
116
-
117
- # @param uri [String]
118
- # @return [String] HTTP response body
119
- def get_page(uri)
120
- res = Net::HTTP.get_response(URI(uri))
121
- return unless res.code == "200"
122
-
123
- # raise RelatonBib::RequestError, "No document found at #{uri}"
124
- # end
125
-
126
- res.body
127
- end
128
-
129
- # @param reference [Nokogiri::XML::Element]
130
- # @return [String]
131
- def language(reference)
132
- reference[:lang] || "en"
133
- end
10
+ extend RelatonBib::BibXMLParser
11
+ extend Scrapper
134
12
 
135
- # @param reference [Nokogiri::XML::Element]
136
- # @return [Array<Hash>]
137
- def titles(reference)
138
- reference.xpath("./front/title").map do |title|
139
- { content: title.text, language: language(reference), script: "Latn" }
140
- end
141
- end
13
+ FLAVOR = "IETF"
142
14
 
143
- # @param reference [Nokogiri::XML::Element]
144
- # @return [RelatonBib::FormattedRef, nil]
145
- def formattedref(reference)
146
- return if reference.at "./fornt/title"
147
-
148
- cont = (reference[:anchor] || reference[:docName] || reference[:number])
149
- if cont
150
- RelatonBib::FormattedRef.new(
151
- content: cont, language: language(reference), script: "Latn",
152
- )
153
- end
154
- end
155
-
156
- # @param reference [Nokogiri::XML::Element]
157
- # @return [Array<RelatonBib::FormattedString>]
158
- def abstracts(ref)
159
- ref.xpath("./front/abstract").map do |a|
160
- RelatonBib::FormattedString.new(
161
- content: a.text.gsub(/\\n\\t{2,4}/, " ").strip,
162
- language: language(ref), script: "Latn"
163
- )
164
- end
165
- end
166
-
167
- # @param reference [Nokogiri::XML::Element]
168
- # @return [Array<Hash>]
169
- def contributors(reference)
170
- persons(reference) + organizations(reference)
171
- end
172
-
173
- # @param reference [Nokogiri::XML::Element]
174
- # @return [Array<Hash{Symbol=>RelatonBib::Person,Symbol=>Array<String>}>]
175
- def persons(reference)
176
- reference.xpath("./front/author[@surname]|./front/author[@fullname]")
177
- .map do |author|
178
- entity = RelatonBib::Person.new(
179
- name: full_name(author, reference),
180
- affiliation: [affiliation(author)],
181
- contact: contacts(author.at("./address")),
182
- )
183
- { entity: entity, role: [contributor_role(author)] }
184
- end
185
- end
186
-
187
- # @param reference [Nokogiri::XML::Element]
188
- # @return [Array<Hash{Symbol=>RelatonBib::Organization,
189
- # Symbol=>Array<String>}>]
190
- def organizations(reference)
191
- publisher = { entity: new_org, role: [type: "publisher"] }
192
- orgs = reference.xpath("./seriesinfo").reduce([publisher]) do |mem, si|
193
- next mem unless si[:stream]
194
-
195
- mem << { entity: new_org(si[:stream], nil), role: [type: "author"] }
196
- end
197
- orgs + reference.xpath(
198
- "front/author[not(@surname)][not(@fullname)]/organization",
199
- ).map do |org|
200
- { entity: new_org(org.text, nil), role: [type: "author"] }
201
- end
202
- end
203
-
204
- # @param author [Nokogiri::XML::Element]
205
- # @param ref [Nokogiri::XML::Element]
206
- # @return [RelatonBib::FullName]
207
- def full_name(author, ref)
208
- lang = language ref
209
- RelatonBib::FullName.new(
210
- completename: localized_string(author[:fullname], lang),
211
- initial: [localized_string(author[:initials], lang)].compact,
212
- surname: localized_string(author[:surname], lang),
213
- )
214
- end
215
-
216
- # @param content [String]
217
- # @param lang [String]
218
- # @return [RelatonBib::LocalizedString]
219
- def localized_string(content, lang)
220
- return unless content
221
-
222
- RelatonBib::LocalizedString.new(content, lang)
223
- end
224
-
225
- # @param postal [Nokogiri::XML::Element]
226
- # @return [Array<RelatonBib::Address, RelatonBib::Phone>]
227
- def contacts(addr)
228
- contacts = []
229
- return contacts unless addr
230
-
231
- postal = addr.at("./postal")
232
- contacts << address(postal) if postal
233
- add_contact(contacts, "phone", addr.at("./phone"))
234
- add_contact(contacts, "email", addr.at("./email"))
235
- add_contact(contacts, "uri", addr.at("./uri"))
236
- contacts
237
- end
238
-
239
- # @param postal [Nokogiri::XML::Element]
240
- # @rerurn [RelatonBib::Address]
241
- def address(postal) # rubocop:disable Metrics/CyclomaticComplexity
242
- RelatonBib::Address.new(
243
- street: [(postal.at("./postalLine") || postal.at("./street"))&.text],
244
- city: postal.at("./city")&.text,
245
- postcode: postal.at("./code")&.text,
246
- country: postal.at("./country")&.text,
247
- state: postal.at("./region")&.text,
248
- )
249
- end
250
-
251
- # @param type [String] allowed "phone", "email" or "uri"
252
- # @param value [String]
253
- def add_contact(contacts, type, value)
254
- return unless value
255
-
256
- contacts << RelatonBib::Contact.new(type: type, value: value.text)
257
- end
258
-
259
- # @param author [Nokogiri::XML::Element]
260
- # @return [RelatonBib::Affiliation]
261
- def affiliation(author)
262
- organization = author.at("./organization")
263
- org = if organization.nil? || organization&.text&.empty?
264
- new_org
265
- else
266
- new_org organization.text, organization[:abbrev]
267
- end
268
- RelatonBib::Affiliation.new organization: org
269
- end
270
-
271
- # @param name [String]
272
- # @param abbr [String]
273
- # @return [RelatonBib::Organization]
274
- def new_org(name = "Internet Engineering Task Force", abbr = "IETF")
275
- RelatonBib::Organization.new name: name, abbreviation: abbr
276
- end
277
-
278
- # @param author [Nokogiri::XML::Document]
279
- # @return [Hash]
280
- def contributor_role(author)
281
- { type: author[:role] || "author" }
282
- end
15
+ GH_URL = "https://raw.githubusercontent.com/relaton/relaton-data-ietf/master/data/reference."
283
16
 
284
- def month(mon)
285
- return 1 if !mon || mon.empty?
286
- return mon if /^\d+$/.match? mon
17
+ # @param text [String]
18
+ # @param is_relation [TrueClass, FalseClass]
19
+ # @return [RelatonIetf::IetfBibliographicItem]
20
+ def scrape_page(text, is_relation: false)
21
+ # Remove initial "IETF " string if specified
22
+ ref = text.gsub(/^IETF /, "")
23
+ /^(?:RFC|BCP|FYI|STD)\s(?<num>\d+)/ =~ ref
24
+ ref.sub!(/(?<=^(?:RFC|BCP|FYI|STD)\s)(\d+)/, num.rjust(4, "0")) if num
25
+ rfc_item ref, is_relation
26
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
27
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
28
+ Net::ProtocolError, SocketError
29
+ raise RelatonBib::RequestError, "No document found for #{ref} reference"
30
+ end
287
31
 
288
- Date::MONTHNAMES.index(mon)
32
+ # @param reference [Nokogiri::XML::Element, nil]
33
+ # @param is_relation [Boolean] don't add fetched date for relation
34
+ # @param url [String, NilClass]
35
+ # @param ver [String, NilClass] Internet Draft version
36
+ # @return [RelatonBib::tfBibliographicItem]
37
+ # def fetch_rfc(reference, is_relation: false, url: nil, ver: nil) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
38
+ # return unless reference
39
+
40
+ # hash = {
41
+ # id: reference[:anchor],
42
+ # type: "standard",
43
+ # docid: docids(reference, ver),
44
+ # status: status(reference),
45
+ # language: [language(reference)],
46
+ # script: ["Latn"],
47
+ # link: link(reference, url, ver),
48
+ # title: titles(reference),
49
+ # formattedref: formattedref(reference),
50
+ # abstract: abstracts(reference),
51
+ # contributor: contributors(reference),
52
+ # relation: relations(reference),
53
+ # date: dates(reference),
54
+ # series: series(reference),
55
+ # keyword: reference.xpath("front/keyword").map(&:text),
56
+ # doctype: doctype(reference[:anchor]),
57
+ # }
58
+ # hash[:fetched] = Date.today.to_s unless is_relation
59
+ # bib_item(**hash)
60
+ # end
61
+
62
+ private
63
+
64
+ # @param anchor [String]
65
+ # @return [String]
66
+ # def doctype(anchor)
67
+ # anchor&.include?("I-D") ? "internet-draft" : "rfc"
68
+ # end
69
+
70
+ # @param reference [Nokogiri::XML::Element]
71
+ # @param url [String]
72
+ # @param ver [String, NilClass] Internet Draft version
73
+ # @return [Array<Hash>]
74
+ # def link(reference, url, ver)
75
+ # l = []
76
+ # l << { type: "xml", content: url } if url
77
+ # l << { type: "src", content: reference[:target] } if reference[:target]
78
+ # if /^I-D/.match? reference[:anchor]
79
+ # reference.xpath("format").each do |f|
80
+ # c = ver ? f[:target].sub(/(?<=-)\d{2}(?=\.)/, ver) : f[:target]
81
+ # l << { type: f[:type], content: c }
82
+ # end
83
+ # end
84
+ # l
85
+ # end
86
+
87
+ # @param attrs [Hash]
88
+ # @return [RelatonIetf::IetfBibliographicItem]
89
+ def bib_item(**attrs)
90
+ unless attrs.delete(:is_relation)
91
+ attrs[:fetched] = Date.today.to_s
92
+ attrs[:place] = ["Fremont, CA"]
289
93
  end
94
+ RelatonIetf::IetfBibliographicItem.new(**attrs)
95
+ end
290
96
 
291
- #
292
- # Extract date from reference.
293
- #
294
- # @param reference [Nokogiri::XML::Element]
295
- # @return [Array<RelatonBib::BibliographicDate>] published data.
296
- #
297
- def dates(reference)
298
- return unless (date = reference.at "./front/date")
299
-
300
- d = [date[:year], month(date[:month]),
301
- (date[:day] || 1)].compact.join "-"
302
- date = Time.parse(d).strftime "%Y-%m-%d"
303
- [RelatonBib::BibliographicDate.new(type: "published", on: date)]
97
+ # @param ref [String]
98
+ # @param is_relation [Boolen, nil]
99
+ # @return [RelatonIetf::IetfBibliographicItem]
100
+ def rfc_item(ref, is_relation)
101
+ /(?<=-)(?<ver>\d{2})$/ =~ ref
102
+ if /^I-D/.match? ref
103
+ ref.sub!(/-\d{2}/, "") if ver
104
+ ref.sub!(/(?<=I-D\.)draft-/, "")
304
105
  end
305
106
 
306
- #
307
- # Extract document identifiers from reference
308
- #
309
- # @param reference [Nokogiri::XML::Element]
310
- # @param ver [String, NilClass] Internet Draft version
311
- #
312
- # @return [Array<RelatonBib::DocumentIdentifier>]
313
- #
314
- def docids(reference, ver) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize
315
- id = (reference[:anchor] || reference[:docName] || reference[:number])
316
- ret = []
317
- if id
318
- ret << RelatonBib::DocumentIdentifier.new(
319
- type: "IETF", id: id.sub(/^(RFC)/, "\\1 "),
320
- )
321
- end
322
- if (id = reference[:anchor])
323
- ret << RelatonBib::DocumentIdentifier.new(type: "rfc-anchor", id: id)
324
- end
325
- ret + reference.xpath("./seriesInfo").map do |si|
326
- next unless ["DOI", "Internet-Draft"].include? si[:name]
327
-
328
- id = si[:value]
329
- id.sub! /(?<=-)\d{2}$/, ver if ver && si[:name] == "Internet-Draft"
330
- RelatonBib::DocumentIdentifier.new(id: id, type: si[:name])
331
- end.compact
332
- end
107
+ uri = "#{GH_URL}#{ref.sub(/\s|\u00a0/, '.')}.xml"
108
+ # doc = Nokogiri::XML get_page(uri)
109
+ # r = doc.at("/referencegroup", "/reference")
110
+ # fetch_rfc r, is_relation: is_relation, url: uri, ver: ver
111
+ parse get_page(uri), url: uri, is_relation: is_relation, ver: ver
112
+ end
333
113
 
334
- #
335
- # Extract series form reference
336
- # @param reference [Nokogiri::XML::Element]
337
- #
338
- # @return [Array<RelatonBib::Series>]
339
- #
340
- def series(reference)
341
- reference.xpath("./seriesInfo").map do |si|
342
- next if si[:name] == "DOI" || si[:stream] || si[:status]
343
-
344
- RelatonBib::Series.new(
345
- title: RelatonBib::TypedTitleString.new(
346
- content: si[:name], language: language(reference), script: "Latn",
347
- ),
348
- number: si[:value],
349
- type: "main",
350
- )
351
- end.compact
352
- end
114
+ # @param reference [Nokogiri::XML::Element]
115
+ # @return [Hash]
116
+ # def relations(reference)
117
+ # reference.xpath("reference").map do |ref|
118
+ # { type: "includes", bibitem: fetch_rfc(ref, is_relation: true) }
119
+ # end
120
+ # end
121
+
122
+ # @param uri [String]
123
+ # @return [String] HTTP response body
124
+ def get_page(uri)
125
+ res = Net::HTTP.get_response(URI(uri))
126
+ return unless res.code == "200"
127
+
128
+ res.body
129
+ end
353
130
 
354
- #
355
- # extract status
356
- # @param reference [Nokogiri::XML::Element]
357
- #
358
- # @return [RelatonBib::DocumentStatus]
359
- #
360
- def status(reference)
361
- st = reference.at("./seriesinfo[@status]")
362
- return unless st
363
-
364
- RelatonBib::DocumentStatus.new(stage: st[:status])
365
- end
131
+ # @param [RelatonBib::WorkGroup]
132
+ # @return [RelatonIetf::Committee]
133
+ def committee(wgr)
134
+ Committee.new wgr
366
135
  end
136
+
137
+ # @param reference [Nokogiri::XML::Element]
138
+ # @return [String]
139
+ # def language(reference)
140
+ # reference[:lang] || "en"
141
+ # end
142
+
143
+ # @param reference [Nokogiri::XML::Element]
144
+ # @return [Array<Hash>]
145
+ # def titles(reference)
146
+ # reference.xpath("./front/title").map do |title|
147
+ # { content: title.text, language: language(reference), script: "Latn" }
148
+ # end
149
+ # end
150
+
151
+ # @param reference [Nokogiri::XML::Element]
152
+ # @return [RelatonBib::FormattedRef, nil]
153
+ # def formattedref(reference)
154
+ # return if reference.at "./front/title"
155
+
156
+ # cont = (reference[:anchor] || reference[:docName] || reference[:number])
157
+ # if cont
158
+ # RelatonBib::FormattedRef.new(
159
+ # content: cont, language: language(reference), script: "Latn",
160
+ # )
161
+ # end
162
+ # end
163
+
164
+ # @param reference [Nokogiri::XML::Element]
165
+ # @return [Array<RelatonBib::FormattedString>]
166
+ # def abstracts(ref)
167
+ # ref.xpath("./front/abstract").map do |a|
168
+ # RelatonBib::FormattedString.new(
169
+ # content: a.text.gsub(/\\n\\t{2,4}/, " ").strip,
170
+ # language: language(ref), script: "Latn"
171
+ # )
172
+ # end
173
+ # end
174
+
175
+ # @param reference [Nokogiri::XML::Element]
176
+ # @return [Array<Hash>]
177
+ # def contributors(reference)
178
+ # persons(reference) + organizations(reference)
179
+ # end
180
+
181
+ # @param reference [Nokogiri::XML::Element]
182
+ # @return [Array<Hash{Symbol=>RelatonBib::Person,Symbol=>Array<String>}>]
183
+ # def persons(reference)
184
+ # reference.xpath("./front/author[@surname]|./front/author[@fullname]")
185
+ # .map do |author|
186
+ # entity = RelatonBib::Person.new(
187
+ # name: full_name(author, reference),
188
+ # affiliation: [affiliation(author)],
189
+ # contact: contacts(author.at("./address")),
190
+ # )
191
+ # { entity: entity, role: [contributor_role(author)] }
192
+ # end
193
+ # end
194
+
195
+ # @param reference [Nokogiri::XML::Element]
196
+ # @return [Array<Hash{Symbol=>RelatonBib::Organization,
197
+ # Symbol=>Array<String>}>]
198
+ # def organizations(reference)
199
+ # publisher = { entity: new_org, role: [type: "publisher"] }
200
+ # orgs = reference.xpath("./seriesinfo").reduce([publisher]) do |mem, si|
201
+ # next mem unless si[:stream]
202
+
203
+ # mem << { entity: new_org(si[:stream], nil), role: [type: "author"] }
204
+ # end
205
+ # orgs + reference.xpath(
206
+ # "front/author[not(@surname)][not(@fullname)]/organization",
207
+ # ).map do |org|
208
+ # { entity: new_org(org.text, nil), role: [type: "author"] }
209
+ # end
210
+ # end
211
+
212
+ # @param author [Nokogiri::XML::Element]
213
+ # @param ref [Nokogiri::XML::Element]
214
+ # @return [RelatonBib::FullName]
215
+ # def full_name(author, ref)
216
+ # lang = language ref
217
+ # RelatonBib::FullName.new(
218
+ # completename: localized_string(author[:fullname], lang),
219
+ # initial: [localized_string(author[:initials], lang)].compact,
220
+ # surname: localized_string(author[:surname], lang),
221
+ # )
222
+ # end
223
+
224
+ # @param content [String]
225
+ # @param lang [String]
226
+ # @return [RelatonBib::LocalizedString]
227
+ # def localized_string(content, lang)
228
+ # return unless content
229
+
230
+ # RelatonBib::LocalizedString.new(content, lang)
231
+ # end
232
+
233
+ # @param postal [Nokogiri::XML::Element]
234
+ # @return [Array<RelatonBib::Address, RelatonBib::Phone>]
235
+ # def contacts(addr)
236
+ # contacts = []
237
+ # return contacts unless addr
238
+
239
+ # postal = addr.at("./postal")
240
+ # contacts << address(postal) if postal
241
+ # add_contact(contacts, "phone", addr.at("./phone"))
242
+ # add_contact(contacts, "email", addr.at("./email"))
243
+ # add_contact(contacts, "uri", addr.at("./uri"))
244
+ # contacts
245
+ # end
246
+
247
+ # @param postal [Nokogiri::XML::Element]
248
+ # @rerurn [RelatonBib::Address]
249
+ # def address(postal) # rubocop:disable Metrics/CyclomaticComplexity
250
+ # RelatonBib::Address.new(
251
+ # street: [(postal.at("./postalLine") || postal.at("./street"))&.text],
252
+ # city: postal.at("./city")&.text,
253
+ # postcode: postal.at("./code")&.text,
254
+ # country: postal.at("./country")&.text,
255
+ # state: postal.at("./region")&.text,
256
+ # )
257
+ # end
258
+
259
+ # @param type [String] allowed "phone", "email" or "uri"
260
+ # @param value [String]
261
+ # def add_contact(contacts, type, value)
262
+ # return unless value
263
+
264
+ # contacts << RelatonBib::Contact.new(type: type, value: value.text)
265
+ # end
266
+
267
+ # @param author [Nokogiri::XML::Element]
268
+ # @return [RelatonBib::Affiliation]
269
+ # def affiliation(author)
270
+ # organization = author.at("./organization")
271
+ # org = if organization.nil? || organization&.text&.empty?
272
+ # new_org
273
+ # else
274
+ # new_org organization.text, organization[:abbrev]
275
+ # end
276
+ # RelatonBib::Affiliation.new organization: org
277
+ # end
278
+
279
+ # @param name [String]
280
+ # @param abbr [String]
281
+ # @return [RelatonBib::Organization]
282
+ # def new_org(name = "Internet Engineering Task Force", abbr = "IETF")
283
+ # RelatonBib::Organization.new name: name, abbreviation: abbr
284
+ # end
285
+
286
+ # @param author [Nokogiri::XML::Document]
287
+ # @return [Hash]
288
+ # def contributor_role(author)
289
+ # { type: author[:role] || "author" }
290
+ # end
291
+
292
+ # def month(mon)
293
+ # return 1 if !mon || mon.empty?
294
+ # return mon if /^\d+$/.match? mon
295
+
296
+ # Date::MONTHNAMES.index(mon)
297
+ # end
298
+
299
+ #
300
+ # Extract date from reference.
301
+ #
302
+ # @param reference [Nokogiri::XML::Element]
303
+ # @return [Array<RelatonBib::BibliographicDate>] published data.
304
+ #
305
+ # def dates(reference)
306
+ # return unless (date = reference.at "./front/date")
307
+
308
+ # d = [date[:year], month(date[:month]),
309
+ # (date[:day] || 1)].compact.join "-"
310
+ # date = Time.parse(d).strftime "%Y-%m-%d"
311
+ # [RelatonBib::BibliographicDate.new(type: "published", on: date)]
312
+ # end
313
+
314
+ #
315
+ # Extract document identifiers from reference
316
+ #
317
+ # @param reference [Nokogiri::XML::Element]
318
+ # @param ver [String, NilClass] Internet Draft version
319
+ #
320
+ # @return [Array<RelatonBib::DocumentIdentifier>]
321
+ #
322
+ # def docids(reference, ver) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize
323
+ # id = (reference[:anchor] || reference[:docName] || reference[:number])
324
+ # ret = []
325
+ # if id
326
+ # ret << RelatonBib::DocumentIdentifier.new(
327
+ # type: "IETF", id: id.sub(/^(RFC)/, "\\1 "),
328
+ # )
329
+ # end
330
+ # if (id = reference[:anchor])
331
+ # ret << RelatonBib::DocumentIdentifier.new(type: "rfc-anchor", id: id)
332
+ # end
333
+ # names = ["DOI", "Internet-Draft"]
334
+ # ret + reference.xpath("./seriesInfo").map do |si|
335
+ # next unless names.include? si[:name]
336
+
337
+ # id = si[:value]
338
+ # id.sub!(/(?<=-)\d{2}$/, ver) if ver && si[:name] == "Internet-Draft"
339
+ # RelatonBib::DocumentIdentifier.new(id: id, type: si[:name])
340
+ # end.compact
341
+ # end
342
+
343
+ #
344
+ # Extract series form reference
345
+ # @param reference [Nokogiri::XML::Element]
346
+ #
347
+ # @return [Array<RelatonBib::Series>]
348
+ #
349
+ # def series(reference)
350
+ # reference.xpath("./seriesInfo").map do |si|
351
+ # next if si[:name] == "DOI" || si[:stream] || si[:status]
352
+
353
+ # RelatonBib::Series.new(
354
+ # title: RelatonBib::TypedTitleString.new(
355
+ # content: si[:name], language: language(reference), script: "Latn",
356
+ # ),
357
+ # number: si[:value],
358
+ # type: "main",
359
+ # )
360
+ # end.compact
361
+ # end
362
+
363
+ #
364
+ # extract status
365
+ # @param reference [Nokogiri::XML::Element]
366
+ #
367
+ # @return [RelatonBib::DocumentStatus]
368
+ #
369
+ # def status(reference)
370
+ # st = reference.at("./seriesinfo[@status]")
371
+ # return unless st
372
+
373
+ # RelatonBib::DocumentStatus.new(stage: st[:status])
374
+ # end
367
375
  end
368
- # rubocop:enable Metrics/ModuleLength
369
376
  end
@@ -1,3 +1,3 @@
1
1
  module RelatonIetf
2
- VERSION = "1.9.0".freeze
2
+ VERSION = "1.9.1".freeze
3
3
  end
@@ -9,7 +9,7 @@ module RelatonIetf
9
9
  # @param item_hash [Hash]
10
10
  # @return [RelatonIetf::IetfBibliographicItem]
11
11
  def bib_item(item_hash)
12
- IetfBibliographicItem.new **item_hash
12
+ IetfBibliographicItem.new(**item_hash)
13
13
  end
14
14
  end
15
15
  end
data/lib/relaton_ietf.rb CHANGED
@@ -5,6 +5,7 @@ require "relaton_ietf/ietf_bibliography"
5
5
  require "relaton_ietf/ietf_bibliographic_item"
6
6
  require "relaton_ietf/xml_parser"
7
7
  require "relaton_ietf/hash_converter"
8
+ require "relaton_ietf/committee"
8
9
 
9
10
  require "relaton/provider_ietf"
10
11
 
data/relaton_ietf.gemspec CHANGED
@@ -38,5 +38,5 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency "vcr"
39
39
  spec.add_development_dependency "webmock"
40
40
 
41
- spec.add_dependency "relaton-bib", "~> 1.9.0"
41
+ spec.add_dependency "relaton-bib", ">= 1.9.5"
42
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-ietf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.9.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-26 00:00:00.000000000 Z
11
+ date: 2021-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: equivalent-xml
@@ -126,16 +126,16 @@ dependencies:
126
126
  name: relaton-bib
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: 1.9.0
131
+ version: 1.9.5
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
- version: 1.9.0
138
+ version: 1.9.5
139
139
  description: "RelatonIetf: retrieve IETF Standards for bibliographic use \nusing the
140
140
  BibliographicItem model.\n\nFormerly known as rfcbib.\n"
141
141
  email:
@@ -163,6 +163,7 @@ files:
163
163
  - grammars/reqt.rng
164
164
  - lib/relaton/provider_ietf.rb
165
165
  - lib/relaton_ietf.rb
166
+ - lib/relaton_ietf/committee.rb
166
167
  - lib/relaton_ietf/hash_converter.rb
167
168
  - lib/relaton_ietf/ietf_bibliographic_item.rb
168
169
  - lib/relaton_ietf/ietf_bibliography.rb