relaton 3.0.0.pre.alpha.4 → 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 (120) 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/adobe/processor.rb +9 -0
  5. data/lib/relaton/bib/converter/csl.rb +110 -0
  6. data/lib/relaton/bib/converter/ris.rb +104 -0
  7. data/lib/relaton/bib/converter/titles.rb +24 -0
  8. data/lib/relaton/bib/item_data.rb +23 -0
  9. data/lib/relaton/bib/model/item.rb +6 -6
  10. data/lib/relaton/bib/sanitizer.rb +71 -30
  11. data/lib/relaton/bib.rb +10 -0
  12. data/lib/relaton/bipm/bibliography.rb +24 -21
  13. data/lib/relaton/bipm/processor.rb +1 -0
  14. data/lib/relaton/bipm/rawdata_bipm_metrologia/affiliations.rb +6 -6
  15. data/lib/relaton/bipm/si_brochure_parser.rb +2 -2
  16. data/lib/relaton/bsi/bibliography.rb +26 -23
  17. data/lib/relaton/bsi/processor.rb +5 -0
  18. data/lib/relaton/calconnect/bibliography.rb +6 -6
  19. data/lib/relaton/calconnect/hit_collection.rb +4 -1
  20. data/lib/relaton/ccsds/bibliography.rb +16 -10
  21. data/lib/relaton/ccsds/hit_collection.rb +1 -1
  22. data/lib/relaton/ccsds/processor.rb +13 -0
  23. data/lib/relaton/cen/bibliography.rb +27 -24
  24. data/lib/relaton/cen/hit_collection.rb +1 -1
  25. data/lib/relaton/cen/processor.rb +5 -0
  26. data/lib/relaton/cen/scraper.rb +9 -9
  27. data/lib/relaton/cie/bibliography.rb +11 -9
  28. data/lib/relaton/cie/data_fetcher.rb +18 -18
  29. data/lib/relaton/cie/processor.rb +1 -0
  30. data/lib/relaton/cie/scrapper.rb +15 -8
  31. data/lib/relaton/cie.rb +1 -1
  32. data/lib/relaton/cloud.rb +127 -0
  33. data/lib/relaton/core/hit_collection.rb +6 -10
  34. data/lib/relaton/core/processor.rb +121 -0
  35. data/lib/relaton/core/request_error.rb +21 -3
  36. data/lib/relaton/db/cache.rb +474 -148
  37. data/lib/relaton/db/cache_entry.rb +42 -0
  38. data/lib/relaton/db/registry.rb +152 -0
  39. data/lib/relaton/db.rb +275 -102
  40. data/lib/relaton/doi/crossref.rb +23 -6
  41. data/lib/relaton/doi/processor.rb +1 -0
  42. data/lib/relaton/easc/processor.rb +1 -0
  43. data/lib/relaton/ecma/bibliography.rb +18 -13
  44. data/lib/relaton/ecma/data_fetcher.rb +1 -1
  45. data/lib/relaton/ecma/data_parser.rb +1 -1
  46. data/lib/relaton/ecma/edition_parser.rb +2 -2
  47. data/lib/relaton/ecma/memento_parser.rb +4 -4
  48. data/lib/relaton/ecma/standard_parser.rb +6 -6
  49. data/lib/relaton/etsi/bibliography.rb +8 -7
  50. data/lib/relaton/etsi/processor.rb +1 -0
  51. data/lib/relaton/gb/bibliography.rb +20 -12
  52. data/lib/relaton/gb/gb_scraper.rb +5 -5
  53. data/lib/relaton/gb/scraper.rb +16 -16
  54. data/lib/relaton/gb/sec_scraper.rb +8 -8
  55. data/lib/relaton/gb/t_scraper.rb +5 -5
  56. data/lib/relaton/gost/processor.rb +1 -0
  57. data/lib/relaton/iala/bibliography.rb +15 -12
  58. data/lib/relaton/iala/processor.rb +1 -0
  59. data/lib/relaton/iana/bibliography.rb +12 -12
  60. data/lib/relaton/iana/data_fetcher.rb +3 -3
  61. data/lib/relaton/iana/parser.rb +12 -5
  62. data/lib/relaton/iana/processor.rb +9 -0
  63. data/lib/relaton/iec/bibliography.rb +18 -7
  64. data/lib/relaton/iec/data_parser.rb +24 -9
  65. data/lib/relaton/iec/processor.rb +11 -0
  66. data/lib/relaton/iec.rb +1 -1
  67. data/lib/relaton/ieee/bibliography.rb +19 -13
  68. data/lib/relaton/ieee/data_fetcher.rb +1 -1
  69. data/lib/relaton/ieee/processor.rb +24 -0
  70. data/lib/relaton/ieee/rawbib_id_parser.rb +2 -2
  71. data/lib/relaton/ietf/bibliography.rb +11 -9
  72. data/lib/relaton/ietf/data_fetcher.rb +1 -1
  73. data/lib/relaton/ietf/processor.rb +1 -0
  74. data/lib/relaton/ietf/rfc/entry.rb +15 -19
  75. data/lib/relaton/ietf/scraper.rb +5 -4
  76. data/lib/relaton/iho/processor.rb +1 -0
  77. data/lib/relaton/index/file_io.rb +2 -2
  78. data/lib/relaton/index/pool.rb +4 -3
  79. data/lib/relaton/index/shard_source.rb +1 -1
  80. data/lib/relaton/index/type.rb +2 -5
  81. data/lib/relaton/isbn/open_library.rb +11 -7
  82. data/lib/relaton/isbn/processor.rb +10 -0
  83. data/lib/relaton/iso/bibliography.rb +11 -9
  84. data/lib/relaton/iso/data_parser.rb +2 -2
  85. data/lib/relaton/iso/processor.rb +5 -0
  86. data/lib/relaton/iso/scraper.rb +20 -20
  87. data/lib/relaton/itu/bibliography.rb +107 -16
  88. data/lib/relaton/itu/data_crawler_r.rb +2 -2
  89. data/lib/relaton/itu/hit_collection.rb +64 -52
  90. data/lib/relaton/itu/processor.rb +1 -0
  91. data/lib/relaton/itu/scraper.rb +13 -3
  92. data/lib/relaton/itu.rb +0 -2
  93. data/lib/relaton/jis/bibliography.rb +22 -11
  94. data/lib/relaton/jis/data_fetcher.rb +4 -4
  95. data/lib/relaton/jis/processor.rb +1 -0
  96. data/lib/relaton/jis/scraper.rb +8 -8
  97. data/lib/relaton/nist/bibliography.rb +25 -21
  98. data/lib/relaton/oasis/bibliography.rb +16 -13
  99. data/lib/relaton/oasis/browser_agent.rb +2 -2
  100. data/lib/relaton/oasis/data_parser.rb +5 -5
  101. data/lib/relaton/oasis/data_parser_utils.rb +2 -2
  102. data/lib/relaton/oasis/data_part_parser.rb +7 -7
  103. data/lib/relaton/ogc/bibliography.rb +15 -14
  104. data/lib/relaton/ogc/hit_collection.rb +9 -7
  105. data/lib/relaton/ogc/processor.rb +13 -0
  106. data/lib/relaton/oiml/processor.rb +1 -0
  107. data/lib/relaton/omg/bibliography.rb +9 -9
  108. data/lib/relaton/omg/scraper.rb +14 -13
  109. data/lib/relaton/omg.rb +1 -1
  110. data/lib/relaton/plateau/bibliography.rb +9 -7
  111. data/lib/relaton/plateau/hit_collection.rb +2 -1
  112. data/lib/relaton/plateau/processor.rb +1 -0
  113. data/lib/relaton/un/bibliography.rb +21 -10
  114. data/lib/relaton/un/processor.rb +1 -0
  115. data/lib/relaton/version.rb +1 -1
  116. data/lib/relaton/w3c/processor.rb +1 -0
  117. data/lib/relaton/xsf/bibliography.rb +11 -6
  118. data/lib/relaton.rb +13 -0
  119. metadata +60 -14
  120. data/lib/relaton/itu/pubid.rb +0 -199
@@ -83,7 +83,7 @@ module Relaton
83
83
  # @param [#get] agent HTTP client responding to #get(url)
84
84
  # @param [Integer] retries number of retries
85
85
  #
86
- # @return [Nokogiri::HTML::Document, Mechanize::Page, nil] page or nil
86
+ # @return [Moxml::Document, Mechanize::Page, nil] page or nil
87
87
  #
88
88
  def retry_page(url, agent, retries = 3)
89
89
  sleep 1 # to avoid 429 error
@@ -156,7 +156,7 @@ module Relaton
156
156
  href = email[:href]
157
157
  if href.start_with?("mailto:")
158
158
  [href.split(":")[1]]
159
- elsif (cf_email = email.at(".//span[@data-cfemail]"))
159
+ elsif (cf_email = email.at_xpath(".//span[@data-cfemail]"))
160
160
  decoded = decode_cf_email(cf_email["data-cfemail"])
161
161
  return [] if decoded.empty?
162
162
 
@@ -7,7 +7,7 @@ module Relaton
7
7
  #
8
8
  # Initialize parser.
9
9
  #
10
- # @param [Nokogiri::HTML::Element] node document node
10
+ # @param [Moxml::Element] node document node
11
11
  #
12
12
  def initialize(node, errors = {}, agent: nil)
13
13
  @node = node
@@ -20,7 +20,7 @@ module Relaton
20
20
 
21
21
  sibling_xpath = "./strong/following-sibling::text()" \
22
22
  "|./span[strong]/following-sibling::text()"
23
- if @node.at(sibling_xpath)
23
+ if @node.at_xpath(sibling_xpath)
24
24
  nodes_xpath = "./strong/following-sibling::node()" \
25
25
  "|./span[strong]/following-sibling::node()"
26
26
  @text = @node.xpath(nodes_xpath).text.strip
@@ -34,7 +34,7 @@ module Relaton
34
34
 
35
35
  xpath = "./span[@class='citationTitle' " \
36
36
  "or @class='citeTitle']|./em|./i"
37
- t = @node.at(xpath)
37
+ t = @node.at_xpath(xpath)
38
38
  @title = if t
39
39
  t.text
40
40
  else
@@ -83,7 +83,7 @@ module Relaton
83
83
  # @return [String] document number
84
84
  #
85
85
  def parse_docnumber
86
- ref = @node.at("./span/strong|./strong|./b/span")
86
+ ref = @node.at_xpath("./span/strong|./strong|./b/span")
87
87
  num = ref.text.match(/[^\[\]]+/).to_s
88
88
  id = parse_errata(num)
89
89
  # some part refs need "Pt" to distinguish from root doc
@@ -183,7 +183,7 @@ module Relaton
183
183
  # @return [Array<Bib::Relation>] document relations
184
184
  #
185
185
  def parse_relation
186
- parser = DataParser.new(@node.at("./ancestor::details"), @errors, agent: @agent)
186
+ parser = DataParser.new(@node.at_xpath("./ancestor::details"), @errors, agent: @agent)
187
187
  fref = parser.parse_docid[0].content
188
188
  bib = ItemData.new(formattedref: Bib::Formattedref.new(content: fref))
189
189
  result = [Bib::Relation.new(type: "partOf", bibitem: bib)]
@@ -221,7 +221,7 @@ module Relaton
221
221
  end
222
222
 
223
223
  def link_node
224
- @link_node = @node.at("./a|./following-sibling::p[1]/a")
224
+ @link_node = @node.at_xpath("./a|./following-sibling::p[1]/a")
225
225
  end
226
226
 
227
227
  #
@@ -230,7 +230,7 @@ module Relaton
230
230
  # @return [Array<String>] technology areas
231
231
  #
232
232
  def parse_technology_area
233
- result = super(@node.at("./ancestor::details"))
233
+ result = super(@node.at_xpath("./ancestor::details"))
234
234
  @errors[:part_technology_area] &&= result.empty?
235
235
  result
236
236
  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,6 +21,19 @@ 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
+
30
+ # The `year` argument filters by publication year, but an OGC pubid's
31
+ # `year` is the year in the document number (`19` in `OGC 19-025r1`),
32
+ # so it cannot be folded into the key: such a query is not cached.
33
+ def cache_key(ref, year, opts, parsed = nil)
34
+ year ? nil : super
35
+ end
36
+
24
37
  # @param source [String]
25
38
  # @param opts [Hash]
26
39
  def fetch_data(_source, opts)
@@ -8,6 +8,7 @@ module Relaton
8
8
  def initialize
9
9
  @short = :relaton_oiml
10
10
  @prefix = "OIML"
11
+ @pubid_identifier = :Oiml # Db cache key
11
12
  @defaultprefix = %r{^OIML\s}
12
13
  @idtype = "OIML"
13
14
  end
@@ -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?
@@ -63,7 +64,7 @@ module Relaton
63
64
  end
64
65
 
65
66
  def fetch_title
66
- content = @doc.at('//dt[.="Title:"]/following-sibling::dd').text
67
+ content = @doc.at_xpath('//dt[.="Title:"]/following-sibling::dd').text
67
68
  content += ": #{@part}" if @part
68
69
  [Bib::Title.new(type: "main", content: content, language: "en", script: "Latn")]
69
70
  end
@@ -76,7 +77,7 @@ module Relaton
76
77
  end
77
78
 
78
79
  def fetch_abstract
79
- content = @doc.at('//section[@id="document-metadata"]/div/div/p').text
80
+ content = @doc.at_xpath('//section[@id="document-metadata"]/div/div/p').text
80
81
  [Bib::Abstract.new(content: content, language: "en", script: "Latn")]
81
82
  end
82
83
 
@@ -85,7 +86,7 @@ module Relaton
85
86
  end
86
87
 
87
88
  def doc_version
88
- @doc_version ||= @doc.at('//dt[.="Version:"]/following-sibling::dd/p/span').text
89
+ @doc_version ||= @doc.at_xpath('//dt[.="Version:"]/following-sibling::dd/p/span').text
89
90
  end
90
91
 
91
92
  def fetch_date
@@ -105,7 +106,7 @@ module Relaton
105
106
  #
106
107
  # @return [Date, nil]
107
108
  def jsonld_date
108
- script = @doc.at('//script[@type="application/ld+json"]')
109
+ script = @doc.at_xpath('//script[@type="application/ld+json"]')
109
110
  return unless script
110
111
 
111
112
  node = JSON.parse(script.text).find { |e| e.is_a?(Hash) && e[LD_DATE] }
@@ -117,7 +118,7 @@ module Relaton
117
118
 
118
119
  # @return [Date, nil]
119
120
  def dd_date
120
- text = @doc.at('//dt[.="Publication Date:"]/following-sibling::dd').text.strip
121
+ text = @doc.at_xpath('//dt[.="Publication Date:"]/following-sibling::dd').text.strip
121
122
  ::Date.parse text
122
123
  rescue ::Date::Error
123
124
  Util.warn "Cannot parse the publication date `#{text}`."
@@ -125,7 +126,7 @@ module Relaton
125
126
  end
126
127
 
127
128
  def fetch_status
128
- status = @doc.at('//dt[.="Document Status:"]/following-sibling::dd')
129
+ status = @doc.at_xpath('//dt[.="Document Status:"]/following-sibling::dd')
129
130
  stage = status.text.strip.match(/\w+/).to_s
130
131
  Bib::Status.new(stage: Bib::Status::Stage.new(content: stage))
131
132
  end
@@ -135,12 +136,12 @@ module Relaton
135
136
 
136
137
  @links = []
137
138
  if @part
138
- a = @doc.at("//a[@href='#{@url}/#{@part}/PDF']")
139
+ a = @doc.at_xpath("//a[@href='#{@url}/#{@part}/PDF']")
139
140
  @links << Bib::Uri.new(type: "src", content: a[:href]) if a
140
141
  else
141
- a = @doc.at('//dt[.="This Document:"]/following-sibling::dd/a')
142
+ a = @doc.at_xpath('//dt[.="This Document:"]/following-sibling::dd/a')
142
143
  @links << Bib::Uri.new(type: "src", content: a[:href]) if a
143
- pdf = @doc.at('//a[@class="download-document"]')
144
+ pdf = @doc.at_xpath('//a[@class="download-document"]')
144
145
  @links << Bib::Uri.new(type: "pdf", content: pdf[:href]) if pdf
145
146
  end
146
147
  @links
@@ -149,9 +150,9 @@ module Relaton
149
150
  def fetch_relation
150
151
  v = @doc.xpath('//h2[.="History"]/following-sibling::section/div/table/tbody/tr')
151
152
  v.reduce([]) do |mem, row|
152
- ver = row.at("td").text
153
+ ver = row.at_xpath("td").text
153
154
  unless ver == doc_version
154
- acronym = row.at("td[3]/a")[:href].split("/")[4]
155
+ acronym = row.at_xpath("td[3]/a")[:href].split("/")[4]
155
156
  id = render_id(acronym, ver)
156
157
  docid = Docidentifier.new(content: id, type: "OMG")
157
158
  bibitem = Bib::ItemBase.new(formattedref: Bib::Formattedref.new(content: id), docidentifier: [docid])
data/lib/relaton/omg.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "nokogiri"
1
+ require "moxml"
2
2
  require "relaton/bib"
3
3
  require_relative "version"
4
4
  require_relative "omg/util"
@@ -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
@@ -8,6 +8,7 @@ module Relaton
8
8
  def initialize # rubocop:disable Lint/MissingSuper
9
9
  @short = :relaton_plateau
10
10
  @prefix = "PLATEAU"
11
+ @pubid_identifier = :Plateau # Db cache key
11
12
  @defaultprefix = /^PLATEAU\s/
12
13
  @idtype = "PLATEAU"
13
14
  @datasets = %w[plateau-handbooks plateau-technical-reports]
@@ -15,25 +15,36 @@ module Relaton
15
15
  "Could not access #{HitCollection::API_BASE}: #{e.message}"
16
16
  end
17
17
 
18
- # @param ref [String] document reference
18
+ # @param ref [String, Pubid::Un::Identifier] document reference
19
19
  # @param year [String, NilClass]
20
20
  # @param opts [Hash] options
21
21
  # @return [Relaton::Bib::ItemData]
22
22
  def get(ref, _year = nil, _opts = {})
23
- Util.info "Fetching from documents.un.org ...", key: ref
24
- /^(?:UN\s)?(?<code>.*)/ =~ ref
25
- result = isobib_search_filter(code)
26
- if result
27
- Util.info "Found: `#{result.item.docidentifier[0].content}`", key: ref
28
- result.item
29
- else
30
- Util.info "Not found.", key: ref
31
- nil
23
+ key = ref.to_s
24
+ Util.info "Fetching from documents.un.org ...", key: key
25
+ item = isobib_search_filter(document_symbol(ref))&.item
26
+ unless item
27
+ Util.info "Not found.", key: key
28
+ return
32
29
  end
30
+
31
+ Util.info "Found: `#{item.docidentifier[0].content}`", key: key
32
+ item
33
33
  end
34
34
 
35
35
  private
36
36
 
37
+ # The UN document symbol to search for. A parsed pubid renders it
38
+ # (`TRADE/CEFACT/2004/32`); a String may start with a `UN ` token.
39
+ #
40
+ # @param ref [String, Pubid::Un::Identifier]
41
+ # @return [String]
42
+ def document_symbol(ref)
43
+ return ref.to_s unless ref.is_a?(String)
44
+
45
+ ref[/^(?:UN\s)?(.*)/, 1]
46
+ end
47
+
37
48
  # Search for hits.
38
49
  #
39
50
  # @param code [String] reference without correction
@@ -10,6 +10,7 @@ module Relaton
10
10
  def initialize
11
11
  @short = :relaton_un
12
12
  @prefix = "UN"
13
+ @pubid_identifier = :Un # Db cache key
13
14
  @defaultprefix = %r{^UN\s}
14
15
  @idtype = "UN"
15
16
  end
@@ -1,3 +1,3 @@
1
1
  module Relaton
2
- VERSION = "3.0.0.pre.alpha.4".freeze
2
+ VERSION = "3.0.0.pre.alpha.6".freeze
3
3
  end
@@ -8,6 +8,7 @@ module Relaton
8
8
  def initialize # rubocop:disable Lint/MissingSuper
9
9
  @short = :relaton_w3c
10
10
  @prefix = "W3C"
11
+ @pubid_identifier = :W3c # Db cache key
11
12
  @defaultprefix = %r{^W3C\s}
12
13
  @idtype = "W3C"
13
14
  @datasets = %w[w3c-api]
@@ -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
 
data/lib/relaton.rb CHANGED
@@ -5,6 +5,18 @@
5
5
  # `require "relaton/<flavor>"`, loading that flavor's code on demand rather than
6
6
  # at `require "relaton"`. When adding a flavor, add an autoload line here.
7
7
  require "relaton/version"
8
+ require "moxml"
9
+
10
+ # YAML through yeptris (Psych-compatible drop-in; stdlib Psych is kept
11
+ # as Yeptris::Psych::ORIGINAL). Must load before any YAML/Psych use.
12
+ # yeptris 0.5 moved the exclusive drop-in rebind to yeptris/psych/drop_in
13
+ # — plain yeptris/psych only defines the namespace and leaves stdlib
14
+ # Psych in place (yeptris-ruby#95, bug 3).
15
+ # Load stdlib Psych first: the drop-in keeps it as Yeptris::Psych::ORIGINAL,
16
+ # and a later plain require "psych" against the rebound constant is a
17
+ # superclass mismatch (yeptris-ruby#95, bug 3 follow-on).
18
+ require "psych"
19
+ require "yeptris/psych/drop_in"
8
20
 
9
21
  module Relaton
10
22
  autoload :Logger, "relaton/logger"
@@ -46,6 +58,7 @@ module Relaton
46
58
  autoload :Plateau, "relaton/plateau"
47
59
  autoload :Doi, "relaton/doi"
48
60
  autoload :Sdo, "relaton/sdo"
61
+ autoload :Cloud, "relaton/cloud"
49
62
 
50
63
  # Global PubID prefix register (relaton-db#103). Maps an SDO document-ID
51
64
  # prefix to the flavor module(s) that own it. Conflicting prefixes (e.g.