relaton-bib 0.3.3 → 0.3.8
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 +5 -5
- data/Gemfile.lock +5 -5
- data/docs/hash.adoc +298 -34
- data/lib/relaton_bib.rb +33 -1
- data/lib/relaton_bib/bib_item_locality.rb +12 -5
- data/lib/relaton_bib/biblio_note.rb +15 -5
- data/lib/relaton_bib/biblio_version.rb +12 -2
- data/lib/relaton_bib/bibliographic_date.rb +18 -24
- data/lib/relaton_bib/bibliographic_item.rb +49 -11
- data/lib/relaton_bib/classification.rb +7 -0
- data/lib/relaton_bib/contribution_info.rb +26 -4
- data/lib/relaton_bib/contributor.rb +42 -4
- data/lib/relaton_bib/copyright_association.rb +12 -5
- data/lib/relaton_bib/document_identifier.rb +7 -0
- data/lib/relaton_bib/document_relation.rb +9 -0
- data/lib/relaton_bib/document_status.rb +8 -0
- data/lib/relaton_bib/formatted_string.rb +12 -2
- data/lib/relaton_bib/hash_converter.rb +164 -101
- data/lib/relaton_bib/hit.rb +32 -0
- data/lib/relaton_bib/hit_collection.rb +34 -0
- data/lib/relaton_bib/localized_string.rb +16 -6
- data/lib/relaton_bib/medium.rb +9 -0
- data/lib/relaton_bib/organization.rb +36 -26
- data/lib/relaton_bib/person.rb +28 -1
- data/lib/relaton_bib/series.rb +16 -0
- data/lib/relaton_bib/typed_title_string.rb +14 -0
- data/lib/relaton_bib/typed_uri.rb +6 -0
- data/lib/relaton_bib/validity.rb +14 -4
- data/lib/relaton_bib/version.rb +1 -1
- data/lib/relaton_bib/xml_parser.rb +20 -6
- data/relaton-bib.gemspec +2 -2
- metadata +10 -8
@@ -0,0 +1,32 @@
|
|
1
|
+
module RelatonBib
|
2
|
+
class Hit
|
3
|
+
# @return [Array<Hash>]
|
4
|
+
attr_reader :hit
|
5
|
+
|
6
|
+
# @param hit [Hash]
|
7
|
+
# @param hit_collection [RelatonIso::HitCollection, RelatonNist:HitCollection]
|
8
|
+
def initialize(hit, hit_collection = nil)
|
9
|
+
@hit = hit
|
10
|
+
@hit_collection = hit_collection
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [String]
|
14
|
+
def to_s
|
15
|
+
inspect
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String]
|
19
|
+
def inspect
|
20
|
+
"<#{self.class}:#{format('%#.14x', object_id << 1)} "\
|
21
|
+
"@text=\"#{@hit_collection&.text}\" "\
|
22
|
+
"@fetched=\"#{!@fetch.nil?}\" "\
|
23
|
+
"@fullIdentifier=\"#{@fetch&.shortref(nil)}\" "\
|
24
|
+
"@title=\"#{@hit[:code]}\">"
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [String]
|
28
|
+
def to_xml(**opts)
|
29
|
+
fetch.to_xml **opts
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RelatonBib
|
2
|
+
class HitCollection < Array
|
3
|
+
# @return [TrueClass, FalseClass]
|
4
|
+
attr_reader :fetched
|
5
|
+
|
6
|
+
# @return [String]
|
7
|
+
attr_reader :text
|
8
|
+
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :year
|
11
|
+
|
12
|
+
# @return [RelatonIso::HitCollection]
|
13
|
+
def fetch
|
14
|
+
workers = WorkersPool.new 4
|
15
|
+
workers.worker(&:fetch)
|
16
|
+
each do |hit|
|
17
|
+
workers << hit
|
18
|
+
end
|
19
|
+
workers.end
|
20
|
+
workers.result
|
21
|
+
@fetched = true
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
inspect
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String]
|
30
|
+
def inspect
|
31
|
+
"<#{self.class}:#{format('%#.14x', object_id << 1)} @fetched=#{@fetched}>"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module RelatonBib
|
4
4
|
# Localized string.
|
5
5
|
class LocalizedString
|
6
|
+
include RelatonBib
|
7
|
+
|
6
8
|
# @return [Array<String>] language Iso639 code
|
7
9
|
attr_reader :language
|
8
10
|
|
@@ -16,10 +18,8 @@ module RelatonBib
|
|
16
18
|
# @param language [String] language code Iso639
|
17
19
|
# @param script [String] script code Iso15924
|
18
20
|
def initialize(content, language = nil, script = nil)
|
19
|
-
@language = []
|
20
|
-
@
|
21
|
-
@script = []
|
22
|
-
@script << script if script
|
21
|
+
@language = language.is_a?(String) ? [language] : language
|
22
|
+
@script = script.is_a?(String) ? [script] : script
|
23
23
|
@content = content
|
24
24
|
end
|
25
25
|
|
@@ -37,9 +37,19 @@ module RelatonBib
|
|
37
37
|
def to_xml(builder)
|
38
38
|
return unless content
|
39
39
|
|
40
|
-
builder.parent["language"] = language.join(",") if language
|
41
|
-
builder.parent["script"] = script.join(",") if script
|
40
|
+
builder.parent["language"] = language.join(",") if language&.any?
|
41
|
+
builder.parent["script"] = script.join(",") if script&.any?
|
42
42
|
builder.text content
|
43
43
|
end
|
44
|
+
|
45
|
+
# @return [Hash]
|
46
|
+
def to_hash
|
47
|
+
return content unless language || script
|
48
|
+
|
49
|
+
hash = { "content" => content }
|
50
|
+
hash["language"] = single_element_array(language) if language&.any?
|
51
|
+
hash["script"] = single_element_array(script) if script&.any?
|
52
|
+
hash
|
53
|
+
end
|
44
54
|
end
|
45
55
|
end
|
data/lib/relaton_bib/medium.rb
CHANGED
@@ -34,6 +34,11 @@ module RelatonBib
|
|
34
34
|
def to_xml(builder)
|
35
35
|
builder.identifier(value, type: type)
|
36
36
|
end
|
37
|
+
|
38
|
+
# @return [Hash]
|
39
|
+
def to_hash
|
40
|
+
{ "type" => type, "id" => value }
|
41
|
+
end
|
37
42
|
end
|
38
43
|
|
39
44
|
# Organization.
|
@@ -41,51 +46,35 @@ module RelatonBib
|
|
41
46
|
# @return [Array<RelatonBib::LocalizedString>]
|
42
47
|
attr_reader :name
|
43
48
|
|
44
|
-
# @return [RelatonBib::LocalizedString]
|
49
|
+
# @return [RelatonBib::LocalizedString, NilClass]
|
45
50
|
attr_reader :abbreviation
|
46
51
|
|
47
|
-
# @return [RelatonBib::LocalizedString]
|
52
|
+
# @return [RelatonBib::LocalizedString, NilClass]
|
48
53
|
attr_reader :subdivision
|
49
54
|
|
50
55
|
# @return [Array<RelatonBib::OrgIdentifier>]
|
51
56
|
attr_reader :identifier
|
52
57
|
|
53
|
-
def hash2locstr(name)
|
54
|
-
name.is_a?(Hash) ?
|
55
|
-
LocalizedString.new(name[:content], name[:language], name[:script]) :
|
56
|
-
LocalizedString.new(name)
|
57
|
-
end
|
58
|
-
|
59
58
|
# @param name [String, Hash, Array<String, Hash>]
|
60
|
-
# @param abbreviation [RelatoBib::
|
61
|
-
# @param subdivision [RelatoBib::
|
59
|
+
# @param abbreviation [RelatoBib::LocalizedString, String]
|
60
|
+
# @param subdivision [RelatoBib::LocalizedString, String]
|
62
61
|
# @param url [String]
|
63
62
|
# @param identifier [Array<RelatonBib::OrgIdentifier>]
|
64
|
-
# @param contact [Array<RelatonBib::Address, RelatonBib::
|
63
|
+
# @param contact [Array<RelatonBib::Address, RelatonBib::Contact>]
|
65
64
|
def initialize(**args)
|
66
65
|
raise ArgumentError, "missing keyword: name" unless args[:name]
|
67
66
|
|
68
67
|
super(url: args[:url], contact: args.fetch(:contact, []))
|
69
68
|
|
70
69
|
@name = if args[:name].is_a?(Array)
|
71
|
-
args[:name].map { |n|
|
70
|
+
args[:name].map { |n| localized_string(n) }
|
72
71
|
else
|
73
|
-
[
|
72
|
+
[localized_string(args[:name])]
|
74
73
|
end
|
75
74
|
|
76
|
-
@abbreviation =
|
77
|
-
|
78
|
-
|
79
|
-
args[:abbreviation]
|
80
|
-
end
|
81
|
-
|
82
|
-
@subdivision = if args[:subdivision].is_a?(String)
|
83
|
-
LocalizedString.new(args[:subdivision])
|
84
|
-
else
|
85
|
-
args[:subdivision]
|
86
|
-
end
|
87
|
-
|
88
|
-
@identifier = args.fetch(:identifier, [])
|
75
|
+
@abbreviation = localized_string args[:abbreviation]
|
76
|
+
@subdivision = localized_string args[:subdivision]
|
77
|
+
@identifier = args.fetch(:identifier, [])
|
89
78
|
end
|
90
79
|
|
91
80
|
# @param builder [Nokogiri::XML::Builder]
|
@@ -101,5 +90,26 @@ module RelatonBib
|
|
101
90
|
super
|
102
91
|
end
|
103
92
|
end
|
93
|
+
|
94
|
+
# @return [Hash]
|
95
|
+
def to_hash
|
96
|
+
hash = { "name" => single_element_array(name) }
|
97
|
+
hash["abbreviation"] = abbreviation.to_hash if abbreviation
|
98
|
+
hash["identifier"] = single_element_array(identifier) if identifier&.any?
|
99
|
+
hash["subdivision"] = subdivision.to_hash if subdivision
|
100
|
+
{ "organization" => hash.merge(super) }
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
# @param arg [String, Hash, RelatoBib::LocalizedString]
|
106
|
+
# @return [RelatoBib::LocalizedString]
|
107
|
+
def localized_string(arg)
|
108
|
+
if arg.is_a?(String) then LocalizedString.new(arg)
|
109
|
+
elsif arg.is_a?(Hash)
|
110
|
+
LocalizedString.new(arg[:content], arg[:language], arg[:script])
|
111
|
+
elsif arg.is_a? LocalizedString then arg
|
112
|
+
end
|
113
|
+
end
|
104
114
|
end
|
105
115
|
end
|
data/lib/relaton_bib/person.rb
CHANGED
@@ -5,6 +5,8 @@ require "relaton_bib/contributor"
|
|
5
5
|
module RelatonBib
|
6
6
|
# Person's full name
|
7
7
|
class FullName
|
8
|
+
include RelatonBib
|
9
|
+
|
8
10
|
# @return [Array<RelatonBib::LocalizedString>]
|
9
11
|
attr_accessor :forename
|
10
12
|
|
@@ -56,6 +58,18 @@ module RelatonBib
|
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
61
|
+
|
62
|
+
# @return [Hash]
|
63
|
+
def to_hash
|
64
|
+
hash = {}
|
65
|
+
hash["forename"] = single_element_array(forename) if forename&.any?
|
66
|
+
hash["initial"] = single_element_array(initial) if initial&.any?
|
67
|
+
hash["surname"] = surname.to_hash if surname
|
68
|
+
hash["addition"] = single_element_array(addition) if addition&.any?
|
69
|
+
hash["prefix"] = single_element_array(prefix) if prefix&.any?
|
70
|
+
hash["completename"] = completename.to_hash if completename
|
71
|
+
hash
|
72
|
+
end
|
59
73
|
end
|
60
74
|
|
61
75
|
# Person identifier type.
|
@@ -94,6 +108,11 @@ module RelatonBib
|
|
94
108
|
def to_xml(builder)
|
95
109
|
builder.identifier value, type: type
|
96
110
|
end
|
111
|
+
|
112
|
+
# @return [Hash]
|
113
|
+
def to_hash
|
114
|
+
{ "type" => type, "id" => value }
|
115
|
+
end
|
97
116
|
end
|
98
117
|
|
99
118
|
# Person class.
|
@@ -109,7 +128,7 @@ module RelatonBib
|
|
109
128
|
|
110
129
|
# @param name [RelatonBib::FullName]
|
111
130
|
# @param affiliation [Array<RelatonBib::Affiliation>]
|
112
|
-
# @param contact [Array<RelatonBib::Address, RelatonBib::
|
131
|
+
# @param contact [Array<RelatonBib::Address, RelatonBib::Contact>]
|
113
132
|
# @param identifier [Array<RelatonBib::PersonIdentifier>]
|
114
133
|
def initialize(name:, affiliation: [], contact: [], identifier: [])
|
115
134
|
super(contact: contact)
|
@@ -127,5 +146,13 @@ module RelatonBib
|
|
127
146
|
contact.each { |contact| contact.to_xml builder }
|
128
147
|
end
|
129
148
|
end
|
149
|
+
|
150
|
+
# @return [Hash]
|
151
|
+
def to_hash
|
152
|
+
hash = { "name" => name.to_hash }
|
153
|
+
hash["affiliation"] = single_element_array(affiliation) if affiliation&.any?
|
154
|
+
hash["identifier"] = single_element_array(identifier) if identifier&.any?
|
155
|
+
{ "person" => hash.merge(super) }
|
156
|
+
end
|
130
157
|
end
|
131
158
|
end
|
data/lib/relaton_bib/series.rb
CHANGED
@@ -93,5 +93,21 @@ module RelatonBib
|
|
93
93
|
end
|
94
94
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
95
95
|
# rubocop:enable Metrics/PerceivedComplexity
|
96
|
+
|
97
|
+
# @return [Hash]
|
98
|
+
def to_hash
|
99
|
+
hash = {}
|
100
|
+
hash["type"] = type if type
|
101
|
+
hash["formattedref"] = formattedref.to_hash if formattedref
|
102
|
+
hash["title"] = title.to_hash if title
|
103
|
+
hash["place"] = place if place
|
104
|
+
hash["organization"] = organization if organization
|
105
|
+
hash["abbreviation"] = abbreviation.to_hash if abbreviation
|
106
|
+
hash["from"] = from if from
|
107
|
+
hash["to"] = to if to
|
108
|
+
hash["number"] = number if number
|
109
|
+
hash["partnumber"] = partnumber if partnumber
|
110
|
+
hash
|
111
|
+
end
|
96
112
|
end
|
97
113
|
end
|
@@ -42,5 +42,19 @@ module RelatonBib
|
|
42
42
|
builder.parent[:type] = type if type
|
43
43
|
title.to_xml builder
|
44
44
|
end
|
45
|
+
|
46
|
+
# @return [Hash]
|
47
|
+
def to_hash
|
48
|
+
th = title.to_hash
|
49
|
+
return th unless type
|
50
|
+
|
51
|
+
hash = { "type" => type }
|
52
|
+
if th.is_a? String
|
53
|
+
hash["content"] = th
|
54
|
+
else
|
55
|
+
hash.merge! th
|
56
|
+
end
|
57
|
+
hash
|
58
|
+
end
|
45
59
|
end
|
46
60
|
end
|
@@ -15,8 +15,14 @@ module RelatonBib
|
|
15
15
|
@content = Addressable::URI.parse content if content
|
16
16
|
end
|
17
17
|
|
18
|
+
# @param builder [Nokogiri::XML::Builder]
|
18
19
|
def to_xml(builder)
|
19
20
|
builder.uri(content.to_s, type: type)
|
20
21
|
end
|
22
|
+
|
23
|
+
# @return [Hash]
|
24
|
+
def to_hash
|
25
|
+
{ "type" => type, "content" => content.to_s }
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
data/lib/relaton_bib/validity.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module RelatonBib
|
2
2
|
class Validity
|
3
|
+
FORMAT = "%Y-%m-%d %H:%M"
|
4
|
+
|
3
5
|
# @return [Time, NilClass]
|
4
6
|
attr_reader :begins
|
5
7
|
|
@@ -20,12 +22,20 @@ module RelatonBib
|
|
20
22
|
|
21
23
|
# @param [Nokogiri::XML::Builder]
|
22
24
|
def to_xml(builder)
|
23
|
-
format = "%Y-%m-%d %H:%M"
|
24
25
|
builder.validity do
|
25
|
-
builder.validityBegins begins.strftime(
|
26
|
-
builder.validityEnds ends.strftime(
|
27
|
-
builder.validityRevision revision.strftime(
|
26
|
+
builder.validityBegins begins.strftime(FORMAT) if begins
|
27
|
+
builder.validityEnds ends.strftime(FORMAT) if ends
|
28
|
+
builder.validityRevision revision.strftime(FORMAT) if revision
|
28
29
|
end
|
29
30
|
end
|
31
|
+
|
32
|
+
# @return [Hash]
|
33
|
+
def to_hash
|
34
|
+
hash = {}
|
35
|
+
hash["begins"] = begins.strftime(FORMAT) if begins
|
36
|
+
hash["ends"] = ends.strftime(FORMAT) if ends
|
37
|
+
hash["revision"] = revision.strftime(FORMAT) if revision
|
38
|
+
hash
|
39
|
+
end
|
30
40
|
end
|
31
41
|
end
|
data/lib/relaton_bib/version.rb
CHANGED
@@ -5,7 +5,7 @@ module RelatonBib
|
|
5
5
|
class << self
|
6
6
|
def from_xml(xml)
|
7
7
|
doc = Nokogiri::XML(xml)
|
8
|
-
bibitem = doc.at "/bibitem"
|
8
|
+
bibitem = doc.at "/bibitem|/bibdata"
|
9
9
|
BibliographicItem.new(item_data(bibitem))
|
10
10
|
end
|
11
11
|
|
@@ -29,8 +29,8 @@ module RelatonBib
|
|
29
29
|
edition: bibitem.at("./edition")&.text,
|
30
30
|
version: fetch_version(bibitem),
|
31
31
|
biblionote: fetch_note(bibitem),
|
32
|
-
language: bibitem
|
33
|
-
script: bibitem
|
32
|
+
language: fetch_language(bibitem),
|
33
|
+
script: fetch_script(bibitem),
|
34
34
|
abstract: fetch_abstract(bibitem),
|
35
35
|
docstatus: fetch_status(bibitem),
|
36
36
|
copyright: fetch_copyright(bibitem),
|
@@ -67,6 +67,14 @@ module RelatonBib
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
def fetch_language(item)
|
71
|
+
item.xpath("./language").reduce([]) { |a, l| l.text.empty? ? a : a << l.text }
|
72
|
+
end
|
73
|
+
|
74
|
+
def fetch_script(item)
|
75
|
+
item.xpath("./script").reduce([]) { |a, s| s.text.empty? ? a : a << s.text }
|
76
|
+
end
|
77
|
+
|
70
78
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
71
79
|
|
72
80
|
def fetch_series(item)
|
@@ -145,8 +153,9 @@ module RelatonBib
|
|
145
153
|
status = item.at("./status")
|
146
154
|
return unless status
|
147
155
|
|
156
|
+
stage = status.at "stage"
|
148
157
|
DocumentStatus.new(
|
149
|
-
stage:
|
158
|
+
stage: stage ? stage.text : status.text,
|
150
159
|
substage: status.at("substage")&.text,
|
151
160
|
iteration: status.at("iteration")&.text,
|
152
161
|
)
|
@@ -154,8 +163,9 @@ module RelatonBib
|
|
154
163
|
|
155
164
|
def fetch_dates(item)
|
156
165
|
item.xpath("./date").map do |d|
|
166
|
+
type = d[:type].to_s.empty? ? "published" : d[:type]
|
157
167
|
RelatonBib::BibliographicDate.new(
|
158
|
-
type:
|
168
|
+
type: type, on: d.at("on")&.text, from: d.at("from")&.text,
|
159
169
|
to: d.at("to")&.text
|
160
170
|
)
|
161
171
|
end
|
@@ -178,7 +188,11 @@ module RelatonBib
|
|
178
188
|
def get_person(person)
|
179
189
|
affilations = person.xpath("./affiliation").map do |a|
|
180
190
|
org = a.at "./organization"
|
181
|
-
|
191
|
+
desc = a.xpath("./description").map do |e|
|
192
|
+
FormattedString.new(content: e.text, language: e[:language],
|
193
|
+
script: e[:script], format: e[:format])
|
194
|
+
end
|
195
|
+
Affilation.new organization: get_org(org), description: desc
|
182
196
|
end
|
183
197
|
|
184
198
|
contact = person.xpath("./address | ./phone | ./email | ./uri").map do |c|
|