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
@@ -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
@@ -3,36 +3,37 @@ module Relaton
3
3
  module Bibliography
4
4
  extend self
5
5
 
6
- # @param text [String]
6
+ # @param ref [String, Pubid::Ogc::Identifier]
7
7
  # @param year [String, nil]
8
8
  # @return [Relaton::Ogc::HitCollection]
9
- def search(text, year = nil, _opts = {})
10
- code = text.sub(/^OGC\s/, "")
9
+ def search(ref, year = nil, _opts = {})
10
+ code = ref.is_a?(String) ? ref.sub(/^OGC\s/, "") : ref
11
11
  HitCollection.new(code, year).find
12
12
  rescue Faraday::ConnectionFailed, Faraday::SSLError
13
13
  raise Relaton::RequestError, HitCollection::ENDPOINT
14
14
  end
15
15
 
16
- # @param code [String]
16
+ # @param ref [String, Pubid::Ogc::Identifier] a reference, or its parse
17
+ # from Relaton::Db (relaton#205), which is used as it is
17
18
  # @param year [String, nil]
18
19
  # @param opts [Hash]
19
20
  # @return [Relaton::Ogc::ItemData, nil]
20
- def get(code, year = nil, opts = {})
21
- result = bib_search_filter(code, year, opts) || (return nil)
21
+ def get(ref, year = nil, opts = {})
22
+ result = bib_search_filter(ref, year, opts) || (return nil)
22
23
  ret = bib_results_filter(result, year)
23
24
  if ret[:ret]
24
- Util.info "Found: `#{ret[:ret].docidentifier.first.content}`", key: code
25
+ Util.info "Found: `#{ret[:ret].docidentifier.first.content}`", key: ref.to_s
25
26
  ret[:ret]
26
27
  else
27
- fetch_ref_err(code, year, ret[:years])
28
+ fetch_ref_err(ref, year, ret[:years])
28
29
  end
29
30
  end
30
31
 
31
32
  private
32
33
 
33
- def bib_search_filter(code, year, opts)
34
- Util.info "Fetching from Relaton repository ...", key: code
35
- search(code, year, opts)
34
+ def bib_search_filter(ref, year, opts)
35
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
36
+ search(ref, year, opts)
36
37
  end
37
38
 
38
39
  def bib_results_filter(result, year)
@@ -51,11 +52,11 @@ module Relaton
51
52
  { years: missed_years }
52
53
  end
53
54
 
54
- def fetch_ref_err(code, year, missed_years)
55
- Util.info "Not found.", key: code
55
+ def fetch_ref_err(ref, year, missed_years)
56
+ Util.info "Not found.", key: ref.to_s
56
57
  unless missed_years.empty?
57
58
  Util.info "There was no match for `#{year}`, though there " \
58
- "were matches found for `#{missed_years.join('`, `')}`.", key: code
59
+ "were matches found for `#{missed_years.join('`, `')}`.", key: ref.to_s
59
60
  end
60
61
  nil
61
62
  end
@@ -8,7 +8,7 @@ module Relaton
8
8
 
9
9
  # @return [self]
10
10
  def find
11
- return self if ref.nil? || ref.empty?
11
+ return self if ref.nil? || ref.to_s.empty?
12
12
 
13
13
  row = best_match ref
14
14
  return self unless row
@@ -50,7 +50,7 @@ module Relaton
50
50
  # `<nnn>` field alone, so one bucket holds every year that reused the
51
51
  # number (`05-007` and `17-007` share bucket `007`).
52
52
  #
53
- # @param text [String]
53
+ # @param ref [String, Pubid::Ogc::Identifier]
54
54
  # @return [Hash, nil]
55
55
  #
56
56
  # The substring-scan fallback this used to take when parsing failed is
@@ -59,8 +59,8 @@ module Relaton
59
59
  # ids, so an ambiguous reference silently resolved to whichever row
60
60
  # sorted first, instead of telling the caller the reference is not an
61
61
  # identifier. ecma, w3c and xsf never had one.
62
- def best_match(text)
63
- pubid = parse_ref text
62
+ def best_match(ref)
63
+ pubid = parse_ref ref
64
64
  rows = index.search(pubid)
65
65
  rows.max_by { |r| [revision_key(r[:id].revision), r[:file]] }
66
66
  end
@@ -93,7 +93,7 @@ module Relaton
93
93
  # lowercases the revision, so `OGC 19-025r1`, `19-025r1`, `11-038R2` and
94
94
  # the revision-less `16-079` all parse without normalization here.
95
95
  #
96
- # @param text [String]
96
+ # @param ref [String, Pubid::Ogc::Identifier] a pubid is returned as it is
97
97
  # @return [Pubid::Ogc::Identifier, nil]
98
98
  #
99
99
  # An unrecognized reference **raises**; like ISO, ETSI and 3GPP we let it
@@ -103,8 +103,10 @@ module Relaton
103
103
  # logs it through the `StandardError` arm at `lib/relaton/db.rb:122`.
104
104
  # Rescuing here would collapse "this identifier is malformed" into "no
105
105
  # such document", leaving a caller unable to tell them apart.
106
- def parse_ref(text)
107
- ::Pubid::Ogc::Identifier.parse text.to_s.strip
106
+ def parse_ref(ref)
107
+ return ref unless ref.is_a?(String)
108
+
109
+ ::Pubid::Ogc::Identifier.parse ref.strip
108
110
  end
109
111
  end
110
112
  end
@@ -21,10 +21,16 @@ module Relaton
21
21
  Bibliography.get(code, date, opts)
22
22
  end
23
23
 
24
+ # OGC documents print their identifier without the `OGC ` token
25
+ # (`19-025r1`).
26
+ def bare_identifiers?
27
+ true
28
+ end
29
+
24
30
  # The `year` argument filters by publication year, but an OGC pubid's
25
31
  # `year` is the year in the document number (`19` in `OGC 19-025r1`),
26
32
  # so it cannot be folded into the key: such a query is not cached.
27
- def cache_key(ref, year, opts)
33
+ def cache_key(ref, year, opts, parsed = nil)
28
34
  year ? nil : super
29
35
  end
30
36
 
@@ -6,23 +6,23 @@ module Relaton
6
6
  module Bibliography
7
7
  extend self
8
8
 
9
- # @param text [String] the OMG standard reference
9
+ # @param ref [String, Pubid::Omg::Identifier] the OMG standard reference
10
10
  # @return [Relaton::Omg::Item]
11
- def search(text)
12
- Scraper.scrape_page text
11
+ def search(ref)
12
+ Scraper.scrape_page ref
13
13
  end
14
14
 
15
- # @param code [String] the OMG standard reference
15
+ # @param ref [String, Pubid::Omg::Identifier] the OMG standard reference
16
16
  # @param year [String] the year the standard was published (optional)
17
17
  # @param opts [Hash] options
18
18
  # @return [Relaton::Omg::Item]
19
- def get(code, _year = nil, _opts = {})
20
- Util.info "Fetching from www.omg.org ...", key: code
21
- result = search code
19
+ def get(ref, _year = nil, _opts = {})
20
+ Util.info "Fetching from www.omg.org ...", key: ref.to_s
21
+ result = search ref
22
22
  if result
23
- Util.info "Found: `#{result.docidentifier.first.content}`", key: code
23
+ Util.info "Found: `#{result.docidentifier.first.content}`", key: ref.to_s
24
24
  else
25
- Util.info "Not found.", key: code
25
+ Util.info "Not found.", key: ref.to_s
26
26
  end
27
27
  result
28
28
  end
@@ -19,12 +19,13 @@ module Relaton
19
19
  @part = part
20
20
  end
21
21
 
22
- # @param ref [String] the OMG reference, e.g. "OMG UML 2.1.1 Superstructure"
22
+ # @param ref [String, Pubid::Omg::Identifier] the OMG reference, e.g.
23
+ # "OMG UML 2.1.1 Superstructure", or its parse from Relaton::Db
23
24
  # @return [Relaton::Omg::ItemData, nil] nil when the page is not found
24
25
  # @raise [Pubid::Errors::ParseError] when the reference is not an OMG
25
26
  # identifier
26
27
  def self.scrape_page(ref)
27
- pubid = ::Pubid::Omg::Identifier.parse(ref)
28
+ pubid = ref.is_a?(String) ? ::Pubid::Omg::Identifier.parse(ref) : ref
28
29
  scraper = new(pubid.acronym, pubid.version, pubid.part)
29
30
  doc = scraper.get_doc
30
31
  return if doc.nil? || scraper.fetch_link.empty?
@@ -3,22 +3,24 @@ module Relaton
3
3
  module Bibliography
4
4
  extend self
5
5
 
6
- def search(code)
7
- HitCollection.new(code).find
6
+ # @param ref [String, Pubid::Plateau::Identifier] the reference, or the
7
+ # parse that Relaton::Db routed with (relaton#205)
8
+ def search(ref)
9
+ HitCollection.new(ref).find
8
10
  end
9
11
 
10
12
  # Only a transport failure is rescued, and it becomes the
11
13
  # Relaton::RequestError that Relaton::Db retries. Anything else keeps
12
14
  # its own class: an unrecognized reference raises Pubid::Errors::ParseError
13
15
  # (relaton-cli reports it), and a bug keeps its backtrace.
14
- def get(code, _year = nil, _opts = {}) # rubocop:disable Metrics/MethodLength
15
- Util.info "Fetching ...", key: code
16
- result = search(code).fetch_doc
16
+ def get(ref, _year = nil, _opts = {}) # rubocop:disable Metrics/MethodLength
17
+ Util.info "Fetching ...", key: ref.to_s
18
+ result = search(ref).fetch_doc
17
19
  if result
18
- Util.info "Found `#{result.docidentifier.first.content}`", key: code
20
+ Util.info "Found `#{result.docidentifier.first.content}`", key: ref.to_s
19
21
  result
20
22
  else
21
- Util.warn "Not found.", key: code
23
+ Util.warn "Not found.", key: ref.to_s
22
24
  end
23
25
  rescue SocketError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
24
26
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
@@ -44,8 +44,9 @@ module Relaton
44
44
  # (metanorma/pubid #269) — so search accepts both forms. An unrecognized
45
45
  # reference raises; like ISO and 3GPP we let it propagate — relaton-cli
46
46
  # rescues Pubid::Errors::Error. See lib/relaton/plateau/CLAUDE.md.
47
+ # Relaton::Db passes the reference already parsed (relaton#205).
47
48
  def pubid_ref
48
- @pubid_ref ||= ::Pubid::Plateau.parse(ref)
49
+ @pubid_ref ||= ref.is_a?(String) ? ::Pubid::Plateau.parse(ref) : ref
49
50
  end
50
51
 
51
52
  # A reference with no edition (`PLATEAU Handbook #00`, or any Technical
@@ -1,3 +1,3 @@
1
1
  module Relaton
2
- VERSION = "3.0.0.pre.alpha.5".freeze
2
+ VERSION = "3.0.0.pre.alpha.7".freeze
3
3
  end
@@ -35,16 +35,18 @@ module Relaton
35
35
  HitCollection.new(parse_ref(ref)).search
36
36
  end
37
37
 
38
- def get(code, _year = nil, _opts = {})
39
- Util.info "Fetching from Relaton repository ...", key: code
40
- result = search(code)
38
+ # @param ref [String, Pubid::Xsf::Identifier] the reference, or the
39
+ # parse that Relaton::Db routed with (relaton#205)
40
+ def get(ref, _year = nil, _opts = {})
41
+ Util.info "Fetching from Relaton repository ...", key: ref.to_s
42
+ result = search(ref)
41
43
  if result.empty?
42
- Util.info "Not found.", key: code
44
+ Util.info "Not found.", key: ref.to_s
43
45
  return
44
46
  end
45
47
 
46
48
  bib = result.first.item
47
- Util.info "Found: `#{bib.docidentifier.first.content}`", key: code
49
+ Util.info "Found: `#{bib.docidentifier.first.content}`", key: ref.to_s
48
50
  bib
49
51
  end
50
52
 
@@ -66,11 +68,14 @@ module Relaton
66
68
  # Anything else raises -- see `.search`. `Pubid::Errors::ParseError`
67
69
  # includes `Pubid::Errors::Error`, which is the class relaton-cli rescues.
68
70
  #
69
- # @param ref [String]
71
+ # @param ref [String, Pubid::Xsf::Identifier]
70
72
  # @return [Pubid::Xsf::Identifier]
71
73
  # @raise [Pubid::Errors::ParseError]
72
74
  #
73
75
  def parse_ref(ref)
76
+ # A parsed pubid comes from Relaton::Db (relaton#205); it is used as it is.
77
+ return ref unless ref.is_a?(String)
78
+
74
79
  ::Pubid::Xsf::Identifier.parse normalize_ref(ref)
75
80
  end
76
81
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.pre.alpha.5
4
+ version: 3.0.0.pre.alpha.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-30 00:00:00.000000000 Z
11
+ date: 2026-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -428,14 +428,14 @@ dependencies:
428
428
  requirements:
429
429
  - - "~>"
430
430
  - !ruby/object:Gem::Version
431
- version: 2.0.0.pre.alpha.13
431
+ version: 2.0.0.pre.alpha.21
432
432
  type: :runtime
433
433
  prerelease: false
434
434
  version_requirements: !ruby/object:Gem::Requirement
435
435
  requirements:
436
436
  - - "~>"
437
437
  - !ruby/object:Gem::Version
438
- version: 2.0.0.pre.alpha.13
438
+ version: 2.0.0.pre.alpha.21
439
439
  - !ruby/object:Gem::Dependency
440
440
  name: yeptris
441
441
  requirement: !ruby/object:Gem::Requirement
@@ -450,6 +450,20 @@ dependencies:
450
450
  - - ">="
451
451
  - !ruby/object:Gem::Version
452
452
  version: '0.4'
453
+ - !ruby/object:Gem::Dependency
454
+ name: relaton-render
455
+ requirement: !ruby/object:Gem::Requirement
456
+ requirements:
457
+ - - "~>"
458
+ - !ruby/object:Gem::Version
459
+ version: 1.4.0.pre.alpha.1
460
+ type: :runtime
461
+ prerelease: false
462
+ version_requirements: !ruby/object:Gem::Requirement
463
+ requirements:
464
+ - - "~>"
465
+ - !ruby/object:Gem::Version
466
+ version: 1.4.0.pre.alpha.1
453
467
  - !ruby/object:Gem::Dependency
454
468
  name: rfcxml
455
469
  requirement: !ruby/object:Gem::Requirement