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
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Gost
|
|
3
|
+
# GOST bibliographic item. Re-declares +ext+ to use the typed Ext
|
|
4
|
+
# subclass so GOST-specific fields round-trip natively. Sub-files
|
|
5
|
+
# (ItemData, Ext, Docidentifier) are loaded lazily via the autoload
|
|
6
|
+
# entries declared in lib/relaton/gost.rb.
|
|
7
|
+
class Item < Bib::Item
|
|
8
|
+
model ItemData
|
|
9
|
+
|
|
10
|
+
attribute :ext, Ext
|
|
11
|
+
attribute :docidentifier, Docidentifier, collection: true,
|
|
12
|
+
initialize_empty: true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Gost
|
|
3
|
+
class ItemBase < Lutaml::Model::Serializable
|
|
4
|
+
include Bib::NamespaceHelper
|
|
5
|
+
|
|
6
|
+
attr_accessor :type
|
|
7
|
+
|
|
8
|
+
model ItemData
|
|
9
|
+
|
|
10
|
+
instance_exec(&Bib::ItemShared::ATTRIBUTES)
|
|
11
|
+
|
|
12
|
+
xml do
|
|
13
|
+
map_attribute "type", to: :type
|
|
14
|
+
instance_exec(&Bib::ItemShared::XML_BODY)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require "relaton/core/processor"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Gost
|
|
5
|
+
# Relaton processor for the GOST flavor. Registered by
|
|
6
|
+
# Relaton::Db::Registry when the unified gem loads (see
|
|
7
|
+
# lib/relaton/db/registry.rb). Supports `relaton fetch gost ...`
|
|
8
|
+
# once the relaton-data-gost dataset is installed.
|
|
9
|
+
class Processor < Core::Processor
|
|
10
|
+
attr_reader :idtype
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@short = :relaton_gost
|
|
14
|
+
@prefix = "GOST"
|
|
15
|
+
# Both Latin "GOST" and Cyrillic "ГОСТ" route here. The trailing
|
|
16
|
+
# \b keeps the prefix from swallowing longer tokens ("GOSTA …").
|
|
17
|
+
@defaultprefix = %r{^(?:GOST|ГОСТ)\b}
|
|
18
|
+
@idtype = "GOST"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get(code, date, opts)
|
|
22
|
+
require_relative "../gost"
|
|
23
|
+
Bibliography.get(code, date, opts)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def from_xml(xml)
|
|
27
|
+
require_relative "../gost"
|
|
28
|
+
Item.from_xml xml
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def from_yaml(yaml)
|
|
32
|
+
require_relative "../gost"
|
|
33
|
+
Item.from_yaml(yaml)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def grammar_hash
|
|
37
|
+
require_relative "../gost"
|
|
38
|
+
@grammar_hash ||= ::Relaton::Gost.grammar_hash
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def remove_index_file
|
|
42
|
+
require_relative "../gost"
|
|
43
|
+
Relaton::Index.find_or_create(
|
|
44
|
+
:gost, url: true, file: "#{INDEXFILE}.yaml"
|
|
45
|
+
).remove_file
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/relaton/gost.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "relaton/bib"
|
|
4
|
+
require "relaton/index"
|
|
5
|
+
require "pubid"
|
|
6
|
+
require "relaton/version"
|
|
7
|
+
|
|
8
|
+
# Relaton::Gost is the GOST (Russian federal standards — Гостстандарт)
|
|
9
|
+
# flavor of the unified relaton gem. Adds typed Ext fields (urn,
|
|
10
|
+
# webpage) so they round-trip natively through YAML and XML without
|
|
11
|
+
# per-repo merge hacks.
|
|
12
|
+
module Relaton
|
|
13
|
+
module Gost
|
|
14
|
+
INDEXFILE = "index-v2".freeze
|
|
15
|
+
|
|
16
|
+
class Error < StandardError; end
|
|
17
|
+
|
|
18
|
+
autoload :Doctype, "relaton/gost/doctype"
|
|
19
|
+
autoload :Ext, "relaton/gost/ext"
|
|
20
|
+
autoload :ItemData, "relaton/gost/item_data"
|
|
21
|
+
autoload :ItemBase, "relaton/gost/item_base"
|
|
22
|
+
autoload :Item, "relaton/gost/item"
|
|
23
|
+
autoload :Bibitem, "relaton/gost/bibitem"
|
|
24
|
+
autoload :Bibdata, "relaton/gost/bibdata"
|
|
25
|
+
autoload :Docidentifier, "relaton/gost/docidentifier"
|
|
26
|
+
autoload :Bibliography, "relaton/gost/bibliography"
|
|
27
|
+
autoload :Util, "relaton/gost/util"
|
|
28
|
+
autoload :Processor, "relaton/gost/processor"
|
|
29
|
+
|
|
30
|
+
# Returns hash of XML grammar
|
|
31
|
+
# @return [String]
|
|
32
|
+
def self.grammar_hash
|
|
33
|
+
Digest::MD5.hexdigest Relaton::VERSION
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Iala
|
|
5
|
+
module Bibliography
|
|
6
|
+
ENDPOINT = "https://raw.githubusercontent.com/relaton/relaton-data-iala/main/".freeze
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
# Search for an IALA publication by its identifier.
|
|
10
|
+
#
|
|
11
|
+
# @param text [String] the IALA reference to look up (e.g. "IALA S1070")
|
|
12
|
+
# @param _year [String, nil] optional edition/year filter
|
|
13
|
+
# @param _opts [Hash] options (unused)
|
|
14
|
+
# @return [Relaton::Iala::Item, nil]
|
|
15
|
+
def search(text, _year = nil, _opts = {})
|
|
16
|
+
Util.info "Fetching from Relaton repository ...", key: text
|
|
17
|
+
row = best_match text
|
|
18
|
+
unless row
|
|
19
|
+
Util.info "Not found.", key: text
|
|
20
|
+
return
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
uri = URI("#{ENDPOINT}#{row[:file]}")
|
|
24
|
+
resp = Net::HTTP.get_response uri
|
|
25
|
+
unless resp.code == "200"
|
|
26
|
+
raise Relaton::RequestError, "Could not access #{uri}: HTTP #{resp.code}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
item = Relaton::Iala::Item.from_yaml resp.body
|
|
30
|
+
Util.info "Found: `#{item.docidentifier.first&.content}`", key: text
|
|
31
|
+
item.tap { |i| i.fetched = Date.today.to_s }
|
|
32
|
+
rescue SocketError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
|
33
|
+
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
|
34
|
+
Net::ProtocolError, Net::ReadTimeout, OpenSSL::SSL::SSLError,
|
|
35
|
+
Errno::ETIMEDOUT => e
|
|
36
|
+
raise Relaton::RequestError, "Could not access #{uri}: #{e.message}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def get(ref, year = nil, opts = {})
|
|
40
|
+
search(ref, year, opts)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# Find the index row for a reference, newest edition first.
|
|
47
|
+
#
|
|
48
|
+
# Passing the pubid to `Index::Type#search` is what enables the binary
|
|
49
|
+
# search on `id.root.number` — with a block alone, or with the plain
|
|
50
|
+
# string this used to pass, the whole index is scanned. Selection is
|
|
51
|
+
# `Type#search`'s default with no block — pubid's asymmetric subset
|
|
52
|
+
# match (`Pubid::SubsetMatch`): the reference on the left, the row on
|
|
53
|
+
# the right, and a component the reference omits matches any value.
|
|
54
|
+
# `edition` and `language` are IALA's only
|
|
55
|
+
# optional components, so a bare `IALA M0001` still finds the
|
|
56
|
+
# `Ed 9.0 (E)` row. The document type is deliberately NOT a wildcard —
|
|
57
|
+
# it is the identifier's class, and `===` requires the same class. 17 of
|
|
58
|
+
# the 309 index numbers are shared by two types, so `R1001` and `C1001`
|
|
59
|
+
# must never match each other. An `Annex` row carries its base
|
|
60
|
+
# identifier, which `===` compares with its own subset match.
|
|
61
|
+
#
|
|
62
|
+
# @param text [String]
|
|
63
|
+
# @return [Hash, nil]
|
|
64
|
+
#
|
|
65
|
+
# The substring-scan fallback this used to take when parsing failed is
|
|
66
|
+
# gone with the rescue. It was the same conflation the convention
|
|
67
|
+
# rejects: an unparseable string matched a SUBSTRING of the rendered
|
|
68
|
+
# ids, so an ambiguous reference silently resolved to whichever row
|
|
69
|
+
# sorted first, instead of telling the caller the reference is not an
|
|
70
|
+
# identifier. ecma, w3c and xsf never had one.
|
|
71
|
+
def best_match(text)
|
|
72
|
+
pubid = parse_ref text
|
|
73
|
+
rows = index.search(pubid)
|
|
74
|
+
rows.max_by { |r| [edition_key(r[:id].edition), language_key(r[:id]), r[:file]] }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Order key for an IALA edition.
|
|
79
|
+
#
|
|
80
|
+
# Editions are dotted version strings, so they must be compared segment
|
|
81
|
+
# by segment as integers rather than as text: `"10.0"` is newer than
|
|
82
|
+
# `"9.0"` but sorts before it as a string. No published edition has a
|
|
83
|
+
# segment above 9 today, so this is a latent bug rather than a live one
|
|
84
|
+
# — the same one already fixed for ETSI. An absent edition sorts below
|
|
85
|
+
# every present one.
|
|
86
|
+
#
|
|
87
|
+
# `2` and `2.0` are distinct editions in the index and compare as
|
|
88
|
+
# `[2] < [2, 0]`; `2.02` and `2.2` reduce to the same segments. Both
|
|
89
|
+
# pairs are broken by the edition text and then the file path, so a
|
|
90
|
+
# repeated lookup returns the same document (the index sort is not
|
|
91
|
+
# stable).
|
|
92
|
+
#
|
|
93
|
+
# @param edition [String, nil]
|
|
94
|
+
# @return [Array]
|
|
95
|
+
#
|
|
96
|
+
def edition_key(edition)
|
|
97
|
+
[edition.to_s.split(".").map(&:to_i), edition.to_s]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Prefer the language-neutral record over its translations: it is the
|
|
101
|
+
# base document, and the translations are keyed off it.
|
|
102
|
+
#
|
|
103
|
+
# @param row_id [Pubid::Iala::Identifier]
|
|
104
|
+
# @return [Integer]
|
|
105
|
+
#
|
|
106
|
+
def language_key(row_id)
|
|
107
|
+
row_id.language.nil? ? 1 : 0
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Parse a user reference into a `Pubid::Iala::Identifier`, or nil.
|
|
112
|
+
#
|
|
113
|
+
# `Pubid::Iala` takes the `IALA ` publisher prefix as optional and
|
|
114
|
+
# zero-pads the number to its type's canonical width, so `IALA M1`,
|
|
115
|
+
# `M0001` and `R1016:ed2.0(F)` all parse without normalization here.
|
|
116
|
+
#
|
|
117
|
+
# @param text [String]
|
|
118
|
+
# @return [Pubid::Iala::Identifier, nil]
|
|
119
|
+
#
|
|
120
|
+
# An unrecognized reference **raises**; like ISO, ETSI and 3GPP we let it
|
|
121
|
+
# propagate. relaton-cli rescues `Pubid::Errors::Error` and renders
|
|
122
|
+
# `"..." is not a recognized standards identifier`
|
|
123
|
+
# (`gems/relaton-cli/lib/relaton/cli/command.rb:324`), and `Db#fetch`
|
|
124
|
+
# logs it through the `StandardError` arm at `lib/relaton/db.rb:122`.
|
|
125
|
+
# Rescuing here would collapse "this identifier is malformed" into "no
|
|
126
|
+
# such document", leaving a caller unable to tell them apart.
|
|
127
|
+
def parse_ref(text)
|
|
128
|
+
::Pubid::Iala::Identifier.parse text.to_s.strip
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# The index is pubid-backed: `pubid_class:` is what makes
|
|
132
|
+
# Relaton::Index deserialize the rows into identifiers, sort them by
|
|
133
|
+
# `id.root.number`, and let `Type#search` bsearch. Without it the rows
|
|
134
|
+
# stay raw hashes and every lookup scans all 701 of them.
|
|
135
|
+
def index
|
|
136
|
+
Relaton::Index.find_or_create(
|
|
137
|
+
:iala,
|
|
138
|
+
url: "#{ENDPOINT}#{INDEXFILE}.zip",
|
|
139
|
+
file: "#{INDEXFILE}.yaml",
|
|
140
|
+
pubid_class: ::Pubid::Iala::Identifier,
|
|
141
|
+
)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Iala
|
|
3
|
+
# Structured IALA document identifier. The docid string is the canonical
|
|
4
|
+
# form (e.g. "IALA S1070 Ed 2.0"). Defined as a subclass so future
|
|
5
|
+
# Pubid::Iala integration can hook in via #pubid without changing the
|
|
6
|
+
# public interface.
|
|
7
|
+
class Docidentifier < Bib::Docidentifier
|
|
8
|
+
attr_reader :pubid
|
|
9
|
+
|
|
10
|
+
# Capture the inherited (LocalizedMarkedUpString) content setter before
|
|
11
|
+
# overriding #content=, so #refresh_content! can write the re-rendered
|
|
12
|
+
# string back WITHOUT re-parsing (a re-parse would rebuild @pubid from
|
|
13
|
+
# the string, which may not even parse back — e.g. an all-parts
|
|
14
|
+
# wrapper's own "(all parts)" rendering — and discard the mutation).
|
|
15
|
+
alias_method :store_content, :content=
|
|
16
|
+
|
|
17
|
+
def initialize(attrs = {}, options = {})
|
|
18
|
+
pubid = attrs.is_a?(Hash) ? attrs.delete(:pubid) : nil
|
|
19
|
+
attrs[:content] ||= pubid.to_s if pubid
|
|
20
|
+
super
|
|
21
|
+
@pubid = pubid if pubid
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def content=(value)
|
|
25
|
+
super
|
|
26
|
+
return unless value
|
|
27
|
+
|
|
28
|
+
@pubid = begin
|
|
29
|
+
# `pubid/iala` needs pubid core (Pubid::PrefixesSupport) loaded first,
|
|
30
|
+
# so require both. Rescue LoadError so a missing pubid gem degrades to
|
|
31
|
+
# a plain string, and StandardError so non-IALA/unparseable content
|
|
32
|
+
# just leaves @pubid nil rather than raising.
|
|
33
|
+
require "pubid"
|
|
34
|
+
require "pubid/iala"
|
|
35
|
+
::Pubid::Iala.parse(value)
|
|
36
|
+
rescue LoadError, StandardError
|
|
37
|
+
nil
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# IALA's Pubid::Iala::Identifier models only publisher/number/edition/
|
|
42
|
+
# language. It has no distinct `date` component and folds any subpart
|
|
43
|
+
# inline into `number` (e.g. "0103-1"), so:
|
|
44
|
+
# * #remove_date! maps onto `edition` — IALA's version discriminator —
|
|
45
|
+
# yielding the version-agnostic ("most recent") reference.
|
|
46
|
+
# * #remove_part! clears the (currently-unused) part/subpart attributes;
|
|
47
|
+
# it is a no-op for the rendered content today, but is implemented so
|
|
48
|
+
# it never raises and starts working automatically should pubid-iala
|
|
49
|
+
# ever model `part` separately.
|
|
50
|
+
# All three no-op safely when @pubid is nil (parse failed or the pubid gem
|
|
51
|
+
# is unavailable), so Bib::ItemData#to_all_parts / #to_most_recent_reference
|
|
52
|
+
# never raise on IALA items.
|
|
53
|
+
|
|
54
|
+
def remove_part!
|
|
55
|
+
clear_attr!(:part)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def remove_date!
|
|
59
|
+
clear_attr!(:edition)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_all_parts!
|
|
63
|
+
return if !@pubid || @pubid.all_parts?
|
|
64
|
+
|
|
65
|
+
# `#exclude` (no args) rebuilds a full independent copy — `remove_part!`
|
|
66
|
+
# / `remove_date!` mutate `@pubid` in place, so a bare reference here
|
|
67
|
+
# would lose the original edition to that mutation too.
|
|
68
|
+
original = @pubid.exclude
|
|
69
|
+
remove_part!
|
|
70
|
+
remove_date!
|
|
71
|
+
@pubid = original.to_all_parts
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def clear_attr!(attr)
|
|
77
|
+
return unless @pubid && @pubid.respond_to?("#{attr}=")
|
|
78
|
+
|
|
79
|
+
@pubid.public_send("#{attr}=", nil)
|
|
80
|
+
@pubid.subpart = nil if attr == :part && @pubid.respond_to?(:subpart=)
|
|
81
|
+
refresh_content!
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def refresh_content!
|
|
85
|
+
store_content(@pubid.to_s) if @pubid
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Iala
|
|
3
|
+
# IALA publication document types. The value is carried in the
|
|
4
|
+
# inherited `content` attribute (e.g. `standard`, `recommendation`).
|
|
5
|
+
# The list mirrors the seven categories the IALA site exposes.
|
|
6
|
+
class Doctype < Bib::Doctype
|
|
7
|
+
TYPES = %w[
|
|
8
|
+
standard
|
|
9
|
+
recommendation
|
|
10
|
+
guideline
|
|
11
|
+
manual
|
|
12
|
+
model-course
|
|
13
|
+
report
|
|
14
|
+
resolution
|
|
15
|
+
].freeze
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Iala
|
|
3
|
+
# IALA bibliographic item extension. Adds IALA-specific structured
|
|
4
|
+
# metadata on top of the shared Relaton::Bib::Ext so the fields
|
|
5
|
+
# round-trip through both XML and YAML without per-repo merge hacks.
|
|
6
|
+
# Doctype is referenced lazily via autoload from lib/relaton/iala.rb.
|
|
7
|
+
class Ext < Bib::Ext
|
|
8
|
+
attribute :doctype, Doctype
|
|
9
|
+
attribute :urn, :string
|
|
10
|
+
attribute :webpage, :string
|
|
11
|
+
attribute :committee, :string
|
|
12
|
+
attribute :normative, :string
|
|
13
|
+
attribute :supersedes, :string, collection: true, initialize_empty: true
|
|
14
|
+
|
|
15
|
+
xml do
|
|
16
|
+
map_element "urn", to: :urn
|
|
17
|
+
map_element "webpage", to: :webpage
|
|
18
|
+
map_element "committee", to: :committee
|
|
19
|
+
map_element "normative", to: :normative
|
|
20
|
+
map_element "supersedes", to: :supersedes
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
key_value do
|
|
24
|
+
map_element "urn", to: :urn
|
|
25
|
+
map_element "webpage", to: :webpage
|
|
26
|
+
map_element "committee", to: :committee
|
|
27
|
+
map_element "normative", to: :normative
|
|
28
|
+
map_element "supersedes", to: :supersedes
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Iala
|
|
3
|
+
# IALA bibliographic item. Re-declares +ext+ to use the typed Ext
|
|
4
|
+
# subclass so IALA-specific fields round-trip natively. Sub-files
|
|
5
|
+
# (ItemData, Ext, Docidentifier, Relation) are loaded lazily via the
|
|
6
|
+
# autoload entries declared in lib/relaton/iala.rb.
|
|
7
|
+
class Item < Bib::Item
|
|
8
|
+
model ItemData
|
|
9
|
+
|
|
10
|
+
attribute :ext, Ext
|
|
11
|
+
attribute :docidentifier, Docidentifier, collection: true,
|
|
12
|
+
initialize_empty: true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Wire up the back-reference: an Item's relation collection contains
|
|
18
|
+
# Relation nodes whose bibitem is an ItemBase. Referencing
|
|
19
|
+
# Relaton::Iala::Relation triggers its autoload.
|
|
20
|
+
Relaton::Iala::Item.attribute :relation, Relaton::Iala::Relation,
|
|
21
|
+
collection: true, initialize_empty: true
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Iala
|
|
3
|
+
class ItemBase < Lutaml::Model::Serializable
|
|
4
|
+
include Bib::NamespaceHelper
|
|
5
|
+
|
|
6
|
+
attr_accessor :type
|
|
7
|
+
|
|
8
|
+
model ItemData
|
|
9
|
+
|
|
10
|
+
instance_exec(&Bib::ItemShared::ATTRIBUTES)
|
|
11
|
+
|
|
12
|
+
xml do
|
|
13
|
+
map_attribute "type", to: :type
|
|
14
|
+
instance_exec(&Bib::ItemShared::XML_BODY)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require "relaton/core/processor"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Iala
|
|
5
|
+
class Processor < Core::Processor
|
|
6
|
+
attr_reader :idtype
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@short = :relaton_iala
|
|
10
|
+
@prefix = "IALA"
|
|
11
|
+
@defaultprefix = %r{^IALA\s}
|
|
12
|
+
@idtype = "IALA"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get(code, date, opts)
|
|
16
|
+
require_relative "../iala"
|
|
17
|
+
Bibliography.get(code, date, opts)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def from_xml(xml)
|
|
21
|
+
require_relative "../iala"
|
|
22
|
+
Item.from_xml xml
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def from_yaml(yaml)
|
|
26
|
+
require_relative "../iala"
|
|
27
|
+
Item.from_yaml(yaml)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def grammar_hash
|
|
31
|
+
require_relative "../iala"
|
|
32
|
+
@grammar_hash ||= ::Relaton::Iala.grammar_hash
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def remove_index_file
|
|
36
|
+
require_relative "../iala"
|
|
37
|
+
Relaton::Index.find_or_create(
|
|
38
|
+
:iala, url: true, file: "#{INDEXFILE}.yaml"
|
|
39
|
+
).remove_file
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/relaton/iala.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "pubid"
|
|
2
|
+
require "relaton/bib"
|
|
3
|
+
require "relaton/index"
|
|
4
|
+
require "relaton/version"
|
|
5
|
+
|
|
6
|
+
# Relaton::Iala is the IALA (International Organization for Marine Aids
|
|
7
|
+
# to Navigation) flavor of the unified relaton gem. Adds typed Ext fields
|
|
8
|
+
# (urn, webpage, committee, normative, supersedes) so they round-trip
|
|
9
|
+
# natively through YAML and XML without per-repo merge hacks.
|
|
10
|
+
module Relaton
|
|
11
|
+
module Iala
|
|
12
|
+
INDEXFILE = "index-v2".freeze
|
|
13
|
+
|
|
14
|
+
class Error < StandardError; end
|
|
15
|
+
|
|
16
|
+
autoload :Util, "relaton/iala/util"
|
|
17
|
+
autoload :Doctype, "relaton/iala/doctype"
|
|
18
|
+
autoload :Ext, "relaton/iala/ext"
|
|
19
|
+
autoload :ItemData, "relaton/iala/item_data"
|
|
20
|
+
autoload :ItemBase, "relaton/iala/item_base"
|
|
21
|
+
autoload :Item, "relaton/iala/item"
|
|
22
|
+
autoload :Relation, "relaton/iala/relation"
|
|
23
|
+
autoload :Bibitem, "relaton/iala/bibitem"
|
|
24
|
+
autoload :Bibdata, "relaton/iala/bibdata"
|
|
25
|
+
autoload :Docidentifier, "relaton/iala/docidentifier"
|
|
26
|
+
autoload :Bibliography, "relaton/iala/bibliography"
|
|
27
|
+
autoload :Processor, "relaton/iala/processor"
|
|
28
|
+
|
|
29
|
+
# Returns hash of XML grammar
|
|
30
|
+
# @return [String]
|
|
31
|
+
def self.grammar_hash
|
|
32
|
+
Digest::MD5.hexdigest Relaton::VERSION
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|