relaton 3.0.0.pre.alpha.1 → 3.0.0.pre.alpha.2
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/README.adoc +57 -1
- data/bin/console +0 -1
- data/lib/relaton/3gpp/bibliography.rb +82 -7
- data/lib/relaton/3gpp/data_fetcher.rb +51 -3
- data/lib/relaton/3gpp/docidentifier.rb +114 -0
- data/lib/relaton/3gpp/item.rb +6 -0
- data/lib/relaton/3gpp/parser.rb +1 -1
- data/lib/relaton/3gpp/processor.rb +4 -1
- data/lib/relaton/3gpp.rb +5 -1
- data/lib/relaton/adobe/bibdata.rb +8 -0
- data/lib/relaton/adobe/bibitem.rb +8 -0
- data/lib/relaton/adobe/bibliography.rb +92 -0
- data/lib/relaton/adobe/docidentifier.rb +49 -0
- data/lib/relaton/adobe/doctype.rb +14 -0
- data/lib/relaton/adobe/ext.rb +32 -0
- data/lib/relaton/adobe/item.rb +15 -0
- data/lib/relaton/adobe/item_base.rb +18 -0
- data/lib/relaton/adobe/item_data.rb +6 -0
- data/lib/relaton/adobe/processor.rb +45 -0
- data/lib/relaton/adobe/util.rb +8 -0
- data/lib/relaton/adobe.rb +37 -0
- data/lib/relaton/bib/model/address.rb +2 -2
- data/lib/relaton/bib/model/docidentifier.rb +24 -9
- data/lib/relaton/bib/model/localized_string.rb +1 -1
- data/lib/relaton/bib/model/structured_identifier.rb +10 -9
- data/lib/relaton/bib/sanitizer.rb +202 -6
- data/lib/relaton/bib.rb +0 -2
- data/lib/relaton/bipm/bibliography.rb +159 -10
- data/lib/relaton/bipm/data_fetcher.rb +26 -2
- data/lib/relaton/bipm/data_outcomes_parser.rb +3 -4
- data/lib/relaton/bipm/id_parser.rb +5 -4
- data/lib/relaton/bipm/model/structured_identifier.rb +21 -0
- data/lib/relaton/bipm/processor.rb +2 -2
- data/lib/relaton/bipm/rawdata_bipm_metrologia/fetcher.rb +2 -4
- data/lib/relaton/bipm/si_brochure_parser.rb +5 -3
- data/lib/relaton/bipm.rb +7 -1
- data/lib/relaton/bsi/bibliography.rb +115 -43
- data/lib/relaton/bsi/hit.rb +14 -0
- data/lib/relaton/bsi/hit_collection.rb +15 -16
- data/lib/relaton/bsi/model/docidentifier.rb +99 -1
- data/lib/relaton/bsi/processor.rb +1 -0
- data/lib/relaton/calconnect/bibliography.rb +12 -14
- data/lib/relaton/calconnect/data_fetcher.rb +77 -9
- data/lib/relaton/calconnect/docidentifier.rb +80 -0
- data/lib/relaton/calconnect/hit_collection.rb +65 -57
- data/lib/relaton/calconnect/model/item.rb +7 -0
- data/lib/relaton/calconnect/processor.rb +7 -1
- data/lib/relaton/calconnect.rb +11 -1
- data/lib/relaton/ccsds/data/fetcher.rb +17 -12
- data/lib/relaton/ccsds/data/parser.rb +1 -1
- data/lib/relaton/ccsds/hit_collection.rb +6 -1
- data/lib/relaton/ccsds/model/docidentifier.rb +121 -0
- data/lib/relaton/ccsds/model/item.rb +2 -0
- data/lib/relaton/cen/bibliography.rb +75 -47
- data/lib/relaton/cen/hit.rb +16 -1
- data/lib/relaton/cen/hit_collection.rb +59 -11
- data/lib/relaton/cen/model/docidentifier.rb +92 -1
- data/lib/relaton/cen/processor.rb +13 -8
- data/lib/relaton/cen/scraper.rb +13 -5
- data/lib/relaton/cen.rb +1 -0
- data/lib/relaton/cie/data_fetcher.rb +215 -30
- data/lib/relaton/cie/processor.rb +3 -1
- data/lib/relaton/cie/scrapper.rb +15 -2
- data/lib/relaton/cie.rb +2 -1
- data/lib/relaton/core/data_fetcher.rb +150 -3
- data/lib/relaton/core/governor.rb +320 -0
- data/lib/relaton/core/pacer.rb +134 -0
- data/lib/relaton/core/processor.rb +19 -0
- data/lib/relaton/core/request_error.rb +14 -0
- data/lib/relaton/core.rb +3 -0
- data/lib/relaton/db/registry.rb +41 -1
- data/lib/relaton/doi/crossref.rb +19 -2
- data/lib/relaton/doi/parser.rb +109 -15
- data/lib/relaton/easc/bibdata.rb +8 -0
- data/lib/relaton/easc/bibitem.rb +8 -0
- data/lib/relaton/easc/bibliography.rb +95 -0
- data/lib/relaton/easc/docidentifier.rb +100 -0
- data/lib/relaton/easc/doctype.rb +14 -0
- data/lib/relaton/easc/ext.rb +44 -0
- data/lib/relaton/easc/item.rb +13 -0
- data/lib/relaton/easc/item_base.rb +18 -0
- data/lib/relaton/easc/item_data.rb +6 -0
- data/lib/relaton/easc/processor.rb +46 -0
- data/lib/relaton/easc/util.rb +8 -0
- data/lib/relaton/easc.rb +35 -0
- data/lib/relaton/ecma/bibliography.rb +93 -25
- data/lib/relaton/ecma/data_fetcher.rb +71 -12
- data/lib/relaton/ecma/docidentifier.rb +124 -0
- data/lib/relaton/ecma/item.rb +2 -0
- data/lib/relaton/ecma/memento_parser.rb +1 -1
- data/lib/relaton/ecma/page_fetcher.rb +15 -3
- data/lib/relaton/ecma/parser_common.rb +2 -2
- data/lib/relaton/ecma/processor.rb +4 -1
- data/lib/relaton/ecma/standard_parser.rb +2 -2
- data/lib/relaton/ecma.rb +10 -1
- data/lib/relaton/etsi/bibliography.rb +67 -2
- data/lib/relaton/etsi/data_fetcher.rb +43 -4
- data/lib/relaton/etsi/processor.rb +3 -1
- data/lib/relaton/etsi.rb +2 -1
- data/lib/relaton/gb/bibliography.rb +55 -29
- data/lib/relaton/gb/docidentifier.rb +58 -9
- data/lib/relaton/gb/processor.rb +3 -0
- data/lib/relaton/gb/scraper.rb +27 -10
- data/lib/relaton/gost/bibdata.rb +8 -0
- data/lib/relaton/gost/bibitem.rb +8 -0
- data/lib/relaton/gost/bibliography.rb +107 -0
- data/lib/relaton/gost/docidentifier.rb +80 -0
- data/lib/relaton/gost/doctype.rb +16 -0
- data/lib/relaton/gost/ext.rb +46 -0
- data/lib/relaton/gost/item.rb +15 -0
- data/lib/relaton/gost/item_base.rb +18 -0
- data/lib/relaton/gost/item_data.rb +6 -0
- data/lib/relaton/gost/processor.rb +49 -0
- data/lib/relaton/gost/util.rb +8 -0
- data/lib/relaton/gost.rb +36 -0
- data/lib/relaton/iala/bibdata.rb +8 -0
- data/lib/relaton/iala/bibitem.rb +8 -0
- data/lib/relaton/iala/bibliography.rb +146 -0
- data/lib/relaton/iala/docidentifier.rb +89 -0
- data/lib/relaton/iala/doctype.rb +18 -0
- data/lib/relaton/iala/ext.rb +32 -0
- data/lib/relaton/iala/item.rb +21 -0
- data/lib/relaton/iala/item_base.rb +18 -0
- data/lib/relaton/iala/item_data.rb +6 -0
- data/lib/relaton/iala/processor.rb +43 -0
- data/lib/relaton/iala/relation.rb +7 -0
- data/lib/relaton/iala/util.rb +8 -0
- data/lib/relaton/iala.rb +35 -0
- data/lib/relaton/iana/bibliography.rb +67 -14
- data/lib/relaton/iana/data_fetcher.rb +35 -5
- data/lib/relaton/iana/processor.rb +3 -1
- data/lib/relaton/iana.rb +12 -1
- data/lib/relaton/iec/data_fetcher.rb +7 -1
- data/lib/relaton/iec/hit_collection.rb +1 -1
- data/lib/relaton/iec/model/docidentifier.rb +9 -5
- data/lib/relaton/iec/model/ext.rb +2 -2
- data/lib/relaton/iec/processor.rb +1 -0
- data/lib/relaton/ieee/bibliography.rb +25 -3
- data/lib/relaton/ieee/data_fetcher.rb +158 -17
- data/lib/relaton/ieee/idams_parser.rb +18 -11
- data/lib/relaton/ieee/processor.rb +4 -1
- data/lib/relaton/ieee/rawbib_id_parser.rb +291 -86
- data/lib/relaton/ieee.rb +2 -1
- data/lib/relaton/ietf/data_fetcher.rb +295 -12
- data/lib/relaton/ietf/processor.rb +7 -3
- data/lib/relaton/ietf/rfc/entry.rb +39 -3
- data/lib/relaton/ietf/scraper.rb +69 -36
- data/lib/relaton/ietf.rb +4 -1
- data/lib/relaton/iho/bibliography.rb +1 -1
- data/lib/relaton/iho/docidentifier.rb +1 -1
- data/lib/relaton/index/file_io.rb +11 -11
- data/lib/relaton/index/file_storage.rb +6 -1
- data/lib/relaton/index/pool.rb +6 -1
- data/lib/relaton/index/shard_source.rb +201 -0
- data/lib/relaton/index/type.rb +63 -12
- data/lib/relaton/index.rb +2 -1
- data/lib/relaton/iso/bibliography.rb +20 -15
- data/lib/relaton/iso/data_fetcher.rb +3 -3
- data/lib/relaton/iso/data_parser.rb +17 -3
- data/lib/relaton/iso/hit_collection.rb +27 -15
- data/lib/relaton/iso/item_data.rb +22 -0
- data/lib/relaton/iso/model/docidentifier.rb +24 -12
- data/lib/relaton/iso/processor.rb +1 -0
- data/lib/relaton/iso/scraper.rb +19 -3
- data/lib/relaton/itu/bibliography.rb +9 -4
- data/lib/relaton/itu/data_crawler_r.rb +664 -0
- data/lib/relaton/itu/data_fetcher.rb +496 -50
- data/lib/relaton/itu/data_merge_r.rb +149 -0
- data/lib/relaton/itu/data_parser_r.rb +163 -89
- data/lib/relaton/itu/data_parser_t.rb +228 -0
- data/lib/relaton/itu/family_cache.rb +177 -0
- data/lib/relaton/itu/governor.rb +56 -0
- data/lib/relaton/itu/hit.rb +9 -3
- data/lib/relaton/itu/hit_collection.rb +258 -86
- data/lib/relaton/itu/model/docidentifier.rb +67 -1
- data/lib/relaton/itu/model/structured_identifier.rb +19 -0
- data/lib/relaton/itu/processor.rb +10 -4
- data/lib/relaton/itu/pubid.rb +27 -5
- data/lib/relaton/itu/recommendation_fields.rb +334 -0
- data/lib/relaton/itu/recommendation_parser.rb +18 -149
- data/lib/relaton/itu/scraper.rb +13 -3
- data/lib/relaton/itu.rb +2 -1
- data/lib/relaton/jcgm/bibdata.rb +8 -0
- data/lib/relaton/jcgm/bibitem.rb +8 -0
- data/lib/relaton/jcgm/bibliography.rb +97 -0
- data/lib/relaton/jcgm/data_fetcher.rb +81 -0
- data/lib/relaton/jcgm/docidentifier.rb +102 -0
- data/lib/relaton/jcgm/doctype.rb +12 -0
- data/lib/relaton/jcgm/ext.rb +23 -0
- data/lib/relaton/jcgm/item.rb +20 -0
- data/lib/relaton/jcgm/item_base.rb +18 -0
- data/lib/relaton/jcgm/item_data.rb +6 -0
- data/lib/relaton/jcgm/meetings_parser.rb +175 -0
- data/lib/relaton/jcgm/processor.rb +71 -0
- data/lib/relaton/jcgm/relation.rb +9 -0
- data/lib/relaton/jcgm/structured_identifier.rb +40 -0
- data/lib/relaton/jcgm/util.rb +8 -0
- data/lib/relaton/jcgm.rb +24 -0
- data/lib/relaton/jis/bibliography.rb +8 -10
- data/lib/relaton/jis/data_fetcher.rb +21 -19
- data/lib/relaton/jis/docidentifier.rb +104 -5
- data/lib/relaton/jis/hit.rb +18 -23
- data/lib/relaton/jis/hit_collection.rb +19 -18
- data/lib/relaton/jis/processor.rb +1 -1
- data/lib/relaton/jis.rb +2 -3
- data/lib/relaton/logger/channels/gh_issue.rb +78 -13
- data/lib/relaton/nist/data_fetcher.rb +63 -13
- data/lib/relaton/nist/docidentifier.rb +165 -0
- data/lib/relaton/nist/item.rb +2 -0
- data/lib/relaton/nist/item_base.rb +16 -0
- data/lib/relaton/nist/mods_parser.rb +38 -12
- data/lib/relaton/nist/processor.rb +2 -1
- data/lib/relaton/nist/relation.rb +3 -0
- data/lib/relaton/nist/scraper.rb +6 -3
- data/lib/relaton/oasis/bibliography.rb +147 -6
- data/lib/relaton/oasis/data_fetcher.rb +41 -5
- data/lib/relaton/oasis/data_parser_utils.rb +37 -3
- data/lib/relaton/oasis/docidentifier.rb +54 -0
- data/lib/relaton/oasis/item.rb +3 -0
- data/lib/relaton/oasis/processor.rb +7 -1
- data/lib/relaton/oasis.rb +14 -1
- data/lib/relaton/ogc/data_fetcher.rb +23 -2
- data/lib/relaton/ogc/docidentifier.rb +105 -0
- data/lib/relaton/ogc/hit_collection.rb +78 -3
- data/lib/relaton/ogc/processor.rb +2 -1
- data/lib/relaton/ogc.rb +5 -1
- data/lib/relaton/oiml/bibliography.rb +90 -15
- data/lib/relaton/oiml/docidentifier.rb +18 -3
- data/lib/relaton/omg/docidentifier.rb +67 -0
- data/lib/relaton/omg/item.rb +1 -0
- data/lib/relaton/omg/processor.rb +1 -0
- data/lib/relaton/omg/scraper.rb +61 -16
- data/lib/relaton/omg.rb +1 -0
- data/lib/relaton/plateau/bibliography.rb +10 -3
- data/lib/relaton/plateau/data_fetcher.rb +25 -2
- data/lib/relaton/plateau/handbook_parser.rb +8 -1
- data/lib/relaton/plateau/hit.rb +10 -2
- data/lib/relaton/plateau/hit_collection.rb +31 -11
- data/lib/relaton/plateau/processor.rb +3 -1
- data/lib/relaton/plateau/technical_report_parser.rb +8 -1
- data/lib/relaton/plateau.rb +2 -1
- data/lib/relaton/sdo/config.rb +34 -0
- data/lib/relaton/sdo/fetcher.rb +52 -0
- data/lib/relaton/sdo/logo.rb +95 -0
- data/lib/relaton/sdo/name.rb +26 -0
- data/lib/relaton/sdo/organization.rb +71 -0
- data/lib/relaton/sdo/store.rb +49 -0
- data/lib/relaton/sdo.rb +29 -0
- data/lib/relaton/version.rb +1 -1
- data/lib/relaton/w3c/bibliography.rb +132 -12
- data/lib/relaton/w3c/data_fetcher.rb +194 -16
- data/lib/relaton/w3c/data_parser.rb +3 -3
- data/lib/relaton/w3c/docidentifier.rb +48 -0
- data/lib/relaton/w3c/governor.rb +32 -0
- data/lib/relaton/w3c/item.rb +3 -0
- data/lib/relaton/w3c/pubid.rb +12 -0
- data/lib/relaton/w3c/safe_realize.rb +110 -21
- data/lib/relaton/w3c.rb +12 -1
- data/lib/relaton/xsf/bibliography.rb +61 -1
- data/lib/relaton/xsf/data_fetcher.rb +55 -5
- data/lib/relaton/xsf/docidentifier.rb +46 -0
- data/lib/relaton/xsf/hit_collection.rb +31 -3
- data/lib/relaton/xsf/item.rb +6 -0
- data/lib/relaton/xsf/processor.rb +1 -0
- data/lib/relaton/xsf.rb +5 -1
- data/lib/relaton.rb +42 -0
- metadata +135 -24
- data/lib/relaton/ieee/pub_id.rb +0 -161
- data/lib/relaton/index/id_number.rb +0 -30
|
@@ -3,8 +3,36 @@ module Relaton
|
|
|
3
3
|
module Bibliography
|
|
4
4
|
extend self
|
|
5
5
|
|
|
6
|
+
#
|
|
7
|
+
# Search the index for a reference.
|
|
8
|
+
#
|
|
9
|
+
# The reference is parsed into a `Pubid::Xsf::Identifier` here and the
|
|
10
|
+
# identifier -- never the string -- is what reaches `HitCollection`.
|
|
11
|
+
# `Index::Type#search_candidates` narrows only when its argument is not a
|
|
12
|
+
# `String`, so parsing at the entry point is what lets the lookup binary
|
|
13
|
+
# search; `Core::HitCollection` takes a `String` or a pubid by design.
|
|
14
|
+
#
|
|
15
|
+
# An unrecognized reference **raises**; like ISO, ETSI and 3GPP we let it
|
|
16
|
+
# propagate. relaton-cli rescues `Pubid::Errors::Error` and renders
|
|
17
|
+
# `"..." is not a recognized standards identifier`
|
|
18
|
+
# (`gems/relaton-cli/lib/relaton/cli/command.rb:324`,
|
|
19
|
+
# `subcommand_collection.rb:134`), and `Db#fetch` logs it via the
|
|
20
|
+
# `StandardError` arm at `lib/relaton/db.rb:122`. Rescuing here would
|
|
21
|
+
# collapse "this identifier is malformed" into "no such document", and a
|
|
22
|
+
# caller could no longer tell them apart.
|
|
23
|
+
#
|
|
24
|
+
# There is also deliberately no substring fallback: the old
|
|
25
|
+
# `index.search(ref)` compared a substring of the rendered id, so a bare
|
|
26
|
+
# `001` answered with 11 documents and `#get` took `.first` -- a truncated
|
|
27
|
+
# reference silently resolved to whichever sorted first.
|
|
28
|
+
#
|
|
29
|
+
# @param ref [String] e.g. "XEP 0001", "XEP-0001", "0001"
|
|
30
|
+
#
|
|
31
|
+
# @return [Relaton::Xsf::HitCollection]
|
|
32
|
+
# @raise [Pubid::Errors::ParseError] if the reference is not an XEP id
|
|
33
|
+
#
|
|
6
34
|
def search(ref)
|
|
7
|
-
HitCollection.new(ref).search
|
|
35
|
+
HitCollection.new(parse_ref(ref)).search
|
|
8
36
|
end
|
|
9
37
|
|
|
10
38
|
def get(code, _year = nil, _opts = {})
|
|
@@ -19,6 +47,38 @@ module Relaton
|
|
|
19
47
|
Util.info "Found: `#{bib.docidentifier.first.content}`", key: code
|
|
20
48
|
bib
|
|
21
49
|
end
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# Parse a user reference into a `Pubid::Xsf::Identifier`, or nil.
|
|
53
|
+
#
|
|
54
|
+
# `Pubid::Xsf` accepts only the canonical `XEP 0001` spelling, so two
|
|
55
|
+
# forms are normalized first:
|
|
56
|
+
#
|
|
57
|
+
# - **`XEP-0001`**, the spelling xmpp.org itself uses everywhere. It did
|
|
58
|
+
# not resolve before either (the substring match compared against
|
|
59
|
+
# `XEP 0001`, which has a space), so this is new support rather than a
|
|
60
|
+
# preserved behaviour.
|
|
61
|
+
# - **A bare `0001`**, which the substring match did resolve, so it has to
|
|
62
|
+
# keep working. The publisher token is added, the W3C idiom.
|
|
63
|
+
#
|
|
64
|
+
# The token match is case-insensitive, so `xep 0001` resolves too.
|
|
65
|
+
#
|
|
66
|
+
# Anything else raises -- see `.search`. `Pubid::Errors::ParseError`
|
|
67
|
+
# includes `Pubid::Errors::Error`, which is the class relaton-cli rescues.
|
|
68
|
+
#
|
|
69
|
+
# @param ref [String]
|
|
70
|
+
# @return [Pubid::Xsf::Identifier]
|
|
71
|
+
# @raise [Pubid::Errors::ParseError]
|
|
72
|
+
#
|
|
73
|
+
def parse_ref(ref)
|
|
74
|
+
::Pubid::Xsf::Identifier.parse normalize_ref(ref)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
def normalize_ref(ref)
|
|
80
|
+
"XEP #{ref.to_s.strip.sub(/\AXEP[-\s]+/i, '')}"
|
|
81
|
+
end
|
|
22
82
|
end
|
|
23
83
|
end
|
|
24
84
|
end
|
|
@@ -3,8 +3,19 @@ require "relaton/core"
|
|
|
3
3
|
module Relaton
|
|
4
4
|
module Xsf
|
|
5
5
|
class DataFetcher < Relaton::Core::DataFetcher
|
|
6
|
+
# `Core::DataFetcher#log_error` raises unless the flavor overrides it, so
|
|
7
|
+
# `report_errors` is unusable without this. (The ECMA precedent.)
|
|
8
|
+
def log_error(msg)
|
|
9
|
+
Util.error msg
|
|
10
|
+
end
|
|
11
|
+
|
|
6
12
|
def index
|
|
7
|
-
|
|
13
|
+
# `pubid_class:` on the producer too: FileIO#save only calls `to_hash`
|
|
14
|
+
# when the value is an instance of it, so without it the crawl writes
|
|
15
|
+
# v1-shaped rows under a v2 name, silently.
|
|
16
|
+
@index ||= Relaton::Index.find_or_create(
|
|
17
|
+
:xsf, file: "#{INDEXFILE}.yaml", pubid_class: ::Pubid::Xsf::Identifier
|
|
18
|
+
)
|
|
8
19
|
end
|
|
9
20
|
|
|
10
21
|
def fetch(_source = nil)
|
|
@@ -18,6 +29,7 @@ module Relaton
|
|
|
18
29
|
Util.warn "Failed to parse #{link[:href]}: #{e.message}"
|
|
19
30
|
end
|
|
20
31
|
index.save
|
|
32
|
+
report_errors
|
|
21
33
|
end
|
|
22
34
|
|
|
23
35
|
def save_doc(bib)
|
|
@@ -30,14 +42,52 @@ module Relaton
|
|
|
30
42
|
id = docid&.content
|
|
31
43
|
return unless id
|
|
32
44
|
|
|
33
|
-
|
|
45
|
+
# Distinct docids can sanitize to one filename; take a path of our own
|
|
46
|
+
# rather than overwriting the other document (Core#unique_output_file).
|
|
47
|
+
file = unique_output_file id
|
|
34
48
|
if @files.include? file
|
|
49
|
+
# Same reserved path == same id: a genuine duplicate. Checked FIRST,
|
|
50
|
+
# because a disambiguated path stays != output_file forever.
|
|
35
51
|
Util.warn "File #{file} already exists"
|
|
36
|
-
|
|
37
|
-
|
|
52
|
+
elsif file != output_file(id)
|
|
53
|
+
Util.warn "File #{output_file id} already exists; writing #{file} instead"
|
|
38
54
|
end
|
|
55
|
+
@files << file
|
|
39
56
|
File.write file, serialize(bib), encoding: "UTF-8"
|
|
40
|
-
|
|
57
|
+
add_to_index id, file
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# Index a document under its pubid, skipping one pubid cannot parse.
|
|
62
|
+
#
|
|
63
|
+
# This guard is not optional here. One unparseable row does not fail that
|
|
64
|
+
# row: `Relaton::Index` declares the **whole file** corrupt, deletes it,
|
|
65
|
+
# and hands back an **empty** index. Measured — 519 good rows plus one
|
|
66
|
+
# unparseable id loads as 0 rows, and the only trace is two INFO lines
|
|
67
|
+
# ("Wrong structure of file …", "Considering … corrupt, removing it"). So
|
|
68
|
+
# indexing one bad row silently breaks every XSF lookup, not just its own.
|
|
69
|
+
#
|
|
70
|
+
# A rejection is recorded in `@errors`, which `report_errors` turns into a
|
|
71
|
+
# GitHub issue at the end of the crawl (the 3GPP/ECMA precedent). Nothing
|
|
72
|
+
# in the published corpus trips it today: pubid parses all 520 rows,
|
|
73
|
+
# including the two entries that are pages rather than XEPs — the XEP
|
|
74
|
+
# repository's `README` and its `xep-xxxx` template, which pubid accepts
|
|
75
|
+
# as the literal numbers `README` and `xxxx` while still rejecting
|
|
76
|
+
# anything else non-numeric (`XEP banana`, or a typo like `XEP 00O1`).
|
|
77
|
+
# So a recorded error now means something genuinely new appeared, which
|
|
78
|
+
# is exactly when an issue is worth filing.
|
|
79
|
+
#
|
|
80
|
+
# The data file is written either way, so a document that cannot be
|
|
81
|
+
# indexed is unindexed, never lost.
|
|
82
|
+
#
|
|
83
|
+
# @param docid [String]
|
|
84
|
+
# @param file [String]
|
|
85
|
+
#
|
|
86
|
+
def add_to_index(docid, file)
|
|
87
|
+
index.add_or_update ::Pubid::Xsf::Identifier.parse(docid), file
|
|
88
|
+
rescue StandardError => e
|
|
89
|
+
@errors[docid] =
|
|
90
|
+
"Unparseable primary id `#{docid}` was not indexed (#{e.message})"
|
|
41
91
|
end
|
|
42
92
|
|
|
43
93
|
def to_yaml(bib)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Xsf
|
|
3
|
+
# An XSF document identifier, backed by `Pubid::Xsf`.
|
|
4
|
+
#
|
|
5
|
+
# Parses its `content` into a `Pubid::Xsf::Identifier` kept in `@pubid`,
|
|
6
|
+
# while the lutaml `content` attribute stays a plain **string** for
|
|
7
|
+
# serialization. Parsing is **soft**: `content=` lazily requires pubid and
|
|
8
|
+
# rescues `LoadError`/`StandardError`, so a missing gem or non-XSF content
|
|
9
|
+
# leaves `@pubid` nil rather than raising during deserialization.
|
|
10
|
+
#
|
|
11
|
+
# **It deliberately implements none of `remove_part!` / `remove_date!` /
|
|
12
|
+
# `to_all_parts!`.** An XEP identifier is a publisher and a number and
|
|
13
|
+
# nothing else — no part, no edition, no date — so there is genuinely
|
|
14
|
+
# nothing for any of them to strip, and `Bib::Docidentifier` already
|
|
15
|
+
# defaults all three to no-ops for exactly that case. Empty overrides here
|
|
16
|
+
# would assert a flavor-specific rule that does not exist. Compare
|
|
17
|
+
# `Relaton::Ogc::Docidentifier`, which overrides `remove_date!` because OGC
|
|
18
|
+
# really does carry a revision.
|
|
19
|
+
#
|
|
20
|
+
# So this class exists for `#pubid`: it gives consumers the structured
|
|
21
|
+
# identifier off a docidentifier, the way every other pubid-backed flavor
|
|
22
|
+
# does, without changing what is serialized.
|
|
23
|
+
class Docidentifier < Bib::Docidentifier
|
|
24
|
+
attr_reader :pubid
|
|
25
|
+
|
|
26
|
+
def initialize(attrs = {}, options = {})
|
|
27
|
+
pubid = attrs.is_a?(Hash) ? attrs.delete(:pubid) : nil
|
|
28
|
+
attrs[:content] ||= pubid.to_s if pubid
|
|
29
|
+
super
|
|
30
|
+
@pubid = pubid if pubid
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def content=(value)
|
|
34
|
+
super
|
|
35
|
+
return unless value
|
|
36
|
+
|
|
37
|
+
@pubid = begin
|
|
38
|
+
require "pubid"
|
|
39
|
+
::Pubid::Xsf::Identifier.parse(value)
|
|
40
|
+
rescue LoadError, StandardError
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -3,11 +3,29 @@ module Relaton
|
|
|
3
3
|
class HitCollection < Relaton::Core::HitCollection
|
|
4
4
|
GHDATA_URL = "https://raw.githubusercontent.com/relaton/relaton-data-xsf/v2/".freeze
|
|
5
5
|
|
|
6
|
+
#
|
|
7
|
+
# Find the index rows for the identifier this collection was built with.
|
|
8
|
+
#
|
|
9
|
+
# `ref` is a `Pubid::Xsf::Identifier` -- `Bibliography.parse_ref` does that
|
|
10
|
+
# step, and raises rather than returning nil for an unrecognized
|
|
11
|
+
# reference. Passing the identifier rather than a string is what enables
|
|
12
|
+
# the binary search on `id.root.number`. The nil guard in `#rows` is
|
|
13
|
+
# defensive only: `Core::HitCollection` permits a nil `ref`, and an empty
|
|
14
|
+
# result beats a NoMethodError if some other caller constructs one.
|
|
15
|
+
#
|
|
16
|
+
# An XEP identifier is only a publisher and a number: no edition, no date,
|
|
17
|
+
# no part. So the reference states everything, and `Type#search`'s default
|
|
18
|
+
# subset match (`Pubid::SubsetMatch`) is a plain equality -- which is the
|
|
19
|
+
# point. Ids are unique, one row per XEP, so there is no selection order
|
|
20
|
+
# to apply either.
|
|
21
|
+
#
|
|
22
|
+
# @return [self]
|
|
23
|
+
#
|
|
6
24
|
def search
|
|
7
|
-
@array =
|
|
8
|
-
Hit.new url: "#{GHDATA_URL}#{row[:file]}"
|
|
9
|
-
end
|
|
25
|
+
@array = rows.map { |row| Hit.new url: "#{GHDATA_URL}#{row[:file]}" }
|
|
10
26
|
self
|
|
27
|
+
rescue Relaton::RequestError
|
|
28
|
+
raise
|
|
11
29
|
rescue StandardError => e
|
|
12
30
|
raise Relaton::RequestError, e.message
|
|
13
31
|
end
|
|
@@ -17,8 +35,18 @@ module Relaton
|
|
|
17
35
|
:xsf,
|
|
18
36
|
url: "#{GHDATA_URL}#{INDEXFILE}.zip",
|
|
19
37
|
file: "#{INDEXFILE}.yaml",
|
|
38
|
+
pubid_class: ::Pubid::Xsf::Identifier,
|
|
20
39
|
)
|
|
21
40
|
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def rows
|
|
45
|
+
return [] unless ref
|
|
46
|
+
|
|
47
|
+
index.search(ref)
|
|
48
|
+
.sort_by { |row| row[:id].to_s }
|
|
49
|
+
end
|
|
22
50
|
end
|
|
23
51
|
end
|
|
24
52
|
end
|
data/lib/relaton/xsf/item.rb
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
require_relative "docidentifier"
|
|
2
|
+
|
|
1
3
|
module Relaton
|
|
2
4
|
module Xsf
|
|
3
5
|
class Item < Bib::Item
|
|
4
6
|
model ItemData
|
|
7
|
+
|
|
8
|
+
# Narrow the inherited `docidentifier` to the flavor's own class, so a
|
|
9
|
+
# deserialized item exposes `#pubid` on each id. (The OGC/ECMA shape.)
|
|
10
|
+
attribute :docidentifier, Docidentifier, collection: true, initialize_empty: true
|
|
5
11
|
end
|
|
6
12
|
end
|
|
7
13
|
end
|
data/lib/relaton/xsf.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "mechanize"
|
|
4
|
+
# pubid loads with the flavor, for the ::Pubid::Xsf::Identifier that the
|
|
5
|
+
# index code names. Processor#remove_index_file names no pubid class: the
|
|
6
|
+
# delete never reads the index (see lib/relaton/index/CLAUDE.md).
|
|
7
|
+
require "pubid"
|
|
4
8
|
require "relaton/index"
|
|
5
9
|
require "relaton/bib"
|
|
6
10
|
require_relative "version"
|
|
@@ -15,7 +19,7 @@ require_relative "xsf/bibliography"
|
|
|
15
19
|
|
|
16
20
|
module Relaton
|
|
17
21
|
module Xsf
|
|
18
|
-
INDEXFILE = "index-
|
|
22
|
+
INDEXFILE = "index-v2".freeze
|
|
19
23
|
|
|
20
24
|
class Error < StandardError; end
|
|
21
25
|
|
data/lib/relaton.rb
CHANGED
|
@@ -12,6 +12,7 @@ module Relaton
|
|
|
12
12
|
autoload :Index, "relaton/index"
|
|
13
13
|
autoload :Bib, "relaton/bib"
|
|
14
14
|
autoload :ThreeGpp, "relaton/3gpp"
|
|
15
|
+
autoload :Adobe, "relaton/adobe"
|
|
15
16
|
autoload :Bipm, "relaton/bipm"
|
|
16
17
|
autoload :Calconnect, "relaton/calconnect"
|
|
17
18
|
autoload :Ccsds, "relaton/ccsds"
|
|
@@ -19,13 +20,17 @@ module Relaton
|
|
|
19
20
|
autoload :Cie, "relaton/cie"
|
|
20
21
|
autoload :Ecma, "relaton/ecma"
|
|
21
22
|
autoload :Etsi, "relaton/etsi"
|
|
23
|
+
autoload :Easc, "relaton/easc"
|
|
24
|
+
autoload :Gost, "relaton/gost"
|
|
22
25
|
autoload :Iana, "relaton/iana"
|
|
26
|
+
autoload :Iala, "relaton/iala"
|
|
23
27
|
autoload :Ieee, "relaton/ieee"
|
|
24
28
|
autoload :Ietf, "relaton/ietf"
|
|
25
29
|
autoload :Iho, "relaton/iho"
|
|
26
30
|
autoload :Isbn, "relaton/isbn"
|
|
27
31
|
autoload :Iso, "relaton/iso"
|
|
28
32
|
autoload :Itu, "relaton/itu"
|
|
33
|
+
autoload :Jcgm, "relaton/jcgm"
|
|
29
34
|
autoload :Nist, "relaton/nist"
|
|
30
35
|
autoload :Oasis, "relaton/oasis"
|
|
31
36
|
autoload :Oiml, "relaton/oiml"
|
|
@@ -40,6 +45,43 @@ module Relaton
|
|
|
40
45
|
autoload :Ogc, "relaton/ogc"
|
|
41
46
|
autoload :Plateau, "relaton/plateau"
|
|
42
47
|
autoload :Doi, "relaton/doi"
|
|
48
|
+
autoload :Sdo, "relaton/sdo"
|
|
49
|
+
|
|
50
|
+
# Global PubID prefix register (relaton-db#103). Maps an SDO document-ID
|
|
51
|
+
# prefix to the flavor module(s) that own it. Conflicting prefixes (e.g.
|
|
52
|
+
# "ISO/IEC", claimed by both ISO and IEC) return several flavors.
|
|
53
|
+
#
|
|
54
|
+
# Relaton.prefix_flavor("NIST") # => [Relaton::Nist]
|
|
55
|
+
# Relaton.prefix_flavor("ISO/IEC") # => [Relaton::Iec, Relaton::Iso]
|
|
56
|
+
# Relaton.prefix_flavor("BOGUS") # => []
|
|
57
|
+
#
|
|
58
|
+
# NOTE: returning the flavor module forces that flavor's lazy load. To resolve
|
|
59
|
+
# a prefix without loading flavor code, use
|
|
60
|
+
# `Relaton::Db::Registry.instance.processors_by_prefix(prefix)`.
|
|
61
|
+
#
|
|
62
|
+
# @param prefix [String]
|
|
63
|
+
# @return [Array<Module>]
|
|
64
|
+
def self.prefix_flavor(prefix)
|
|
65
|
+
Db::Registry.instance.flavors_by_prefix(prefix)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# SDO organization & logo store (metanorma#346, relaton-db#132). Looks up a
|
|
69
|
+
# standards body by abbreviation and returns its metadata — names/translations
|
|
70
|
+
# and logo variants — from the `relaton-data-sdo` data repo. This is a
|
|
71
|
+
# non-flavor store: no processor, no Db::Registry entry.
|
|
72
|
+
#
|
|
73
|
+
# org = Relaton.organization("ISO")
|
|
74
|
+
# org.name # default name
|
|
75
|
+
# org.name("fr") # translated name
|
|
76
|
+
# org.name(language: "fr") # translated name (keyword form)
|
|
77
|
+
# org.logo_query(format: "eps", style: "default") # matching logo variants
|
|
78
|
+
# org.logo(format: "eps", style: "default") # one logo
|
|
79
|
+
#
|
|
80
|
+
# @param abbreviation [String]
|
|
81
|
+
# @return [Relaton::Sdo::Organization, nil]
|
|
82
|
+
def self.organization(abbreviation)
|
|
83
|
+
Sdo::Store.instance.organization(abbreviation)
|
|
84
|
+
end
|
|
43
85
|
end
|
|
44
86
|
|
|
45
87
|
require "relaton/db"
|