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.
- checksums.yaml +4 -4
- data/lib/relaton/3gpp/bibliography.rb +19 -6
- data/lib/relaton/3gpp/processor.rb +6 -0
- data/lib/relaton/adobe/processor.rb +9 -0
- data/lib/relaton/bib/converter/csl.rb +110 -0
- data/lib/relaton/bib/converter/ris.rb +104 -0
- data/lib/relaton/bib/converter/titles.rb +24 -0
- data/lib/relaton/bib/item_data.rb +23 -0
- data/lib/relaton/bib/model/item.rb +6 -6
- data/lib/relaton/bib/sanitizer.rb +71 -30
- data/lib/relaton/bib.rb +10 -0
- data/lib/relaton/bipm/bibliography.rb +24 -21
- data/lib/relaton/bipm/processor.rb +1 -0
- data/lib/relaton/bipm/rawdata_bipm_metrologia/affiliations.rb +6 -6
- data/lib/relaton/bipm/si_brochure_parser.rb +2 -2
- data/lib/relaton/bsi/bibliography.rb +26 -23
- data/lib/relaton/bsi/processor.rb +5 -0
- data/lib/relaton/calconnect/bibliography.rb +6 -6
- data/lib/relaton/calconnect/hit_collection.rb +4 -1
- data/lib/relaton/ccsds/bibliography.rb +16 -10
- data/lib/relaton/ccsds/hit_collection.rb +1 -1
- data/lib/relaton/ccsds/processor.rb +13 -0
- data/lib/relaton/cen/bibliography.rb +27 -24
- data/lib/relaton/cen/hit_collection.rb +1 -1
- data/lib/relaton/cen/processor.rb +5 -0
- data/lib/relaton/cen/scraper.rb +9 -9
- data/lib/relaton/cie/bibliography.rb +11 -9
- data/lib/relaton/cie/data_fetcher.rb +18 -18
- data/lib/relaton/cie/processor.rb +1 -0
- data/lib/relaton/cie/scrapper.rb +15 -8
- data/lib/relaton/cie.rb +1 -1
- data/lib/relaton/cloud.rb +127 -0
- data/lib/relaton/core/hit_collection.rb +6 -10
- data/lib/relaton/core/processor.rb +121 -0
- data/lib/relaton/core/request_error.rb +21 -3
- data/lib/relaton/db/cache.rb +474 -148
- data/lib/relaton/db/cache_entry.rb +42 -0
- data/lib/relaton/db/registry.rb +152 -0
- data/lib/relaton/db.rb +275 -102
- data/lib/relaton/doi/crossref.rb +23 -6
- data/lib/relaton/doi/processor.rb +1 -0
- data/lib/relaton/easc/processor.rb +1 -0
- data/lib/relaton/ecma/bibliography.rb +18 -13
- data/lib/relaton/ecma/data_fetcher.rb +1 -1
- data/lib/relaton/ecma/data_parser.rb +1 -1
- data/lib/relaton/ecma/edition_parser.rb +2 -2
- data/lib/relaton/ecma/memento_parser.rb +4 -4
- data/lib/relaton/ecma/standard_parser.rb +6 -6
- data/lib/relaton/etsi/bibliography.rb +8 -7
- data/lib/relaton/etsi/processor.rb +1 -0
- data/lib/relaton/gb/bibliography.rb +20 -12
- data/lib/relaton/gb/gb_scraper.rb +5 -5
- data/lib/relaton/gb/scraper.rb +16 -16
- data/lib/relaton/gb/sec_scraper.rb +8 -8
- data/lib/relaton/gb/t_scraper.rb +5 -5
- data/lib/relaton/gost/processor.rb +1 -0
- data/lib/relaton/iala/bibliography.rb +15 -12
- data/lib/relaton/iala/processor.rb +1 -0
- data/lib/relaton/iana/bibliography.rb +12 -12
- data/lib/relaton/iana/data_fetcher.rb +3 -3
- data/lib/relaton/iana/parser.rb +12 -5
- data/lib/relaton/iana/processor.rb +9 -0
- data/lib/relaton/iec/bibliography.rb +18 -7
- data/lib/relaton/iec/data_parser.rb +24 -9
- data/lib/relaton/iec/processor.rb +11 -0
- data/lib/relaton/iec.rb +1 -1
- data/lib/relaton/ieee/bibliography.rb +19 -13
- data/lib/relaton/ieee/data_fetcher.rb +1 -1
- data/lib/relaton/ieee/processor.rb +24 -0
- data/lib/relaton/ieee/rawbib_id_parser.rb +2 -2
- data/lib/relaton/ietf/bibliography.rb +11 -9
- data/lib/relaton/ietf/data_fetcher.rb +1 -1
- data/lib/relaton/ietf/processor.rb +1 -0
- data/lib/relaton/ietf/rfc/entry.rb +15 -19
- data/lib/relaton/ietf/scraper.rb +5 -4
- data/lib/relaton/iho/processor.rb +1 -0
- data/lib/relaton/index/file_io.rb +2 -2
- data/lib/relaton/index/pool.rb +4 -3
- data/lib/relaton/index/shard_source.rb +1 -1
- data/lib/relaton/index/type.rb +2 -5
- data/lib/relaton/isbn/open_library.rb +11 -7
- data/lib/relaton/isbn/processor.rb +10 -0
- data/lib/relaton/iso/bibliography.rb +11 -9
- data/lib/relaton/iso/data_parser.rb +2 -2
- data/lib/relaton/iso/processor.rb +5 -0
- data/lib/relaton/iso/scraper.rb +20 -20
- data/lib/relaton/itu/bibliography.rb +107 -16
- data/lib/relaton/itu/data_crawler_r.rb +2 -2
- data/lib/relaton/itu/hit_collection.rb +64 -52
- data/lib/relaton/itu/processor.rb +1 -0
- data/lib/relaton/itu/scraper.rb +13 -3
- data/lib/relaton/itu.rb +0 -2
- data/lib/relaton/jis/bibliography.rb +22 -11
- data/lib/relaton/jis/data_fetcher.rb +4 -4
- data/lib/relaton/jis/processor.rb +1 -0
- data/lib/relaton/jis/scraper.rb +8 -8
- data/lib/relaton/nist/bibliography.rb +25 -21
- data/lib/relaton/oasis/bibliography.rb +16 -13
- data/lib/relaton/oasis/browser_agent.rb +2 -2
- data/lib/relaton/oasis/data_parser.rb +5 -5
- data/lib/relaton/oasis/data_parser_utils.rb +2 -2
- data/lib/relaton/oasis/data_part_parser.rb +7 -7
- data/lib/relaton/ogc/bibliography.rb +15 -14
- data/lib/relaton/ogc/hit_collection.rb +9 -7
- data/lib/relaton/ogc/processor.rb +13 -0
- data/lib/relaton/oiml/processor.rb +1 -0
- data/lib/relaton/omg/bibliography.rb +9 -9
- data/lib/relaton/omg/scraper.rb +14 -13
- data/lib/relaton/omg.rb +1 -1
- data/lib/relaton/plateau/bibliography.rb +9 -7
- data/lib/relaton/plateau/hit_collection.rb +2 -1
- data/lib/relaton/plateau/processor.rb +1 -0
- data/lib/relaton/un/bibliography.rb +21 -10
- data/lib/relaton/un/processor.rb +1 -0
- data/lib/relaton/version.rb +1 -1
- data/lib/relaton/w3c/processor.rb +1 -0
- data/lib/relaton/xsf/bibliography.rb +11 -6
- data/lib/relaton.rb +13 -0
- metadata +60 -14
- 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 [
|
|
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.
|
|
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 [
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
6
|
+
# @param ref [String, Pubid::Ogc::Identifier]
|
|
7
7
|
# @param year [String, nil]
|
|
8
8
|
# @return [Relaton::Ogc::HitCollection]
|
|
9
|
-
def search(
|
|
10
|
-
code =
|
|
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
|
|
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(
|
|
21
|
-
result = bib_search_filter(
|
|
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:
|
|
25
|
+
Util.info "Found: `#{ret[:ret].docidentifier.first.content}`", key: ref.to_s
|
|
25
26
|
ret[:ret]
|
|
26
27
|
else
|
|
27
|
-
fetch_ref_err(
|
|
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(
|
|
34
|
-
Util.info "Fetching from Relaton repository ...", key:
|
|
35
|
-
search(
|
|
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(
|
|
55
|
-
Util.info "Not found.", key:
|
|
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:
|
|
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
|
|
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(
|
|
63
|
-
pubid = parse_ref
|
|
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
|
|
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(
|
|
107
|
-
|
|
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)
|
|
@@ -6,23 +6,23 @@ module Relaton
|
|
|
6
6
|
module Bibliography
|
|
7
7
|
extend self
|
|
8
8
|
|
|
9
|
-
# @param
|
|
9
|
+
# @param ref [String, Pubid::Omg::Identifier] the OMG standard reference
|
|
10
10
|
# @return [Relaton::Omg::Item]
|
|
11
|
-
def search(
|
|
12
|
-
Scraper.scrape_page
|
|
11
|
+
def search(ref)
|
|
12
|
+
Scraper.scrape_page ref
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
# @param
|
|
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(
|
|
20
|
-
Util.info "Fetching from www.omg.org ...", key:
|
|
21
|
-
result = search
|
|
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:
|
|
23
|
+
Util.info "Found: `#{result.docidentifier.first.content}`", key: ref.to_s
|
|
24
24
|
else
|
|
25
|
-
Util.info "Not found.", key:
|
|
25
|
+
Util.info "Not found.", key: ref.to_s
|
|
26
26
|
end
|
|
27
27
|
result
|
|
28
28
|
end
|
data/lib/relaton/omg/scraper.rb
CHANGED
|
@@ -19,12 +19,13 @@ module Relaton
|
|
|
19
19
|
@part = part
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# @param ref [String] the OMG reference, e.g.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
153
|
+
ver = row.at_xpath("td").text
|
|
153
154
|
unless ver == doc_version
|
|
154
|
-
acronym = row.
|
|
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
|
@@ -3,22 +3,24 @@ module Relaton
|
|
|
3
3
|
module Bibliography
|
|
4
4
|
extend self
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
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(
|
|
15
|
-
Util.info "Fetching ...", key:
|
|
16
|
-
result = search(
|
|
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:
|
|
20
|
+
Util.info "Found `#{result.docidentifier.first.content}`", key: ref.to_s
|
|
19
21
|
result
|
|
20
22
|
else
|
|
21
|
-
Util.warn "Not found.", key:
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Util.info "
|
|
28
|
-
|
|
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
|
data/lib/relaton/un/processor.rb
CHANGED
data/lib/relaton/version.rb
CHANGED
|
@@ -35,16 +35,18 @@ module Relaton
|
|
|
35
35
|
HitCollection.new(parse_ref(ref)).search
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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:
|
|
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:
|
|
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.
|