relaton 3.0.0.pre.alpha.5 → 3.0.0.pre.alpha.7

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 (52) 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/etsi/data_fetcher.rb +118 -9
  24. data/lib/relaton/gb/bibliography.rb +20 -12
  25. data/lib/relaton/iala/bibliography.rb +15 -12
  26. data/lib/relaton/iana/bibliography.rb +12 -12
  27. data/lib/relaton/iana/parser.rb +5 -2
  28. data/lib/relaton/iec/bibliography.rb +18 -7
  29. data/lib/relaton/iec/processor.rb +6 -1
  30. data/lib/relaton/ieee/bibliography.rb +19 -13
  31. data/lib/relaton/ieee/processor.rb +16 -0
  32. data/lib/relaton/ieee/rawbib_id_parser.rb +2 -2
  33. data/lib/relaton/ietf/bibliography.rb +11 -9
  34. data/lib/relaton/ietf/scraper.rb +5 -4
  35. data/lib/relaton/index/config.rb +9 -1
  36. data/lib/relaton/index/file_io.rb +190 -0
  37. data/lib/relaton/index/type.rb +96 -23
  38. data/lib/relaton/iso/bibliography.rb +11 -9
  39. data/lib/relaton/itu/bibliography.rb +9 -4
  40. data/lib/relaton/jis/bibliography.rb +22 -11
  41. data/lib/relaton/nist/bibliography.rb +25 -21
  42. data/lib/relaton/oasis/bibliography.rb +16 -13
  43. data/lib/relaton/ogc/bibliography.rb +15 -14
  44. data/lib/relaton/ogc/hit_collection.rb +9 -7
  45. data/lib/relaton/ogc/processor.rb +7 -1
  46. data/lib/relaton/omg/bibliography.rb +9 -9
  47. data/lib/relaton/omg/scraper.rb +3 -2
  48. data/lib/relaton/plateau/bibliography.rb +9 -7
  49. data/lib/relaton/plateau/hit_collection.rb +2 -1
  50. data/lib/relaton/version.rb +1 -1
  51. data/lib/relaton/xsf/bibliography.rb +11 -6
  52. metadata +18 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b34a85f74b2b8b07d61b51a20d976f1204240dbc353f9e7d73eeeb7262912337
4
- data.tar.gz: 6e51891af83e32391abb096a788685f42d7cc648fc6a3e3483683868daa8e4b3
3
+ metadata.gz: 21f068205ef6a80e718953c7989c7a51219a9f5f6e25a4fecc67ac93d9fa4da5
4
+ data.tar.gz: 7c438465496dc3b95370bc6990420073c63f41d5edba70022a71b39bd45f343f
5
5
  SHA512:
6
- metadata.gz: 6530a4f026cf099bcd3a1c1b359d307089b57bbe14f94a77362adabafa329abbcb4f64349feaa9061e9a6eda9ff413645af6b14812bdcb3ac9bcb4e22e6ad0a1
7
- data.tar.gz: 7c555c9ddb34285255f22766b7b9c56be98b657018bfb4503bb66bc316eea7a1c2fd796f21e1910ad41615a0079d8db32f76d2b46bc051a2a4e7c6ed4c0316cc
6
+ metadata.gz: af94d0ffa5ae9cbeefecf98d9aad8a04a7ea74814b92e470b6235b2bb1c2f19593db50e0f919b2ce3bbf1bdf44b8e637fa20000e6d59bc400736159fe0f9a2d1
7
+ data.tar.gz: 833bbe454eaa888a145fb9dcd5daff7d8bc8cf2e03f603c2100b0d19d981531a5b4bfce87b77bc00f3b5a5684904473f58656ebf820b2c7272b606f5c26afddc
@@ -6,15 +6,17 @@ module Relaton
6
6
  module Bibliography
7
7
  SOURCE = "https://raw.githubusercontent.com/relaton/relaton-data-3gpp/v2/"
8
8
 
9
- # @param text [String]
9
+ # @param ref [String, ::Pubid::Tgpp::Identifier] the reference, or the
10
+ # parse that Relaton::Db routed with (relaton#205)
10
11
  # @return [Relaton::ThreeGpp::ItemData, nil]
11
- def search(text)
12
+ def search(ref)
12
13
  # An unrecognized reference raises; like ISO and ETSI we let it
13
14
  # propagate — relaton-cli rescues Pubid::Errors::Error and renders
14
15
  # "… is not a recognized standards identifier", and API callers rescue
15
16
  # it themselves. The rescue below lists transport errors only, so it
16
17
  # does not swallow the parse error.
17
- pubid = ::Pubid::Tgpp::Identifier.parse text.to_s.strip
18
+ pubid = ref
19
+ pubid = ::Pubid::Tgpp::Identifier.parse ref.strip if ref.is_a?(String)
18
20
  row = best_match pubid
19
21
  return unless row
20
22
 
@@ -36,19 +38,30 @@ module Relaton
36
38
  # @param opts [Hash] options
37
39
  # @return [Relaton::ThreeGpp::ItemData, nil]
38
40
  def get(ref, _year = nil, _opts = {})
39
- Util.info "Fetching from Relaton repository ...", key: ref
41
+ Util.info "Fetching from Relaton repository ...", key: log_key(ref)
40
42
  result = search(ref)
41
43
  unless result
42
- Util.info "Not found.", key: ref
44
+ Util.info "Not found.", key: log_key(ref)
43
45
  return
44
46
  end
45
47
 
46
- Util.info "Found: `#{result.docidentifier[0].content}`", key: ref
48
+ Util.info "Found: `#{result.docidentifier[0].content}`",
49
+ key: log_key(ref)
47
50
  result
48
51
  end
49
52
 
50
53
  private
51
54
 
55
+ # `Pubid::Tgpp#to_s` omits the `3GPP ` publisher token by default (it
56
+ # renders the index id), so a pubid from Relaton::Db (relaton#205) is
57
+ # logged with it, as the caller wrote the reference.
58
+ #
59
+ # @param ref [String, ::Pubid::Tgpp::Identifier]
60
+ # @return [String]
61
+ def log_key(ref)
62
+ ref.is_a?(String) ? ref : ref.to_s(with_publisher: true)
63
+ end
64
+
52
65
  #
53
66
  # Find the index row for a reference, newest version first.
54
67
  #
@@ -23,6 +23,12 @@ module Relaton
23
23
  Bibliography.get(code, date, opts)
24
24
  end
25
25
 
26
+ # 3GPP index ids print without the `3GPP ` token
27
+ # (`TS 23.207:REL-18/18.0.0`).
28
+ def bare_identifiers?
29
+ true
30
+ end
31
+
26
32
  #
27
33
  # Fetch all the documents from http://xml2rfc.tools.ietf.org/public/rfc/bibxml-3gpp-new/
28
34
  #
@@ -160,6 +160,20 @@ module Relaton
160
160
  Converter::Csl.from_item(self)
161
161
  end
162
162
 
163
+ # ISO 690 rendered reference (the style instance lives in the
164
+ # relaton-models citation module; the engine in relaton-render).
165
+ def to_iso690(lang: "en", script: "Latn")
166
+ require "relaton/render/iso690"
167
+ Render::Iso690::Renderer.render(self, lang: lang, script: script)
168
+ end
169
+
170
+ # ISO 690 name-and-date in-text citation.
171
+ def to_iso690_citation(lang: "en", script: "Latn", disambiguator: nil)
172
+ require "relaton/render/iso690"
173
+ Render::Iso690::Renderer.citation(
174
+ self, disambiguator: disambiguator, lang: lang, script: script
175
+ )
176
+ end
163
177
 
164
178
  def to_asciibib
165
179
  Converter::Asciibib.from_item(self)
@@ -5,18 +5,20 @@ module Relaton::Bipm
5
5
  GH_ENDPOINT = "https://raw.githubusercontent.com/relaton/relaton-data-bipm/refs/heads/v2/".freeze
6
6
 
7
7
  class << self
8
- # @param text [String]
8
+ # @param ref [String, Pubid::Bipm::Identifier] the reference, or its
9
+ # parse from Relaton::Db (relaton#205)
9
10
  # @return [RelatonBipm::BipmBibliographicItem]
10
- def search(text, _year = nil, _opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
11
- Util.info "Fetching from Relaton repository ...", key: text
12
- ref = text.sub(/^BIPM\s/, "")
13
- item = get_bipm ref
11
+ def search(ref, _year = nil, _opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
12
+ key = ref.to_s
13
+ Util.info "Fetching from Relaton repository ...", key: key
14
+ query = ref.is_a?(String) ? ref.sub(/^BIPM\s/, "") : ref
15
+ item = get_bipm query
14
16
  unless item
15
- Util.info "Not found.", key: text
17
+ Util.info "Not found.", key: key
16
18
  return
17
19
  end
18
20
 
19
- Util.info "Found: `#{item.docidentifier[0].content}`", key: text
21
+ Util.info "Found: `#{item.docidentifier[0].content}`", key: key
20
22
  item
21
23
  rescue Mechanize::ResponseCodeError => e
22
24
  raise Relaton::RequestError, e.message unless e.response_code == "404"
@@ -40,13 +42,13 @@ module Relaton::Bipm
40
42
  # end
41
43
 
42
44
  #
43
- # @param reference [String]
45
+ # @param ref [String, Pubid::Bipm::Identifier]
44
46
  #
45
47
  # @return [RelatonBipm::BipmBibliographicItem]
46
48
  #
47
- def get_bipm(reference) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
48
- pubid = parse_ref reference
49
- rows = search_index pubid, reference
49
+ def get_bipm(ref) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
50
+ pubid = ref.is_a?(String) ? parse_ref(ref) : ref
51
+ rows = search_index pubid, ref.to_s
50
52
  return if rows.empty?
51
53
 
52
54
  # Latest edition wins. Metrologia and SI Brochure rows carry no year,
@@ -78,9 +80,9 @@ module Relaton::Bipm
78
80
  # a rescan cannot help — only re-reading the tail as number-plus-year.
79
81
  #
80
82
  # @param pubid [Pubid::Bipm::Identifier] the parsed reference
81
- # @param reference [String, nil] the raw reference, for the retry
83
+ # @param ref [String, nil] the raw reference, for the retry
82
84
  # @return [Array<Hash>] the matching index rows
83
- def search_index(pubid, reference)
85
+ def search_index(pubid, ref)
84
86
  # Reduce the query once, not once per row. `#exclude` copies the
85
87
  # identifier, so rebuilding it per candidate dominated the lookup.
86
88
  query_stem = stem pubid, pubid
@@ -88,7 +90,7 @@ module Relaton::Bipm
88
90
  rows = index.search { |r| pubid_match? r[:id], pubid, query_stem } if rows.empty?
89
91
  return rows unless rows.empty?
90
92
 
91
- retry_pubid = year_number_retry reference
93
+ retry_pubid = year_number_retry ref
92
94
  retry_pubid ? search_index(retry_pubid, nil) : rows
93
95
  end
94
96
 
@@ -101,10 +103,10 @@ module Relaton::Bipm
101
103
  # reference, so a probe that does not parse is a miss (nil), never a
102
104
  # malformed-reference error -- the same rule as ISO's type/stage probe.
103
105
  #
104
- # @param reference [String, nil]
106
+ # @param ref [String, nil]
105
107
  # @return [Pubid::Bipm::Identifier, nil]
106
- def year_number_retry(reference)
107
- match = reference&.match(/\A(?<stem>.+)\s(?<year>\d{4})-(?<number>\d+)\z/)
108
+ def year_number_retry(ref)
109
+ match = ref&.match(/\A(?<stem>.+)\s(?<year>\d{4})-(?<number>\d+)\z/)
108
110
  return unless match
109
111
 
110
112
  parse_ref "#{match[:stem]} #{match[:number].sub(/\A0+(?=\d)/, '')} (#{match[:year]})"
@@ -205,11 +207,11 @@ module Relaton::Bipm
205
207
  # Pubid::Errors::Error and renders "... is not a recognized standards
206
208
  # identifier".
207
209
  #
208
- # @param reference [String]
210
+ # @param ref [String]
209
211
  # @return [Pubid::Bipm::Identifier]
210
212
  # @raise [Pubid::Errors::ParseError]
211
- def parse_ref(reference)
212
- ::Pubid::Bipm.parse reference
213
+ def parse_ref(ref)
214
+ ::Pubid::Bipm.parse ref
213
215
  end
214
216
 
215
217
  def index
@@ -219,7 +221,8 @@ module Relaton::Bipm
219
221
  )
220
222
  end
221
223
 
222
- # @param ref [String] the BIPM standard Code to look up (e..g "BIPM B-11")
224
+ # @param ref [String, Pubid::Bipm::Identifier] the BIPM standard Code to
225
+ # look up (e..g "BIPM B-11"), or its parse from Relaton::Db
223
226
  # @param year [String] not used
224
227
  # @param opts [Hash] not used
225
228
  # @return [RelatonBipm::BipmBibliographicItem]
@@ -7,10 +7,11 @@ module Relaton::Bsi
7
7
  Ids = ::Pubid::Bsi::Identifiers
8
8
 
9
9
  class << self
10
- # @param text [String]
10
+ # @param ref [String] the printed reference
11
11
  # @return [Relaton::Bsi::HitCollection]
12
- def search(text, year = nil)
13
- code = text.sub(/^BSI\s/, "").sub(/ExComm|Expert commentary/, "Ex")
12
+ def search(ref, year = nil)
13
+ # A pubid from Relaton::Db (relaton#205) prints "Expert Commentary".
14
+ code = ref.sub(/^BSI\s/, "").sub(/ExComm|Expert commentary/i, "Ex")
14
15
  HitCollection.search(code, year)
15
16
  rescue SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
16
17
  EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
@@ -19,16 +20,18 @@ module Relaton::Bsi
19
20
  end
20
21
 
21
22
  #
22
- # @param code [String] the BSI standard Code to look up
23
+ # @param ref [String, Pubid::Bsi::Identifier] the BSI standard reference
24
+ # to look up, or its parse from Relaton::Db (relaton#205)
23
25
  # @param year [String] the year the standard was published (optional)
24
26
  # @param opts [Hash] options
25
27
  # @option opts [Boolean] :all_parts if all-parts reference is required
26
28
  # @option opts [Boolean] :no_year if last published document is required
27
29
  #
28
30
  # @return [String] Relaton XML serialisation of reference
29
- def get(code, year = nil, opts = {})
30
- year ||= publication_year(code)
31
- ret = bib_get(code, year, opts)
31
+ def get(ref, year = nil, opts = {})
32
+ query = ref.is_a?(String) ? parse(ref) : ref
33
+ year ||= year_of(query)
34
+ ret = bib_get(ref.to_s, year, opts, query)
32
35
  return nil if ret.nil?
33
36
 
34
37
  ret = ret.to_most_recent_reference unless year || opts[:keep_year]
@@ -40,18 +43,18 @@ module Relaton::Bsi
40
43
  # Pubid::Errors::Error and renders "... is not a recognized standards
41
44
  # identifier". A catalogue hit code is a different case: `Hit#pubid`
42
45
  # rescues, because one odd Algolia row must not abort the search.
43
- # @param [String] code document identifier
46
+ # @param [String] ref the reference
44
47
  # @return [Pubid::Bsi::Identifier]
45
48
  # @raise [Pubid::Errors::ParseError]
46
- def parse(code)
47
- ::Pubid::Bsi::Identifier.parse(code)
49
+ def parse(ref)
50
+ ::Pubid::Bsi::Identifier.parse(ref)
48
51
  end
49
52
 
50
53
  # Publication year of a reference's base document.
51
- # @param [String] code document identifier
54
+ # @param [String] ref the reference
52
55
  # @return [String, nil]
53
- def publication_year(code)
54
- year_of parse(code)
56
+ def publication_year(ref)
57
+ year_of parse(ref)
55
58
  end
56
59
 
57
60
  # Whether a query and a candidate hit denote the same BSI document, at the
@@ -154,14 +157,14 @@ module Relaton::Bsi
154
157
  #
155
158
  # Search for a BSI standard.
156
159
  #
157
- # @param [String] code the BSI standard Code to look up
160
+ # @param [String] ref the BSI standard reference to look up
161
+ # @param [Pubid::Bsi::Identifier] query the parsed reference
158
162
  #
159
163
  # @return [Relaton::Bsi::HitCollection] a collection of hits
160
164
  #
161
- def search_filter(code)
162
- query = parse(code)
163
- Util.info "Fetching from shop.bsigroup.com ...", key: code
164
- search(code).filter_hits!(query)
165
+ def search_filter(ref, query)
166
+ Util.info "Fetching from shop.bsigroup.com ...", key: ref
167
+ search(ref).filter_hits!(query)
165
168
  end
166
169
 
167
170
  # Sort through the results, and return the first result that matches the
@@ -180,15 +183,15 @@ module Relaton::Bsi
180
183
  { years: missed_years }
181
184
  end
182
185
 
183
- def bib_get(code, year, _opts)
184
- result = search_filter(code) || return
186
+ def bib_get(ref, year, _opts, query)
187
+ result = search_filter(ref, query) || return
185
188
  ret = results_filter(result, year)
186
189
  if ret[:ret]
187
- Util.info "Found: `#{ret[:ret].docidentifier.first&.content}`", key: code
190
+ Util.info "Found: `#{ret[:ret].docidentifier.first&.content}`", key: ref
188
191
  ret[:ret]
189
192
  else
190
- Util.info "Not found", key: code
191
- fetch_ref_err(code, year, ret[:years])
193
+ Util.info "Not found", key: ref
194
+ fetch_ref_err(ref, year, ret[:years])
192
195
  end
193
196
  end
194
197
  end
@@ -3,10 +3,10 @@ require "mechanize"
3
3
  module Relaton::Calconnect
4
4
  class Bibliography
5
5
  class << self
6
- # @param text [String]
6
+ # @param ref [String]
7
7
  # @return [RelatonCalconnect::HitCollection]
8
- def search(text, year = nil, _opts = {})
9
- HitCollection.new text, year
8
+ def search(ref, year = nil, _opts = {})
9
+ HitCollection.new ref, year
10
10
  rescue Mechanize::ResponseCodeError, SocketError, Errno::ECONNREFUSED
11
11
  raise Relaton::RequestError, "Could not access https://standards.calconnect.org"
12
12
  end
@@ -26,14 +26,14 @@ module Relaton::Calconnect
26
26
  # afterwards, because an undated reference reaches every year of the
27
27
  # document. That split is why `bib_results_filter` stays.
28
28
  def get(ref, year = nil, opts = {})
29
- Util.info "Fetching from Relaton repository ...", key: ref
29
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
30
30
  result = search(ref, year, opts) || (return nil)
31
31
  ret = bib_results_filter(result, year)
32
32
  if ret[:ret]
33
- Util.info "Found: `#{ret[:ret].docidentifier.first.content}`", key: ref
33
+ Util.info "Found: `#{ret[:ret].docidentifier.first.content}`", key: ref.to_s
34
34
  ret[:ret]
35
35
  else
36
- Util.info "Not found.", key: ref
36
+ Util.info "Not found.", key: ref.to_s
37
37
  fetch_ref_err(ref, year, ret[:years])
38
38
  end
39
39
  end
@@ -55,7 +55,7 @@ module Relaton::Calconnect
55
55
  # outside the transport rescue in `Bibliography.search`, so it never becomes
56
56
  # a `Relaton::RequestError`.
57
57
  #
58
- # @param ref [String]
58
+ # @param ref [String, Pubid::Calconnect::Identifier]
59
59
  # @return [Pubid::Calconnect::Identifier, nil]
60
60
  #
61
61
  # An unrecognized reference **raises**; like ISO, ETSI and 3GPP we let it
@@ -66,6 +66,9 @@ module Relaton::Calconnect
66
66
  # Rescuing here would collapse "this identifier is malformed" into "no
67
67
  # such document", leaving a caller unable to tell them apart.
68
68
  def parse_ref(ref)
69
+ # A parsed pubid comes from Relaton::Db (relaton#205); it is used as it is.
70
+ return ref unless ref.is_a?(String)
71
+
69
72
  ::Pubid::Calconnect::Identifier.parse ref.to_s.strip
70
73
  end
71
74
 
@@ -20,31 +20,36 @@ module Relaton
20
20
  # Get CCSDS standard by document reference.
21
21
  # If format is not specified, then all format will be returned.
22
22
  #
23
- # @param reference [String]
23
+ # @param ref [String, Pubid::Ccsds::Identifier] the reference, or
24
+ # the parse that Relaton::Db routed with (relaton#205)
24
25
  # @param year [String, nil]
25
26
  # @param opts [Hash]
26
27
  # @option opts [String] :format format of fetched document (DOC, PDF)
27
28
  #
28
29
  # @return [RelatonCcsds::BibliographicItem]
29
30
  #
30
- def get(reference, _year = nil, opts = {})
31
- ref, opts = parse_format(reference, opts)
32
- Util.info "Fetching from Relaton repository ...", key: reference
33
- item, hit = fetch_item(ref)
31
+ def get(ref, _year = nil, opts = {})
32
+ query, opts = parse_format(ref, opts)
33
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
34
+ item, hit = fetch_item(query)
34
35
  if item.nil? || filter_sources(item, opts[:format])
35
- Util.info "Not found.", key: reference
36
+ Util.info "Not found.", key: ref.to_s
36
37
  return nil
37
38
  end
38
- Util.info "Found: `#{hit[:code]}`.", key: reference
39
+ Util.info "Found: `#{hit[:code]}`.", key: ref.to_s
39
40
  item
40
41
  end
41
42
 
42
43
  private
43
44
 
44
- def parse_format(reference, opts)
45
- ref = reference.sub(/\s\((DOC|PDF)\)$/, "")
45
+ def parse_format(ref, opts)
46
+ # A pubid carries no format suffix: Processor#query_pubid hands `get`
47
+ # the String whenever the reference has one.
48
+ return [ref, opts] unless ref.is_a?(String)
49
+
50
+ query = ref.sub(/\s\((DOC|PDF)\)$/, "")
46
51
  opts[:format] ||= Regexp.last_match(1)
47
- [ref, opts]
52
+ [query, opts]
48
53
  end
49
54
  public :parse_format
50
55
 
@@ -26,7 +26,7 @@ module Relaton
26
26
  end
27
27
 
28
28
  def pubid
29
- @pubid ||= Pubid::Ccsds::Identifier.parse(ref)
29
+ @pubid ||= ref.is_a?(String) ? Pubid::Ccsds::Identifier.parse(ref) : ref
30
30
  end
31
31
 
32
32
  def rows
@@ -25,8 +25,9 @@ module Relaton
25
25
 
26
26
  # A format (` (DOC)` or `opts[:format]`) keeps only the item's sources
27
27
  # of that format, a filter the Db cache cannot apply to a cached item:
28
- # such a query gets no key, so it is not cached.
29
- def cache_key(ref, year, opts)
28
+ # such a query gets no pubid, so it is not cached, and `get` receives
29
+ # the String with its format.
30
+ def query_pubid(ref, opts = {}, parsed = nil)
30
31
  require_relative "../ccsds"
31
32
  _, format_opts = Bibliography.parse_format(ref, opts.dup)
32
33
  return if format_opts[:format]
@@ -5,10 +5,10 @@ module Relaton
5
5
  # Class methods for search Cenelec standards.
6
6
  class Bibliography
7
7
  class << self
8
- # @param text [String]
8
+ # @param ref [String] the printed reference
9
9
  # @return [Relaton::Cen::HitCollection]
10
- def search(text, year = nil)
11
- HitCollection.new(text, year).search
10
+ def search(ref, year = nil)
11
+ HitCollection.new(ref, year).search
12
12
  rescue Mechanize::ResponseCodeError, Net::ReadTimeout => e
13
13
  raise Relaton::RequestError, e.message
14
14
  end
@@ -32,23 +32,24 @@ module Relaton
32
32
  end
33
33
 
34
34
  #
35
- # @param code [String] the CEN standard Code to look up
35
+ # @param ref [String, Pubid::CenCenelec::Identifier] the CEN standard
36
+ # reference to look up, or its parse from Relaton::Db (relaton#205)
36
37
  # @param year [String] the year the standard was published (optional)
37
38
  # @param opts [Hash] options
38
39
  # @option opts [Boolean] :keep_year don't upate reference
39
40
  #
40
41
  # @return [Relaton::Cen::ItemData, nil]
41
42
  #
42
- def get(code, year = nil, opts = {})
43
+ def get(ref, year = nil, opts = {})
43
44
  # An empty string is no reference, not a malformed one, so it stays a
44
45
  # plain nil rather than a parse failure. Mirrors the guard
45
46
  # HitCollection#search already carries.
46
- return if code.nil? || code.strip.empty?
47
+ return if ref.nil? || (ref.is_a?(String) && ref.strip.empty?)
47
48
 
48
- query = parse code
49
+ query = ref.is_a?(String) ? parse(ref) : ref
49
50
  year ||= publication_year query
50
51
 
51
- bib_get code, year, opts, query
52
+ bib_get ref.to_s, year, opts, query
52
53
  end
53
54
 
54
55
  private
@@ -77,10 +78,11 @@ module Relaton
77
78
  id.exclude(*keys) == id
78
79
  end
79
80
 
80
- def fetch_ref_err(_code, year, missed_years)
81
+ def fetch_ref_err(ref, year, missed_years)
81
82
  unless missed_years.empty?
82
83
  Util.info "There was no match for `#{year}`, though there " \
83
- "were matches found for `#{missed_years.join('`, `')}`."
84
+ "were matches found for `#{missed_years.join('`, `')}`.",
85
+ key: ref
84
86
  end
85
87
  nil
86
88
  end
@@ -88,10 +90,11 @@ module Relaton
88
90
  #
89
91
  # Selects the portal hits that denote the same document as the query.
90
92
  #
91
- # The search text stays the caller's raw reference — that is
92
- # search-engine input, not identifier parsing — while the SELECTION is
93
- # pubid's. A hit whose code the grammar cannot read is dropped rather
94
- # than aborting the search.
93
+ # The search text is the reference as printed (the caller's String, or
94
+ # the print of a pubid from Relaton::Db) — that is search-engine input,
95
+ # not identifier parsing — while the SELECTION is pubid's. A hit whose
96
+ # code the grammar cannot read is dropped rather than aborting the
97
+ # search.
95
98
  #
96
99
  # The selection is pubid's subset match `query === hit.pubid`. A part,
97
100
  # a year or a supplement year that the query omits matches any value.
@@ -101,13 +104,13 @@ module Relaton
101
104
  # amendment's record, and a supplement reference never answers with
102
105
  # its base document.
103
106
  #
104
- # @param code [String] the raw reference, as the portal form wants it
107
+ # @param ref [String] the printed reference, as the portal form wants it
105
108
  # @param query [Pubid::CenCenelec::Identifier]
106
109
  #
107
110
  # @return [Relaton::Cen::HitCollection]
108
111
  #
109
- def search_filter(code, query)
110
- search(code).select! { |hit| hit.pubid && query === hit.pubid }
112
+ def search_filter(ref, query)
113
+ search(ref).select! { |hit| hit.pubid && query === hit.pubid }
111
114
  end
112
115
 
113
116
  # Sort through the results from Isobib, fetching them three at a time,
@@ -129,18 +132,18 @@ module Relaton
129
132
  { years: missed_years }
130
133
  end
131
134
 
132
- def bib_get(code, year, opts, query) # rubocop:disable Metrics/MethodLength
133
- ref = year && absent?(query, :year) ? "#{code}:#{year}" : code
134
- Util.info "Fetching from standards.cencenelec.eu ...", key: ref
135
- result = search_filter(code, query)
135
+ def bib_get(ref, year, opts, query) # rubocop:disable Metrics/MethodLength
136
+ key = year && absent?(query, :year) ? "#{ref}:#{year}" : ref
137
+ Util.info "Fetching from standards.cencenelec.eu ...", key: key
138
+ result = search_filter(ref, query)
136
139
  ret = isobib_results_filter(result, year)
137
140
  if ret[:ret]
138
141
  bib = year || opts[:keep_year] ? ret[:ret] : ret[:ret].to_most_recent_reference
139
- Util.info "Found: `#{bib.docidentifier.first&.content}`", key: ref
142
+ Util.info "Found: `#{bib.docidentifier.first&.content}`", key: key
140
143
  bib
141
144
  else
142
- Util.info "Not found.", key: ref
143
- fetch_ref_err(code, year, ret[:years])
145
+ Util.info "Not found.", key: key
146
+ fetch_ref_err(ref, year, ret[:years])
144
147
  end
145
148
  end
146
149
  end
@@ -5,23 +5,25 @@ module Relaton
5
5
  # IETF bibliography module
6
6
  module Bibliography
7
7
  class << self
8
- # @param code [String] the ECMA standard Code to look up (e..g "ECMA-6")
8
+ # @param ref [String, Pubid::Cie::Identifier] the CIE reference (e.g.
9
+ # "CIE 001-1980"), or its parse from Relaton::Db (relaton#205)
9
10
  # @return [Relaton::Cie::ItemData]
10
- def search(code)
11
- Scrapper.scrape_page code
11
+ def search(ref)
12
+ Scrapper.scrape_page ref
12
13
  end
13
14
 
14
- # @param code [String] the ECMA standard Code to look up (e..g "ECMA-6")
15
+ # @param ref [String, Pubid::Cie::Identifier] the CIE reference (e.g.
16
+ # "CIE 001-1980"), or its parse from Relaton::Db (relaton#205)
15
17
  # @param year [String] not used
16
18
  # @param opts [Hash] not used
17
19
  # @return [Relaton::Cie::ItemData] Relaton of reference
18
- def get(code, _year = nil, _opts = {})
19
- Util.info "Fetching from Relaton repository ...", key: code
20
- result = search code
20
+ def get(ref, _year = nil, _opts = {})
21
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
22
+ result = search ref
21
23
  if result
22
- Util.info "Found: `#{result.docidentifier.first.content}`", key: code
24
+ Util.info "Found: `#{result.docidentifier.first.content}`", key: ref.to_s
23
25
  else
24
- Util.info "Not found.", key: code
26
+ Util.info "Not found.", key: ref.to_s
25
27
  end
26
28
  result
27
29
  end
@@ -6,14 +6,15 @@ module Relaton
6
6
  ENDPOINT = "https://raw.githubusercontent.com/relaton/relaton-data-cie/refs/heads/v2/".freeze
7
7
 
8
8
  class << self
9
- # @param code [String]
9
+ # @param ref [String, Pubid::Cie::Identifier] the reference, or the
10
+ # parse that Relaton::Db routed with (relaton#205)
10
11
  # @return [Relaton::Cie::ItemData]
11
- def scrape_page(code)
12
+ def scrape_page(ref)
12
13
  # An unrecognized reference raises; like ISO and 3GPP we let it
13
14
  # propagate -- relaton-cli rescues Pubid::Errors::Error and renders
14
15
  # "... is not a recognized standards identifier". Partial refs
15
16
  # (`CIE 001`, `CIE 15`) parse, so nothing valid is lost.
16
- pubid = ::Pubid::Cie.parse code
17
+ pubid = to_pubid ref
17
18
  index = Index.find_or_create :cie, url: "#{ENDPOINT}#{INDEXFILE}.zip", file: "#{INDEXFILE}.yaml",
18
19
  pubid_class: ::Pubid::Cie::Identifier
19
20
  # Pass the parsed pubid (not the raw String) so index-v2 narrows
@@ -26,25 +27,31 @@ module Relaton
26
27
  .min_by { |r| r[:id].to_s }
27
28
  return unless row
28
29
 
29
- parse_page "#{ENDPOINT}#{row[:file]}", code
30
+ parse_page "#{ENDPOINT}#{row[:file]}", ref.to_s
30
31
  end
31
32
 
32
33
  private
33
34
 
35
+ # @param ref [String, Pubid::Cie::Identifier]
36
+ # @return [Pubid::Cie::Identifier] parses only a String
37
+ def to_pubid(ref)
38
+ ref.is_a?(String) ? ::Pubid::Cie.parse(ref) : ref
39
+ end
40
+
34
41
  # @param url [String]
35
- # @param code [String]
42
+ # @param ref [String]
36
43
  # @retrurn [Relato::Cie::ItemData]
37
- def parse_page(url, code)
44
+ def parse_page(url, ref)
38
45
  resp = Mechanize.new.get url
39
46
  Item.from_yaml(resp.body).tap { |item| item.fetched = Date.today.to_s }
40
47
  rescue Mechanize::ResponseCodeError => e
41
48
  return if e.response_code == "404"
42
49
 
43
- raise Relaton::RequestError, "No document found for #{code} reference. #{e.message}"
50
+ raise Relaton::RequestError, "No document found for #{ref} reference. #{e.message}"
44
51
  rescue Mechanize::RedirectLimitReachedError, Timeout::Error,
45
52
  Mechanize::UnauthorizedError, Mechanize::UnsupportedSchemeError,
46
53
  Mechanize::ResponseReadError, Mechanize::ChunkedTerminationError => e
47
- raise Relaton::RequestError, "No document found for #{code} reference. #{e.message}"
54
+ raise Relaton::RequestError, "No document found for #{ref} reference. #{e.message}"
48
55
  end
49
56
  end
50
57
  end