relaton 3.0.0.pre.alpha.5 → 3.0.0.pre.alpha.6

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/lib/relaton/3gpp/bibliography.rb +19 -6
  3. data/lib/relaton/3gpp/processor.rb +6 -0
  4. data/lib/relaton/bib/item_data.rb +14 -0
  5. data/lib/relaton/bipm/bibliography.rb +24 -21
  6. data/lib/relaton/bsi/bibliography.rb +26 -23
  7. data/lib/relaton/calconnect/bibliography.rb +6 -6
  8. data/lib/relaton/calconnect/hit_collection.rb +4 -1
  9. data/lib/relaton/ccsds/bibliography.rb +15 -10
  10. data/lib/relaton/ccsds/hit_collection.rb +1 -1
  11. data/lib/relaton/ccsds/processor.rb +3 -2
  12. data/lib/relaton/cen/bibliography.rb +27 -24
  13. data/lib/relaton/cie/bibliography.rb +11 -9
  14. data/lib/relaton/cie/scrapper.rb +15 -8
  15. data/lib/relaton/core/processor.rb +61 -8
  16. data/lib/relaton/core/request_error.rb +21 -3
  17. data/lib/relaton/db/cache.rb +49 -19
  18. data/lib/relaton/db/cache_entry.rb +9 -0
  19. data/lib/relaton/db/registry.rb +128 -28
  20. data/lib/relaton/db.rb +162 -48
  21. data/lib/relaton/ecma/bibliography.rb +18 -13
  22. data/lib/relaton/etsi/bibliography.rb +8 -7
  23. data/lib/relaton/gb/bibliography.rb +20 -12
  24. data/lib/relaton/iala/bibliography.rb +15 -12
  25. data/lib/relaton/iana/bibliography.rb +12 -12
  26. data/lib/relaton/iana/parser.rb +5 -2
  27. data/lib/relaton/iec/bibliography.rb +18 -7
  28. data/lib/relaton/iec/processor.rb +5 -0
  29. data/lib/relaton/ieee/bibliography.rb +19 -13
  30. data/lib/relaton/ieee/processor.rb +16 -0
  31. data/lib/relaton/ieee/rawbib_id_parser.rb +2 -2
  32. data/lib/relaton/ietf/bibliography.rb +11 -9
  33. data/lib/relaton/ietf/scraper.rb +5 -4
  34. data/lib/relaton/iso/bibliography.rb +11 -9
  35. data/lib/relaton/itu/bibliography.rb +9 -4
  36. data/lib/relaton/jis/bibliography.rb +22 -11
  37. data/lib/relaton/nist/bibliography.rb +25 -21
  38. data/lib/relaton/oasis/bibliography.rb +16 -13
  39. data/lib/relaton/ogc/bibliography.rb +15 -14
  40. data/lib/relaton/ogc/hit_collection.rb +9 -7
  41. data/lib/relaton/ogc/processor.rb +7 -1
  42. data/lib/relaton/omg/bibliography.rb +9 -9
  43. data/lib/relaton/omg/scraper.rb +3 -2
  44. data/lib/relaton/plateau/bibliography.rb +9 -7
  45. data/lib/relaton/plateau/hit_collection.rb +2 -1
  46. data/lib/relaton/version.rb +1 -1
  47. data/lib/relaton/xsf/bibliography.rb +11 -6
  48. metadata +18 -4
@@ -15,10 +15,10 @@ module Relaton
15
15
  module Bibliography
16
16
  SOURCE = "https://raw.githubusercontent.com/relaton/relaton-data-iana/refs/heads/v2/"
17
17
 
18
- # @param text [String, Pubid::Iana::Identifier]
18
+ # @param ref [String, Pubid::Iana::Identifier]
19
19
  # @return [Relaton::Iana::Item, nil]
20
- def search(text)
21
- pubid = parse_ref text
20
+ def search(ref)
21
+ pubid = parse_ref ref
22
22
  return unless pubid
23
23
 
24
24
  # Pass the pubid so Relaton::Index narrows candidates by number via
@@ -34,19 +34,19 @@ module Relaton
34
34
  raise Relaton::RequestError, e.message
35
35
  end
36
36
 
37
- # @param ref [String] the IANA registry slug to look up
37
+ # @param ref [String, Pubid::Iana::Identifier] the IANA registry slug to look up
38
38
  # @param year [String, NilClass] not used
39
39
  # @param opts [Hash] options
40
40
  # @return [Relaton::Iana::Item, nil]
41
41
  def get(ref, _year = nil, _opts = {})
42
- Util.info "Fetching from Relaton repository ...", key: ref
42
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
43
43
  result = search(ref)
44
44
  unless result
45
- Util.info "Not found.", key: ref
45
+ Util.info "Not found.", key: ref.to_s
46
46
  return
47
47
  end
48
48
 
49
- Util.info "Found: `#{result.docidentifier[0].content}`", key: ref
49
+ Util.info "Found: `#{result.docidentifier[0].content}`", key: ref.to_s
50
50
  result
51
51
  end
52
52
 
@@ -63,14 +63,14 @@ module Relaton
63
63
  # RuntimeError on anything else, and a citation relaton cannot parse is a
64
64
  # miss, not an error — `#get` reports it as "Not found.".
65
65
  #
66
- # @param text [String, Pubid::Iana::Identifier]
66
+ # @param ref [String, Pubid::Iana::Identifier]
67
67
  # @return [Pubid::Iana::Identifier, nil]
68
- def parse_ref(text)
69
- return text unless text.is_a? String
68
+ def parse_ref(ref)
69
+ return ref unless ref.is_a? String
70
70
 
71
- ::Pubid::Iana::Identifier.parse text
71
+ ::Pubid::Iana::Identifier.parse ref
72
72
  rescue StandardError => e
73
- Util.warn "Failed to parse pubid `#{text}`: #{e.message}"
73
+ Util.warn "Failed to parse pubid `#{ref}`: #{e.message}"
74
74
  nil
75
75
  end
76
76
 
@@ -125,8 +125,11 @@ module Relaton
125
125
  # @return [Array<Relaton::Bib::Date>] date
126
126
  #
127
127
  def parse_date
128
- d = @xml.xpath("./xmlns:created|./xmlns:published|./xmlns:updated", NS).map do |dt|
129
- Bib::Date.new(type: dt.name, at: dt.text)
128
+ # moxml 0.5.98 drops every branch after the second in an N>=3 union
129
+ # under the reserved `xmlns` prefix (lutaml/moxml#315), which silently
130
+ # stripped `updated` dates from every crawled registry.
131
+ d = %w[created published updated].flat_map do |type|
132
+ @xml.xpath("./xmlns:#{type}", NS).map { |dt| Bib::Date.new(type: dt.name, at: dt.text) }
130
133
  end
131
134
  result = d.none? && @rootdoc ? @rootdoc.date : d
132
135
  @errors[:date] &&= result.empty?
@@ -24,18 +24,29 @@ module Relaton
24
24
  raise Relaton::RequestError, e.message
25
25
  end
26
26
 
27
- # @param code [String] the IEC standard code to look up (e.g. "IEC 8000")
27
+ # @param ref [String, Pubid::Iec::Identifier] the IEC standard code to
28
+ # look up (e.g. "IEC 8000"), or the parse that Relaton::Db routed
29
+ # with (relaton#205); a pubid is never mutated
28
30
  # @param year [String] the year the standard was published (optional)
29
31
  # @param opts [Hash] options; restricted to :all_parts if all-parts
30
32
  # reference is required
31
33
  # @return [Relaton::Iec::ItemData, nil]
32
- def get(code, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
33
- opts[:all_parts] ||= code.match?(/\s\(all parts\)/)
34
- ref = code.sub(/\s\(all parts\)/, "")
35
- return iev if ref.casecmp("IEV").zero?
36
-
37
- pubid = ::Pubid::Iec::Identifier.parse ref.upcase
34
+ def get(ref, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
35
+ if ref.is_a?(String)
36
+ opts[:all_parts] ||= ref.match?(/\s\(all parts\)/)
37
+ text = ref.sub(/\s\(all parts\)/, "")
38
+ return iev if text.casecmp("IEV").zero?
39
+
40
+ pubid = ::Pubid::Iec::Identifier.parse text.upcase
41
+ elsif ref.all_parts?
42
+ opts[:all_parts] = true
43
+ pubid = ref.identifiers.first
44
+ else
45
+ pubid = ref
46
+ end
38
47
  if year
48
+ # Copy first: a caller's pubid is also its Db cache key.
49
+ pubid = pubid.class.from_hash(pubid.to_hash)
39
50
  pubid.date = ::Pubid::Components::Date.new(year: year.to_s)
40
51
  end
41
52
 
@@ -63,7 +63,12 @@ module Relaton
63
63
 
64
64
  # @param code [String]
65
65
  # @return [String, nil]
66
+ # Only a URN: `Relaton::Iec.urn_to_code` splits on `:`, so it would
67
+ # rewrite any reference with enough colons
68
+ # (`IEC 60034-1:1969+AMD1:1977+AMD2:1979+AMD3:1980 CSV`).
66
69
  def urn_to_code(code)
70
+ return unless code.match?(/\Aurn:/i)
71
+
67
72
  require_relative "../iec"
68
73
  Relaton::Iec.urn_to_code code
69
74
  end
@@ -7,11 +7,12 @@ module Relaton
7
7
  #
8
8
  # Search IEEE bibliography item by reference.
9
9
  #
10
- # @param code [String]
10
+ # @param ref [String, Pubid::Ieee::Identifier] the reference, or its
11
+ # parse from Relaton::Db (relaton#205)
11
12
  #
12
13
  # @return [Relaton::Ieee::ItemData, nil]
13
14
  #
14
- def search(code) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
15
+ def search(ref) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
15
16
  index = Relaton::Index.find_or_create :ieee, url: "#{GH_URL}#{INDEXFILE}.zip", file: "#{INDEXFILE}.yaml",
16
17
  pubid_class: ::Pubid::Ieee::Identifier
17
18
  # Pass the parsed pubid (not the raw String) so index-v2 narrows
@@ -20,7 +21,7 @@ module Relaton
20
21
  # unparseable/partial ref falls back to the full-scan String search.
21
22
  # Rows are Pubid::Ieee::Identifier objects (not Comparable), so pick by
22
23
  # the string form.
23
- pubid = parse_pubid code
24
+ pubid = parse_pubid ref
24
25
  needle = pubid.to_s
25
26
  row = index.search(pubid) { |r| r[:id].to_s.include?(needle) }.min_by { |r| r[:id].to_s }
26
27
  return unless row
@@ -36,20 +37,22 @@ module Relaton
36
37
  #
37
38
  # Get IEEE bibliography item by reference.
38
39
  #
39
- # @param code [String] the IEEE standard Code to look up (e..g "528-2019")
40
+ # @param ref [String, Pubid::Ieee::Identifier] the IEEE standard
41
+ # reference to look up (e.g. "IEEE 528-2019"), or its parse from
42
+ # Relaton::Db (relaton#205)
40
43
  # @param year [String] the year the standard was published (optional)
41
44
  # @param opts [Hash] options
42
45
  #
43
46
  # @return [Relaton::Ieee::ItemData, nil]
44
47
  #
45
- def get(code, _year = nil, _opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
46
- Util.info "Fetching from Relaton repository ...", key: code
47
- item = search(code)
48
+ def get(ref, _year = nil, _opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
49
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
50
+ item = search(ref)
48
51
  if item
49
- Util.info "Found: `#{item.docidentifier.first.content}`", key: code
52
+ Util.info "Found: `#{item.docidentifier.first.content}`", key: ref.to_s
50
53
  item
51
54
  else
52
- Util.info "Not found.", key: code
55
+ Util.info "Not found.", key: ref.to_s
53
56
  nil
54
57
  end
55
58
  end
@@ -60,12 +63,15 @@ module Relaton
60
63
  # return the raw String when pubid can't parse it (e.g. a partial ref) so
61
64
  # the search falls back to the substring scan.
62
65
  #
63
- # @param code [String]
66
+ # @param ref [String, ::Pubid::Ieee::Identifier]
64
67
  # @return [::Pubid::Ieee::Identifier, String]
65
- def parse_pubid(code)
66
- ::Pubid::Ieee::Identifier.parse code
68
+ def parse_pubid(ref)
69
+ # A pubid from Relaton::Db (relaton#205) is used as it is.
70
+ return ref unless ref.is_a?(String)
71
+
72
+ ::Pubid::Ieee::Identifier.parse ref
67
73
  rescue StandardError
68
- code
74
+ ref
69
75
  end
70
76
  end
71
77
  end
@@ -44,6 +44,22 @@ module Relaton
44
44
  nil
45
45
  end
46
46
 
47
+ # An IEEE pubid keeps the other publishers in `publishers` (a joint
48
+ # development) or `copublisher` (a standard), not in the shared
49
+ # `copublishers`.
50
+ #
51
+ # @param pubid [Pubid::Ieee::Identifier]
52
+ # @return [Array<String>]
53
+ def copublishers(pubid)
54
+ pubid = pubid.identifiers.first if pubid.all_parts?
55
+ others = if pubid.respond_to?(:publishers) && pubid.publishers
56
+ pubid.publishers
57
+ elsif pubid.respond_to?(:copublisher)
58
+ pubid.copublisher
59
+ end
60
+ Array(others).map(&:to_s) - %w[IEEE AIEE]
61
+ end
62
+
47
63
  # @param xml [String]
48
64
  # @return [Relaton::Ieee::ItemData]
49
65
  def from_xml(xml)
@@ -138,8 +138,8 @@ module Relaton
138
138
  Renderer.new(publisher: "IEEE", number: "P802", part: "11aj", draft: "8.0", year: "2017")
139
139
  when "IEEE P802.11ajD9.0, November 2017" # "IEEE P802-11aj/D9.0.2017"
140
140
  Renderer.new(publisher: "IEEE", number: "P802", part: "11aj", draft: "9.0", year: "2017")
141
- when "ISO/IEC/IEEE P29119-4-DISMay2013" # "ISO/IEC/IEEE DIS P29119-4.2013"
142
- Renderer.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P29119", part: "4", year: "2013")
141
+ when "ISO/IEC/IEEE P29119-4-DISMay2013" # "ISO/IEC/IEEE DIS P29119-4.2013-05"
142
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P29119", part: "4", year: "2013", month: "05")
143
143
  when "IEEE-P15026-3-DIS-January 2015" # "IEEE DIS P15026-3.2015"
144
144
  Renderer.new(publisher: "IEEE", stage: "DIS", number: "P15026", year: "2015")
145
145
  when "ANSI/IEEE PC63.7/D rev17, December 2014" # "ANSI/IEEE PC63-7/D/REV-17.2014"
@@ -7,25 +7,27 @@ module Relaton
7
7
  # IETF bibliography module
8
8
  module Bibliography
9
9
  class << self
10
- # @param code [String] the ISO standard Code to look up (e..g "ISO 9000")
10
+ # @param ref [String, Pubid::Ietf::Identifier] the IETF reference
11
+ # (e.g. "RFC 8341"), or its parse from Relaton::Db (relaton#205)
11
12
  # @return [RelatonIetf::IetfBibliographicItem]
12
- def search(text)
13
- Scraper.scrape_page text
13
+ def search(ref)
14
+ Scraper.scrape_page ref
14
15
  end
15
16
 
16
- # @param code [String] the ISO standard Code to look up (e..g "ISO 9000")
17
+ # @param ref [String, Pubid::Ietf::Identifier] the IETF reference
18
+ # (e.g. "RFC 8341"), or its parse from Relaton::Db (relaton#205)
17
19
  # @param year [String] the year the standard was published (optional)
18
20
  # @param opts [Hash] options; restricted to :all_parts if all-parts
19
21
  # reference is required
20
22
  # @return [RelatonIetf::IetfBibliographicItem] Relaton of reference
21
- def get(code, _year = nil, _opts = {})
22
- Util.info "Fetching from Relaton repository ...", key: code
23
- result = search code
23
+ def get(ref, _year = nil, _opts = {})
24
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
25
+ result = search ref
24
26
  if result
25
27
  docid = result.docidentifier.detect(&:primary) || result.docidentifier.first
26
- Util.info "Found: `#{docid.content}`", key: code
28
+ Util.info "Found: `#{docid.content}`", key: ref.to_s
27
29
  else
28
- Util.info "Not found.", key: code
30
+ Util.info "Not found.", key: ref.to_s
29
31
  end
30
32
  result
31
33
  end
@@ -15,17 +15,18 @@ module Relaton
15
15
  # publishing their `index-v1` for released relatons, untouched.
16
16
  IETF = "https://raw.githubusercontent.com/relaton/relaton-data-ietf/main/"
17
17
 
18
- # @param text [String]
18
+ # @param ref [String, Pubid::Ietf::Identifier] a reference, or its parse
19
+ # from Relaton::Db (relaton#205), which is used as it is
19
20
  # @return [Relaton::Ietf::ItemData, nil]
20
- def scrape_page(text)
21
- id = parse_id text.sub(/\AIETF\s+/, "")
21
+ def scrape_page(ref)
22
+ id = ref.is_a?(String) ? parse_id(ref.sub(/\AIETF\s+/, "")) : ref
22
23
  return unless id
23
24
 
24
25
  fetch_doc id
25
26
  rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
26
27
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
27
28
  Net::ProtocolError, SocketError
28
- raise Relaton::RequestError, "No document found for #{text} reference"
29
+ raise Relaton::RequestError, "No document found for #{ref} reference"
29
30
  end
30
31
 
31
32
  private
@@ -24,7 +24,9 @@ module Relaton
24
24
  raise Relaton::RequestError, e.message
25
25
  end
26
26
 
27
- # @param ref [String] the ISO standard Code to look up (e..g "ISO 9000")
27
+ # @param ref [String, Pubid::Iso::Identifier] the ISO standard Code to
28
+ # look up (e..g "ISO 9000"), or the parse that Relaton::Db routed with
29
+ # (relaton#205); a pubid is never mutated
28
30
  # @param year [String, NilClass] the year the standard was published
29
31
  # @param opts [Hash] options; restricted to :all_parts if all-parts
30
32
  # @option opts [Boolean] :all_parts if all-parts reference is required
@@ -33,21 +35,21 @@ module Relaton
33
35
  #
34
36
  # @return [RelatonIsoBib::IsoBibliographicItem] Bibliographic item
35
37
  def get(ref, year = nil, opts = {}) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity,Metrics/AbcSize
36
- code = ref.gsub("\u2013", "-")
37
-
38
- # parse "all parts" request
39
- # code.sub! " (all parts)", ""
40
- # opts[:all_parts] ||= $~ && opts[:all_parts].nil?
41
-
42
- query_pubid = ::Pubid::Iso::Identifier.parse(code)
38
+ query_pubid = if ref.is_a?(String)
39
+ ::Pubid::Iso::Identifier.parse(ref.gsub("\u2013", "-"))
40
+ else
41
+ ref
42
+ end
43
43
  if year&.respond_to?(:to_i)
44
+ # Copy first: a caller's pubid is also its Db cache key.
45
+ query_pubid = query_pubid.class.from_hash(query_pubid.to_hash)
44
46
  query_pubid.root.date = ::Pubid::Components::Date.new(year: year.to_s)
45
47
  end
46
48
  query_pubid = query_pubid.to_all_parts if opts[:all_parts]
47
49
  Util.info "Fetching from Relaton repository ...", key: query_pubid.to_s
48
50
 
49
51
  hits, missed_year_ids = isobib_search_filter(query_pubid, opts)
50
- tip_ids = look_up_with_any_types_stages(hits, ref, opts)
52
+ tip_ids = look_up_with_any_types_stages(hits, ref.to_s, opts)
51
53
 
52
54
  date_filter = opts[:publication_date_before] || opts[:publication_date_after]
53
55
  if date_filter && !query_pubid.all_parts
@@ -31,13 +31,18 @@ module Relaton
31
31
  HitCollection.new(refid).tap(&:search)
32
32
  end
33
33
 
34
- # @param code [String] the ITU standard Code to look up
34
+ # @param ref [String, Pubid::Itu::Identifier] the ITU standard Code to
35
+ # look up, or its parse from Relaton::Db (relaton#205); #with_year
36
+ # copies, so the pubid is not changed
35
37
  # @param year [String] the year the standard was published (optional)
36
38
  # @param opts [Hash] options
37
39
  # @return [Relaton::Bib::ItemData, nil]
38
- def get(code, year = nil, opts = {})
39
- warn_incorrect_ref(code)
40
- refid = with_year ::Pubid::Itu.parse(code), year
40
+ def get(ref, year = nil, opts = {})
41
+ if ref.is_a? String
42
+ warn_incorrect_ref(ref)
43
+ ref = ::Pubid::Itu.parse(ref)
44
+ end
45
+ refid = with_year ref, year
41
46
 
42
47
  ret = itubib_get1(refid)
43
48
  return nil if ret.nil?
@@ -13,7 +13,8 @@ module Relaton
13
13
  # the reference's series and number (a supplement is filed under its base
14
14
  # number), so an edition and its amendments are returned together.
15
15
  #
16
- # @param [String] code JIS document code
16
+ # @param [String, Pubid::Jis::Identifier] ref JIS document reference; a
17
+ # pubid is never mutated
17
18
  # @param [String, nil] year JIS document year
18
19
  #
19
20
  # @return [Relaton::Jis::HitCollection] search result
@@ -21,16 +22,21 @@ module Relaton
21
22
  # @raise [Pubid::Errors::ParseError] when the reference is not a JIS
22
23
  # identifier, so a malformed reference is not reported as "not found"
23
24
  #
24
- def search(code, year = nil)
25
- pubid = ::Pubid::Jis::Identifier.parse code
26
- pubid.year ||= year.to_i if year
25
+ def search(ref, year = nil)
26
+ pubid = ref.is_a?(String) ? ::Pubid::Jis::Identifier.parse(ref) : ref
27
+ if year && pubid.year.nil?
28
+ # Copy first: a caller's pubid is also its Db cache key.
29
+ pubid = pubid.class.from_hash(pubid.to_hash)
30
+ pubid.year = year.to_i
31
+ end
27
32
  HitCollection.new pubid
28
33
  end
29
34
 
30
35
  #
31
36
  # Get JIS document by reference
32
37
  #
33
- # @param [String] ref JIS document reference
38
+ # @param [String, Pubid::Jis::Identifier] ref JIS document reference, or
39
+ # the parse that Relaton::Db routed with (relaton#205)
34
40
  # @param [String, nil] year JIS document year
35
41
  # @param [Hash] opts options
36
42
  # @option opts [Boolean] :all_parts return all parts of document
@@ -41,16 +47,21 @@ module Relaton
41
47
  # identifier
42
48
  #
43
49
  def get(ref, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize
44
- code = ref.sub(/\s\((all parts|規格群)\)/, "")
45
- opts[:all_parts] ||= !$1.nil?
46
- Util.info "Fetching from webdesk.jsa.or.jp ...", key: ref
47
- hits = search(code, year)
50
+ if ref.is_a?(String)
51
+ query = ref.sub(/\s\((all parts|規格群)\)/, "")
52
+ opts[:all_parts] ||= !$1.nil?
53
+ else
54
+ opts[:all_parts] ||= ref.all_parts?
55
+ query = ref.all_parts? ? ref.identifiers.first : ref
56
+ end
57
+ Util.info "Fetching from webdesk.jsa.or.jp ...", key: ref.to_s
58
+ hits = search(query, year)
48
59
  result = opts[:all_parts] ? hits.find_all_parts : hits.find
49
60
  if result.is_a? Bib::ItemData
50
- Util.info "Found: `#{result.docidentifier[0].content}`", key: ref
61
+ Util.info "Found: `#{result.docidentifier[0].content}`", key: ref.to_s
51
62
  return result
52
63
  end
53
- hint result, ref, year
64
+ hint result, ref.to_s, year
54
65
  end
55
66
 
56
67
  #
@@ -7,18 +7,18 @@ module Relaton
7
7
  #
8
8
  # Search NIST documents by reference
9
9
  #
10
- # @param text [String] reference
10
+ # @param ref [String] reference
11
11
  #
12
12
  # @return [Relaton::Nist::HitCollection] search result
13
13
  #
14
- def search(text, year = nil, opts = {})
15
- ref = text.sub(/^NISTIR/, "NIST IR").sub(/\/Add/, " Add")
14
+ def search(ref, year = nil, opts = {})
15
+ query = ref.sub(/^NISTIR/, "NIST IR").sub(/\/Add/, " Add")
16
16
  # pubid 2.x only recognizes the addendum marker with a trailing
17
17
  # period, and only splits an uppercase part letter — canonicalize
18
18
  # both ("800-38a Add" -> "800-38A Add.") so @reference parses to the
19
19
  # same pubid the index/CSRC carry.
20
- ref = ref.sub(/\bAdd\b\.?/i, "Add.").sub(/([0-9])([a-z])(?=\s+Add\.)/) { "#{$1}#{$2.upcase}" }
21
- HitCollection.search ref, year, opts
20
+ query = query.sub(/\bAdd\b\.?/i, "Add.").sub(/([0-9])([a-z])(?=\s+Add\.)/) { "#{$1}#{$2.upcase}" }
21
+ HitCollection.search query, year, opts
22
22
  rescue OpenURI::HTTPError, SocketError, OpenSSL::SSL::SSLError => e
23
23
  raise Relaton::RequestError, e.message
24
24
  end
@@ -26,34 +26,38 @@ module Relaton
26
26
  #
27
27
  # Get NIST document by reference
28
28
  #
29
- # @param code [String] the NIST standard Code to look up
29
+ # @param ref [String, Pubid::Nist::Identifier] the NIST standard Code
30
+ # to look up, or its parse from Relaton::Db (relaton#205)
30
31
  # @param year [String] the year the standard was published (optional)
31
32
  # @param opts [Hash] options
32
33
  # @option opts [Boolean] :all_parts restricted to all parts
33
34
  #
34
35
  # @return [Relaton::Nist::ItemData, nil] bibliographic item
35
36
  #
36
- def get(code, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
37
- return fetch_ref_err(code, year, []) if code.match?(/\sEP$/)
37
+ def get(ref, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
38
+ # The lookup below works on text, so a pubid from Relaton::Db is
39
+ # read back as its printed form; the pubid itself is not changed.
40
+ ref = ref.to_s unless ref.is_a?(String)
41
+ return fetch_ref_err(ref, year, []) if ref.match?(/\sEP$/)
38
42
 
39
- /^(?<code2>[^(]+)(?:\((?<date2>\w+\s(?:\d{2},\s)?\d{4})\))?\s?\(?(?:(?<=\()(?<stage>(?:I|F|\d)PD))?/ =~ code
40
- stage ||= /(?<=\.)PD-\w+(?=\.)/.match(code)&.to_s
43
+ /^(?<code2>[^(]+)(?:\((?<date2>\w+\s(?:\d{2},\s)?\d{4})\))?\s?\(?(?:(?<=\()(?<stage>(?:I|F|\d)PD))?/ =~ ref
44
+ stage ||= /(?<=\.)PD-\w+(?=\.)/.match(ref)&.to_s
41
45
  if code2
42
- code = code2.strip
46
+ ref = code2.strip
43
47
  opts[:date] = parse_date(date2, str: false) if date2
44
48
  opts[:stage] = stage if stage
45
49
  end
46
50
 
47
51
  if year.nil?
48
- /^(?<code1>[^:]+):(?<year1>[^:]+)$/ =~ code
52
+ /^(?<code1>[^:]+):(?<year1>[^:]+)$/ =~ ref
49
53
  unless code1.nil?
50
- code = code1
54
+ ref = code1
51
55
  year = year1
52
56
  end
53
57
  end
54
58
 
55
- code += "-1" if opts[:all_parts]
56
- nistbib_get(code, year, opts)
59
+ ref += "-1" if opts[:all_parts]
60
+ nistbib_get(ref, year, opts)
57
61
  end
58
62
 
59
63
  private
@@ -61,14 +65,14 @@ module Relaton
61
65
  #
62
66
  # Get NIST document by reference
63
67
  #
64
- # @param [String] code reference
68
+ # @param [String] ref reference
65
69
  # @param [String] year year
66
70
  # @param [Hash] opts options
67
71
  #
68
72
  # @return [Relaton::Nist::ItemData, nil] bibliographic item
69
73
  #
70
- def nistbib_get(code, year, opts)
71
- result = nistbib_search_filter(code, year, opts) || (return nil)
74
+ def nistbib_get(ref, year, opts)
75
+ result = nistbib_search_filter(ref, year, opts) || (return nil)
72
76
  ret = nistbib_results_filter(result, year, opts)
73
77
  if ret[:ret]
74
78
  Util.info "Found: `#{ret[:ret].docidentifier.first.content}`", key: result.reference
@@ -153,14 +157,14 @@ module Relaton
153
157
  #
154
158
  # Get search results and filter them by code and year
155
159
  #
156
- # @param code [String] reference
160
+ # @param ref [String] reference
157
161
  # @param year [String, nil] year
158
162
  # @param opts [Hash] options
159
163
  #
160
164
  # @return [Relaton::Nist::HitCollection] hits collection
161
165
  #
162
- def nistbib_search_filter(code, year, opts)
163
- result = search(code, year, opts)
166
+ def nistbib_search_filter(ref, year, opts)
167
+ result = search(ref, year, opts)
164
168
  result.search_filter
165
169
  end
166
170
 
@@ -16,16 +16,16 @@ module Relaton
16
16
  OPTIONAL = %i[version stage part label].freeze
17
17
 
18
18
  class << self
19
- def search(text, _year = nil, _opts = {}) # rubocop:disable Metrics/MethodLength
20
- Util.info "Fetching from Relaton repository ...", key: text
21
- row = find_index_entry(text)
19
+ def search(ref, _year = nil, _opts = {}) # rubocop:disable Metrics/MethodLength
20
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
21
+ row = find_index_entry(ref)
22
22
  unless row
23
- Util.info "Not found.", key: text
23
+ Util.info "Not found.", key: ref.to_s
24
24
  return
25
25
  end
26
26
 
27
27
  uri = URI("#{ENDPOINT}#{row[:file]}")
28
- parse_item(fetch_yaml(uri), text)
28
+ parse_item(fetch_yaml(uri), ref)
29
29
  rescue SocketError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
30
30
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
31
31
  Net::ProtocolError, Net::ReadTimeout,
@@ -78,11 +78,11 @@ module Relaton
78
78
  # by substring, so `OASIS amqp` resolved to some `amqp-core` record;
79
79
  # v2 matches identifiers, so a partial name no longer resolves.
80
80
  #
81
- # @param text [String] the reference as the caller wrote it
81
+ # @param ref [String] the reference as the caller wrote it
82
82
  # @return [Hash, nil] the index row, or nil
83
83
  #
84
- def find_index_entry(text)
85
- pubid = parse_ref text
84
+ def find_index_entry(ref)
85
+ pubid = parse_ref ref
86
86
  return unless pubid
87
87
 
88
88
  rows = index.search(pubid)
@@ -111,12 +111,15 @@ module Relaton
111
111
  # Rescuing here would collapse "this identifier is malformed" into "no
112
112
  # such document", leaving a caller unable to tell them apart.
113
113
  #
114
- # @param text [String]
114
+ # @param ref [String, Pubid::Oasis::Identifier]
115
115
  # @return [Pubid::Oasis::Identifier]
116
116
  # @raise [Pubid::Errors::ParseError]
117
117
  #
118
- def parse_ref(text)
119
- slug = text.to_s.strip.sub(/\A#{Regexp.escape PREFIX}/i, "")
118
+ def parse_ref(ref)
119
+ # A parsed pubid comes from Relaton::Db (relaton#205); it is used as it is.
120
+ return ref unless ref.is_a?(String)
121
+
122
+ slug = ref.to_s.strip.sub(/\A#{Regexp.escape PREFIX}/i, "")
120
123
  ::Pubid::Oasis::Identifier.parse "#{PREFIX}#{slug}"
121
124
  end
122
125
 
@@ -190,9 +193,9 @@ module Relaton
190
193
  resp.body
191
194
  end
192
195
 
193
- def parse_item(yaml, text)
196
+ def parse_item(yaml, ref)
194
197
  item = Item.from_yaml yaml
195
- Util.info "Found: `#{item.docidentifier.first.content}`", key: text
198
+ Util.info "Found: `#{item.docidentifier.first.content}`", key: ref.to_s
196
199
  item.tap { |i| i.fetched = Date.today.to_s }
197
200
  end
198
201
  end