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,32 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Adobe
|
|
3
|
+
# Adobe bibliographic item extension. Adds Adobe-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/adobe.rb.
|
|
7
|
+
class Ext < Bib::Ext
|
|
8
|
+
attribute :doctype, Doctype
|
|
9
|
+
attribute :urn, :string
|
|
10
|
+
attribute :webpage, :string
|
|
11
|
+
attribute :tech_note_number, :string
|
|
12
|
+
attribute :source_repo_path, :string
|
|
13
|
+
attribute :publication_slug, :string
|
|
14
|
+
|
|
15
|
+
xml do
|
|
16
|
+
map_element "urn", to: :urn
|
|
17
|
+
map_element "webpage", to: :webpage
|
|
18
|
+
map_element "tech_note_number", to: :tech_note_number
|
|
19
|
+
map_element "source_repo_path", to: :source_repo_path
|
|
20
|
+
map_element "publication_slug", to: :publication_slug
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
key_value do
|
|
24
|
+
map_element "urn", to: :urn
|
|
25
|
+
map_element "webpage", to: :webpage
|
|
26
|
+
map_element "tech_note_number", to: :tech_note_number
|
|
27
|
+
map_element "source_repo_path", to: :source_repo_path
|
|
28
|
+
map_element "publication_slug", to: :publication_slug
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Adobe
|
|
3
|
+
# Adobe bibliographic item. Re-declares +ext+ to use the typed Ext
|
|
4
|
+
# subclass so Adobe-specific fields round-trip natively. Sub-files
|
|
5
|
+
# (ItemData, Ext, Docidentifier) are loaded lazily via the autoload
|
|
6
|
+
# entries declared in lib/relaton/adobe.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 Adobe
|
|
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,45 @@
|
|
|
1
|
+
require "relaton/core/processor"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Adobe
|
|
5
|
+
# Relaton processor for the Adobe flavor. Registered by
|
|
6
|
+
# Relaton::Registry when the unified gem loads (see
|
|
7
|
+
# lib/relaton/registry.rb). Supports `relaton fetch adobe ...` once
|
|
8
|
+
# the relaton-data-adobe dataset is installed.
|
|
9
|
+
class Processor < Core::Processor
|
|
10
|
+
attr_reader :idtype
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@short = :relaton_adobe
|
|
14
|
+
@prefix = "Adobe"
|
|
15
|
+
@defaultprefix = %r{^(?:Adobe|ATN)}
|
|
16
|
+
@idtype = "Adobe"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def get(code, date, opts)
|
|
20
|
+
require_relative "../adobe"
|
|
21
|
+
Bibliography.get(code, date, opts)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def from_xml(xml)
|
|
25
|
+
require_relative "../adobe"
|
|
26
|
+
Item.from_xml xml
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def from_yaml(yaml)
|
|
30
|
+
require_relative "../adobe"
|
|
31
|
+
Item.from_yaml(yaml)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def grammar_hash
|
|
35
|
+
require_relative "../adobe"
|
|
36
|
+
@grammar_hash ||= ::Relaton::Adobe.grammar_hash
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def remove_index_file
|
|
40
|
+
require_relative "../adobe"
|
|
41
|
+
Relaton::Index.find_or_create(:adobe, url: true, file: "#{INDEXFILE}.yaml").remove_file
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "relaton/bib"
|
|
4
|
+
require "relaton/index"
|
|
5
|
+
require "pubid"
|
|
6
|
+
require "relaton/version"
|
|
7
|
+
|
|
8
|
+
# Relaton::Adobe is the Adobe (font tech notes, character collections,
|
|
9
|
+
# PostScript Language, etc.) flavor of the unified relaton gem. Adds
|
|
10
|
+
# typed Ext fields (urn, webpage, tech_note_number, source_repo_path,
|
|
11
|
+
# publication_slug) so they round-trip natively through YAML and XML
|
|
12
|
+
# without per-repo merge hacks.
|
|
13
|
+
module Relaton
|
|
14
|
+
module Adobe
|
|
15
|
+
INDEXFILE = "index-v2".freeze
|
|
16
|
+
|
|
17
|
+
class Error < StandardError; end
|
|
18
|
+
|
|
19
|
+
autoload :Doctype, "relaton/adobe/doctype"
|
|
20
|
+
autoload :Ext, "relaton/adobe/ext"
|
|
21
|
+
autoload :ItemData, "relaton/adobe/item_data"
|
|
22
|
+
autoload :ItemBase, "relaton/adobe/item_base"
|
|
23
|
+
autoload :Item, "relaton/adobe/item"
|
|
24
|
+
autoload :Bibitem, "relaton/adobe/bibitem"
|
|
25
|
+
autoload :Bibdata, "relaton/adobe/bibdata"
|
|
26
|
+
autoload :Docidentifier, "relaton/adobe/docidentifier"
|
|
27
|
+
autoload :Util, "relaton/adobe/util"
|
|
28
|
+
autoload :Bibliography, "relaton/adobe/bibliography"
|
|
29
|
+
autoload :Processor, "relaton/adobe/processor"
|
|
30
|
+
|
|
31
|
+
# Returns hash of XML grammar
|
|
32
|
+
# @return [String]
|
|
33
|
+
def self.grammar_hash
|
|
34
|
+
Digest::MD5.hexdigest Relaton::VERSION
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -6,7 +6,7 @@ module Relaton
|
|
|
6
6
|
attribute :state, :string
|
|
7
7
|
attribute :country, :string
|
|
8
8
|
attribute :postcode, :string
|
|
9
|
-
attribute :formatted_address, :string
|
|
9
|
+
attribute :formatted_address, :string
|
|
10
10
|
|
|
11
11
|
xml do
|
|
12
12
|
root "address"
|
|
@@ -15,7 +15,7 @@ module Relaton
|
|
|
15
15
|
map_element "state", to: :state
|
|
16
16
|
map_element "country", to: :country
|
|
17
17
|
map_element "postcode", to: :postcode
|
|
18
|
-
map_element "formattedAddress", to: :formatted_address
|
|
18
|
+
map_element "formattedAddress", to: :formatted_address, raw: :content
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -18,17 +18,32 @@ module Relaton
|
|
|
18
18
|
map "primary", to: :primary
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
# `Bib::ItemData#to_all_parts` and `#to_most_recent_reference` broadcast
|
|
22
|
+
# these three to EVERY docidentifier unconditionally, so raising here made
|
|
23
|
+
# both calls unusable for any flavor that had not subclassed this class —
|
|
24
|
+
# 13 of them had not, and both died on every item they produced. The raise
|
|
25
|
+
# was also `NotImplementedError`, which descends from `ScriptError`, so a
|
|
26
|
+
# caller's `rescue => e` did not even catch it.
|
|
27
|
+
#
|
|
28
|
+
# The default is therefore a **no-op**. An identifier that models neither
|
|
29
|
+
# a part nor a date has nothing to strip, and returning it unchanged is
|
|
30
|
+
# the correct answer for both calls.
|
|
31
|
+
#
|
|
32
|
+
# A flavor whose identifier does carry one overrides these — see
|
|
33
|
+
# `Relaton::Ogc::Docidentifier` or `Relaton::Iala::Docidentifier` for the
|
|
34
|
+
# pubid-backed shape (parse `content` into a pubid, mutate, re-render
|
|
35
|
+
# through a `store_content` alias so the write does not re-parse).
|
|
36
|
+
#
|
|
37
|
+
# The trade-off, recorded so it stays a choice rather than an oversight: a
|
|
38
|
+
# flavor that DOES carry a date but has not overridden `remove_date!` now
|
|
39
|
+
# returns a dated reference silently, where before it crashed loudly.
|
|
40
|
+
# That is a missing override in the flavor, not a defect here.
|
|
24
41
|
|
|
25
|
-
def
|
|
26
|
-
raise NotImplementedError, "`to_all_parts!` method not implemented in #{self.class}"
|
|
27
|
-
end
|
|
42
|
+
def remove_part!; end
|
|
28
43
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
end
|
|
44
|
+
def to_all_parts!; end
|
|
45
|
+
|
|
46
|
+
def remove_date!; end
|
|
32
47
|
end
|
|
33
48
|
end
|
|
34
49
|
end
|
|
@@ -32,17 +32,18 @@ module Relaton
|
|
|
32
32
|
map_element "year", to: :year
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
# The same broadcast reaches `ext.structuredidentifier`
|
|
36
|
+
# (`Bib::ItemData#ext_to_all_parts!` / `#ext_remove_date`), so these
|
|
37
|
+
# default to no-ops for the same reason as `Bib::Docidentifier`'s: a
|
|
38
|
+
# structured identifier with no part and no date has nothing to strip.
|
|
39
|
+
# Flavors that model one override them — see
|
|
40
|
+
# `Relaton::Iso::StructuredIdentifier` and `Relaton::Gb::StructuredIdentifier`.
|
|
38
41
|
|
|
39
|
-
def
|
|
40
|
-
raise NotImplementedError, "`to_all_parts!` method not implemented in #{self.class}"
|
|
41
|
-
end
|
|
42
|
+
def remove_part!; end
|
|
42
43
|
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
end
|
|
44
|
+
def to_all_parts!; end
|
|
45
|
+
|
|
46
|
+
def remove_date!; end
|
|
46
47
|
end
|
|
47
48
|
end
|
|
48
49
|
end
|
|
@@ -3,8 +3,13 @@ require "nokogiri"
|
|
|
3
3
|
module Relaton
|
|
4
4
|
module Bib
|
|
5
5
|
# Strips inline markup not in the basicdoc PureTextElement set
|
|
6
|
-
# (plus <p>, <eref>, <xref>, <fn>) from raw marked-up content
|
|
7
|
-
# Disallowed elements are unwrapped: tags removed, inner text kept.
|
|
6
|
+
# (plus <p>, <eref>, <xref>, <fn>, <link>) from raw marked-up content
|
|
7
|
+
# strings. Disallowed elements are unwrapped: tags removed, inner text kept.
|
|
8
|
+
#
|
|
9
|
+
# <link> (basicdoc's inline hyperlink) is admitted because it is a valid
|
|
10
|
+
# TextElement child of a biblionote and carries a target URL that must
|
|
11
|
+
# survive the from_xml/to_xml round-trip — dropping it silently loses
|
|
12
|
+
# every URL in amended note.display references (relaton-bib#122).
|
|
8
13
|
#
|
|
9
14
|
# <fn> is admitted beyond strict PureTextElement because bibliographic
|
|
10
15
|
# titles in real Metanorma input routinely carry footnotes (e.g. ISO
|
|
@@ -22,7 +27,7 @@ module Relaton
|
|
|
22
27
|
module Sanitizer
|
|
23
28
|
ALLOWED = %w[
|
|
24
29
|
em strong sub sup tt underline strike smallcap br stem
|
|
25
|
-
p eref xref fn
|
|
30
|
+
p eref xref fn link
|
|
26
31
|
].freeze
|
|
27
32
|
|
|
28
33
|
# Elements whose children are non-basicdoc inline notation
|
|
@@ -36,15 +41,206 @@ module Relaton
|
|
|
36
41
|
|
|
37
42
|
TAG_RX = %r{<[a-zA-Z/!?]}
|
|
38
43
|
|
|
44
|
+
# Captures a namespace prefix, on a tag or on an attribute: the
|
|
45
|
+
# "jats" of <jats:p> and </jats:italic>, and the "xlink" of
|
|
46
|
+
# xlink:href.
|
|
47
|
+
NS_PREFIX_RX = %r{(?:</?|\s)([A-Za-z_][\w.-]*):(?=[A-Za-z_])}
|
|
48
|
+
|
|
49
|
+
# Namespace that declares a prefix which the content leaves
|
|
50
|
+
# undeclared. The sanitiser removes it again before it serialises.
|
|
51
|
+
NS_PLACEHOLDER = "urn:x-relaton-undeclared:%s".freeze
|
|
52
|
+
|
|
53
|
+
# Element that carries the placeholder declarations. Its children
|
|
54
|
+
# are the sanitised content, so the element itself never reaches
|
|
55
|
+
# the output.
|
|
56
|
+
NS_WRAPPER = "relaton-sanitizer-root".freeze
|
|
57
|
+
|
|
58
|
+
# Extension that lengthens the wrapper name past a collision, and
|
|
59
|
+
# the pattern that measures how far the content already extends it.
|
|
60
|
+
NS_WRAPPER_SUFFIX = "-x".freeze
|
|
61
|
+
NS_WRAPPER_RX = /#{NS_WRAPPER}(?:#{NS_WRAPPER_SUFFIX})*/
|
|
62
|
+
|
|
63
|
+
# Reserved prefixes. XML declares both, so the content must not.
|
|
64
|
+
NS_RESERVED = %w[xml xmlns].freeze
|
|
65
|
+
|
|
66
|
+
# Serialise without the FORMAT option, so the sanitiser keeps the
|
|
67
|
+
# shape of element-only content instead of adding newlines and
|
|
68
|
+
# indent.
|
|
69
|
+
SAVE_OPTS = Nokogiri::XML::Node::SaveOptions::AS_XML
|
|
70
|
+
|
|
39
71
|
def self.sanitize(content)
|
|
40
72
|
return content unless sanitizable?(content)
|
|
41
73
|
|
|
74
|
+
node = parse(content)
|
|
75
|
+
return content if node.nil?
|
|
76
|
+
|
|
77
|
+
sanitize_children(node)
|
|
78
|
+
node.children.map do |c|
|
|
79
|
+
c.to_xml(encoding: "UTF-8", save_with: SAVE_OPTS)
|
|
80
|
+
end.join
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Parse the content into a node whose children are the content.
|
|
85
|
+
#
|
|
86
|
+
# @param [String] content The raw marked-up content.
|
|
87
|
+
#
|
|
88
|
+
# @return [Nokogiri::XML::Node, nil] The node, or nil when the
|
|
89
|
+
# content does not parse.
|
|
90
|
+
#
|
|
91
|
+
def self.parse(content)
|
|
42
92
|
fragment = Nokogiri::XML::DocumentFragment.parse(content)
|
|
43
|
-
return
|
|
93
|
+
return fragment if fragment.errors.empty?
|
|
94
|
+
|
|
95
|
+
parse_with_prefixes(content)
|
|
96
|
+
end
|
|
97
|
+
private_class_method :parse
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Parse content that uses undeclared namespace prefixes.
|
|
101
|
+
#
|
|
102
|
+
# An undeclared prefix is always a parse error, so without this the
|
|
103
|
+
# sanitiser gives up on exactly the third-party markup that needs
|
|
104
|
+
# sanitising most. Declare every prefix that the content uses on a
|
|
105
|
+
# wrapper element, parse, then remove the placeholder namespaces
|
|
106
|
+
# from the elements and from the attributes. See metanorma-pdfa#99.
|
|
107
|
+
#
|
|
108
|
+
# An undeclared prefix inside an OPAQUE <stem> goes as well. The
|
|
109
|
+
# sanitiser cannot keep it: an undeclared prefix in the output is
|
|
110
|
+
# the exact failure that this method removes. Only a namespace that
|
|
111
|
+
# the content declares itself survives verbatim.
|
|
112
|
+
#
|
|
113
|
+
# @param [String] content The raw marked-up content.
|
|
114
|
+
#
|
|
115
|
+
# @return [Nokogiri::XML::Element, nil] The wrapper element, or nil
|
|
116
|
+
# when the content uses no prefix or does not parse.
|
|
117
|
+
#
|
|
118
|
+
def self.parse_with_prefixes(content)
|
|
119
|
+
decl = placeholder_declarations(content) or return
|
|
120
|
+
name = wrapper_name(content)
|
|
121
|
+
doc = Nokogiri::XML "<#{name} #{decl}>#{content}</#{name}>"
|
|
122
|
+
return unless doc.errors.empty?
|
|
123
|
+
|
|
124
|
+
drop_placeholder_namespaces doc.root
|
|
125
|
+
end
|
|
126
|
+
private_class_method :parse_with_prefixes
|
|
127
|
+
|
|
128
|
+
#
|
|
129
|
+
# Declare every namespace prefix that the content uses.
|
|
130
|
+
#
|
|
131
|
+
# @param [String] content The raw marked-up content.
|
|
132
|
+
#
|
|
133
|
+
# @return [String, nil] The declarations, or nil when the content
|
|
134
|
+
# uses no prefix.
|
|
135
|
+
#
|
|
136
|
+
def self.placeholder_declarations(content)
|
|
137
|
+
prefixes = content.scan(NS_PREFIX_RX).flatten.uniq - NS_RESERVED
|
|
138
|
+
return if prefixes.empty?
|
|
139
|
+
|
|
140
|
+
prefixes.map do |pfx|
|
|
141
|
+
%(xmlns:#{pfx}="#{format NS_PLACEHOLDER, pfx}")
|
|
142
|
+
end.join(" ")
|
|
143
|
+
end
|
|
144
|
+
private_class_method :placeholder_declarations
|
|
145
|
+
|
|
146
|
+
#
|
|
147
|
+
# Name a wrapper element that the content does not close itself.
|
|
148
|
+
#
|
|
149
|
+
# Content that holds the literal end tag of the wrapper would close
|
|
150
|
+
# it early. The document then has more than one root, the parse
|
|
151
|
+
# fails, and the sanitiser gives up on content that it can handle.
|
|
152
|
+
#
|
|
153
|
+
# Extend past the longest run of the suffix that the content already
|
|
154
|
+
# holds, in ONE scan. Growing the name and re-testing with include?
|
|
155
|
+
# is quadratic: each extension re-scans the whole string, and
|
|
156
|
+
# content shaped like "…-root-x-x-x" forces one pass per two
|
|
157
|
+
# characters (measured at 229 ms for 20k characters). The sanitiser
|
|
158
|
+
# runs on every marked-up assignment, on third-party content.
|
|
159
|
+
#
|
|
160
|
+
# @param [String] content The raw marked-up content.
|
|
161
|
+
#
|
|
162
|
+
# @return [String] A name that the content does not contain.
|
|
163
|
+
#
|
|
164
|
+
def self.wrapper_name(content)
|
|
165
|
+
longest = content.scan(NS_WRAPPER_RX).map(&:size).max
|
|
166
|
+
return NS_WRAPPER unless longest
|
|
167
|
+
|
|
168
|
+
extra = ((longest - NS_WRAPPER.size) / NS_WRAPPER_SUFFIX.size) + 1
|
|
169
|
+
NS_WRAPPER + (NS_WRAPPER_SUFFIX * extra)
|
|
170
|
+
end
|
|
171
|
+
private_class_method :wrapper_name
|
|
172
|
+
|
|
173
|
+
#
|
|
174
|
+
# Remove the placeholder namespaces, and only those.
|
|
175
|
+
#
|
|
176
|
+
# Nokogiri's remove_namespaces! would also strip a namespace that
|
|
177
|
+
# the content declares itself, such as the MathML xmlns inside an
|
|
178
|
+
# OPAQUE <stem>, which must survive verbatim. Match the wrapper's
|
|
179
|
+
# own declarations, so a namespace of the content never matches,
|
|
180
|
+
# whatever its URI.
|
|
181
|
+
#
|
|
182
|
+
# The declarations stay on the wrapper element. Only its children
|
|
183
|
+
# reach the output, so the declarations never leak. Do not
|
|
184
|
+
# serialise the root itself.
|
|
185
|
+
#
|
|
186
|
+
# @param [Nokogiri::XML::Element] root The wrapper element.
|
|
187
|
+
#
|
|
188
|
+
# @return [Nokogiri::XML::Element] The same element.
|
|
189
|
+
#
|
|
190
|
+
def self.drop_placeholder_namespaces(root)
|
|
191
|
+
placeholders = root.namespace_definitions
|
|
192
|
+
root.traverse do |node|
|
|
193
|
+
node.namespace = nil if placeholders.include?(node.namespace)
|
|
194
|
+
next unless node.element?
|
|
195
|
+
|
|
196
|
+
drop_attribute_namespaces node, placeholders
|
|
197
|
+
end
|
|
198
|
+
root
|
|
199
|
+
end
|
|
200
|
+
private_class_method :drop_placeholder_namespaces
|
|
201
|
+
|
|
202
|
+
#
|
|
203
|
+
# Un-prefix the placeholder attributes of one element.
|
|
204
|
+
#
|
|
205
|
+
# Un-prefixing renames the attribute, so it can collide: an element
|
|
206
|
+
# carrying both target and xlink:target would keep two attributes
|
|
207
|
+
# called target, and Nokogiri rejects the result with "Attribute
|
|
208
|
+
# target redefined" -- the unparseable output this whole path
|
|
209
|
+
# exists to prevent. Drop the prefixed one instead.
|
|
210
|
+
#
|
|
211
|
+
# @param [Nokogiri::XML::Element] node The element.
|
|
212
|
+
# @param [Array<Nokogiri::XML::Namespace>] placeholders The
|
|
213
|
+
# wrapper's own declarations.
|
|
214
|
+
#
|
|
215
|
+
# @return [void]
|
|
216
|
+
#
|
|
217
|
+
def self.drop_attribute_namespaces(node, placeholders)
|
|
218
|
+
node.attribute_nodes.each do |attr|
|
|
219
|
+
next unless placeholders.include?(attr.namespace)
|
|
220
|
+
|
|
221
|
+
if plain_attribute?(node, attr.name) then attr.unlink
|
|
222
|
+
else attr.namespace = nil
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
private_class_method :drop_attribute_namespaces
|
|
44
227
|
|
|
45
|
-
|
|
46
|
-
|
|
228
|
+
#
|
|
229
|
+
# Does the element already carry this attribute without a prefix?
|
|
230
|
+
#
|
|
231
|
+
# Nokogiri's Node#attribute matches on the name alone, so it finds
|
|
232
|
+
# the prefixed attribute itself and every un-prefixing would look
|
|
233
|
+
# like a collision. Match on the namespace as well.
|
|
234
|
+
#
|
|
235
|
+
# @param [Nokogiri::XML::Element] node The element.
|
|
236
|
+
# @param [String] name The un-prefixed attribute name.
|
|
237
|
+
#
|
|
238
|
+
# @return [Boolean] Whether the element carries it.
|
|
239
|
+
#
|
|
240
|
+
def self.plain_attribute?(node, name)
|
|
241
|
+
node.attribute_nodes.any? { |a| a.namespace.nil? && a.name == name }
|
|
47
242
|
end
|
|
243
|
+
private_class_method :plain_attribute?
|
|
48
244
|
|
|
49
245
|
def self.sanitizable?(content)
|
|
50
246
|
content.is_a?(::String) && !content.empty? && content.match?(TAG_RX)
|