relaton-bib 1.20.7 → 2.0.0.pre.alpha.1
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/.rubocop.yml +1 -1
- data/README.adoc +183 -154
- data/bin/console +1 -1
- data/grammars/basicdoc.rng +1516 -645
- data/grammars/biblio-standoc.rng +100 -20
- data/grammars/biblio.rng +959 -356
- data/grammars/versions.json +10 -10
- data/lib/relaton/bib/hash_parser_v1.rb +711 -0
- data/lib/relaton/bib/item_data.rb +168 -0
- data/lib/relaton/bib/model/address.rb +22 -0
- data/lib/relaton/bib/model/affiliation.rb +16 -0
- data/lib/relaton/bib/model/bibdata.rb +24 -0
- data/lib/relaton/bib/model/bibitem.rb +23 -0
- data/lib/relaton/bib/model/contact.rb +18 -0
- data/lib/relaton/bib/model/contribution_info.rb +16 -0
- data/lib/relaton/bib/model/contributor.rb +71 -0
- data/lib/relaton/bib/model/copyright.rb +27 -0
- data/lib/relaton/bib/model/date.rb +29 -0
- data/lib/relaton/bib/model/depiction.rb +14 -0
- data/lib/relaton/bib/model/docidentifier.rb +33 -0
- data/lib/relaton/bib/model/doctype.rb +14 -0
- data/lib/relaton/bib/model/edition.rb +14 -0
- data/lib/relaton/bib/model/editorial_group.rb +14 -0
- data/lib/relaton/bib/model/ext.rb +29 -0
- data/lib/relaton/bib/model/extent.rb +16 -0
- data/lib/relaton/bib/model/full_name_type.rb +64 -0
- data/lib/relaton/bib/model/fullname.rb +11 -0
- data/lib/relaton/bib/model/ics.rb +14 -0
- data/lib/relaton/bib/model/image.rb +28 -0
- data/lib/relaton/bib/model/item.rb +129 -0
- data/lib/relaton/bib/model/item_base.rb +19 -0
- data/lib/relaton/bib/model/keyword.rb +30 -0
- data/lib/relaton/bib/model/locality.rb +18 -0
- data/lib/relaton/bib/model/locality_stack.rb +14 -0
- data/lib/relaton/bib/model/localized_string.rb +57 -0
- data/lib/relaton/bib/model/localized_string_attrs.rb +24 -0
- data/lib/relaton/bib/model/logo.rb +12 -0
- data/lib/relaton/bib/model/medium.rb +22 -0
- data/lib/relaton/bib/model/note.rb +16 -0
- data/lib/relaton/bib/model/organization.rb +13 -0
- data/lib/relaton/bib/model/organization_type.rb +42 -0
- data/lib/relaton/bib/model/person.rb +36 -0
- data/lib/relaton/bib/model/phone.rb +14 -0
- data/lib/relaton/bib/model/place.rb +33 -0
- data/lib/relaton/bib/model/price.rb +14 -0
- data/lib/relaton/bib/model/relation.rb +43 -0
- data/lib/relaton/bib/model/series.rb +32 -0
- data/lib/relaton/bib/model/size.rb +23 -0
- data/lib/relaton/bib/model/source_locality_stack.rb +14 -0
- data/lib/relaton/bib/model/status.rb +27 -0
- data/lib/relaton/bib/model/structured_identifier.rb +48 -0
- data/lib/relaton/bib/model/subdivision.rb +14 -0
- data/lib/relaton/bib/model/technical_committee.rb +14 -0
- data/lib/relaton/bib/model/title.rb +18 -0
- data/lib/relaton/bib/model/uri.rb +18 -0
- data/lib/relaton/bib/model/validity.rb +16 -0
- data/lib/relaton/bib/model/version.rb +14 -0
- data/lib/relaton/bib/model/workgroup.rb +20 -0
- data/lib/relaton/bib/parser/rfc_address.rb +60 -0
- data/lib/relaton/bib/parser/rfc_contacts.rb +35 -0
- data/lib/relaton/bib/parser/rfc_docidentifier.rb +70 -0
- data/lib/relaton/bib/parser/rfc_organization.rb +31 -0
- data/lib/relaton/bib/parser/rfc_person.rb +42 -0
- data/lib/relaton/bib/parser/rfc_reference.rb +143 -0
- data/lib/relaton/bib/parser/rfc_referencegroup.rb +45 -0
- data/lib/relaton/bib/parser/rfc_shared.rb +23 -0
- data/lib/relaton/bib/renderer/bibtex_builder.rb +348 -0
- data/lib/relaton/bib/renderer/rfc.rb +297 -0
- data/lib/relaton/bib/util.rb +18 -0
- data/lib/relaton/bib/version.rb +5 -0
- data/lib/{relaton_bib.rb → relaton/bib.rb} +47 -36
- data/lib/{relaton_bib → relaton}/bibtex_parser.rb +24 -27
- data/lib/{relaton_bib → relaton}/bibxml_parser.rb +43 -46
- data/lib/{relaton_bib → relaton}/hit.rb +3 -3
- data/lib/{relaton_bib → relaton}/hit_collection.rb +2 -2
- data/lib/{relaton_bib → relaton}/workers_pool.rb +1 -1
- data/lib/{relaton_bib → relaton}/xml_parser.rb +49 -51
- data/relaton-bib.gemspec +8 -8
- metadata +95 -74
- data/lib/relaton_bib/bib_item_locality.rb +0 -175
- data/lib/relaton_bib/biblio_note.rb +0 -72
- data/lib/relaton_bib/biblio_version.rb +0 -46
- data/lib/relaton_bib/bibliographic_date.rb +0 -119
- data/lib/relaton_bib/bibliographic_item.rb +0 -668
- data/lib/relaton_bib/bibliographic_size.rb +0 -103
- data/lib/relaton_bib/classification.rb +0 -40
- data/lib/relaton_bib/config.rb +0 -16
- data/lib/relaton_bib/contribution_info.rb +0 -117
- data/lib/relaton_bib/contributor.rb +0 -277
- data/lib/relaton_bib/copyright_association.rb +0 -79
- data/lib/relaton_bib/document_identifier.rb +0 -118
- data/lib/relaton_bib/document_relation.rb +0 -95
- data/lib/relaton_bib/document_relation_collection.rb +0 -57
- data/lib/relaton_bib/document_status.rb +0 -92
- data/lib/relaton_bib/document_type.rb +0 -52
- data/lib/relaton_bib/edition.rb +0 -55
- data/lib/relaton_bib/editorial_group.rb +0 -41
- data/lib/relaton_bib/extent.rb +0 -39
- data/lib/relaton_bib/forename.rb +0 -65
- data/lib/relaton_bib/formatted_ref.rb +0 -17
- data/lib/relaton_bib/formatted_string.rb +0 -133
- data/lib/relaton_bib/full_name.rb +0 -108
- data/lib/relaton_bib/hash_converter.rb +0 -568
- data/lib/relaton_bib/ics.rb +0 -42
- data/lib/relaton_bib/image.rb +0 -95
- data/lib/relaton_bib/localized_string.rb +0 -149
- data/lib/relaton_bib/medium.rb +0 -76
- data/lib/relaton_bib/organization.rb +0 -165
- data/lib/relaton_bib/person.rb +0 -129
- data/lib/relaton_bib/place.rb +0 -203
- data/lib/relaton_bib/renderer/bibtex_builder.rb +0 -312
- data/lib/relaton_bib/renderer/bibxml.rb +0 -296
- data/lib/relaton_bib/series.rb +0 -119
- data/lib/relaton_bib/structured_identifier.rb +0 -173
- data/lib/relaton_bib/technical_committee.rb +0 -34
- data/lib/relaton_bib/typed_title_string.rb +0 -191
- data/lib/relaton_bib/typed_uri.rb +0 -57
- data/lib/relaton_bib/util.rb +0 -16
- data/lib/relaton_bib/validity.rb +0 -52
- data/lib/relaton_bib/version.rb +0 -3
- data/lib/relaton_bib/workgroup.rb +0 -58
- /data/lib/{relaton_bib → relaton}/deep_dup.rb +0 -0
@@ -0,0 +1,711 @@
|
|
1
|
+
require_relative "../bib"
|
2
|
+
|
3
|
+
module Relaton
|
4
|
+
module Bib
|
5
|
+
module HashParserV1
|
6
|
+
extend self
|
7
|
+
# @param args [Hash]
|
8
|
+
# @return [Hash]
|
9
|
+
def hash_to_bib(args) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
10
|
+
return nil unless args.is_a?(Hash)
|
11
|
+
|
12
|
+
ret = Marshal.load(Marshal.dump(symbolize(args))) # deep copy
|
13
|
+
ret[:fetched] &&= ::Date.parse(ret[:fetched])
|
14
|
+
ret[:schema_version] = ret.delete(:"schema-version") if ret[:"schema-version"]
|
15
|
+
title_hash_to_bib(ret)
|
16
|
+
link_hash_to_bib(ret)
|
17
|
+
language_hash_to_bib(ret)
|
18
|
+
script_hash_to_bib(ret)
|
19
|
+
dates_hash_to_bib(ret)
|
20
|
+
docid_hash_to_bib(ret)
|
21
|
+
version_hash_to_bib(ret)
|
22
|
+
biblionote_hash_to_bib(ret)
|
23
|
+
abstract_hash_to_bib(ret)
|
24
|
+
formattedref_hash_to_bib(ret)
|
25
|
+
docstatus_hash_to_bib(ret)
|
26
|
+
contributors_hash_to_bib(ret)
|
27
|
+
edition_hash_to_bib(ret)
|
28
|
+
copyright_hash_to_bib(ret)
|
29
|
+
relations_hash_to_bib(ret)
|
30
|
+
series_hash_to_bib(ret)
|
31
|
+
medium_hash_to_bib(ret)
|
32
|
+
place_hash_to_bib(ret)
|
33
|
+
extent_hash_to_bib(ret)
|
34
|
+
size_hash_to_bib(ret)
|
35
|
+
accesslocation_hash_to_bib(ret)
|
36
|
+
classification_hash_to_bib(ret)
|
37
|
+
validity_hash_to_bib(ret)
|
38
|
+
keyword_hash_to_bib(ret)
|
39
|
+
ret[:license] = Relaton.array(ret[:license])
|
40
|
+
ext_hash_to_bib ret
|
41
|
+
ret
|
42
|
+
end
|
43
|
+
|
44
|
+
def ext_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize
|
45
|
+
ret[:ext] ||= {}
|
46
|
+
doctype_hash_to_bib ret
|
47
|
+
ret[:ext][:subdoctype] = ret.delete(:subdoctype) if ret[:subdoctype]
|
48
|
+
ret[:ext][:flavor] ||= flavor(ret)
|
49
|
+
editorialgroup_hash_to_bib ret
|
50
|
+
ics_hash_to_bib ret
|
51
|
+
structuredidentifier_hash_to_bib ret
|
52
|
+
ret[:ext] = Bib::Ext.new(**ret[:ext])
|
53
|
+
end
|
54
|
+
|
55
|
+
def flavor(ret)
|
56
|
+
return unless ret[:docid]
|
57
|
+
|
58
|
+
docid = ret[:docidentifier].find(&:primary)
|
59
|
+
return unless docid
|
60
|
+
|
61
|
+
docid.type.downcase
|
62
|
+
end
|
63
|
+
|
64
|
+
def keyword_hash_to_bib(ret)
|
65
|
+
ret[:keyword] = Relaton.array(ret[:keyword]).map do |keyword|
|
66
|
+
Bib::Keyword.new taxon: [localizedstring(keyword)]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def extent_hash_to_bib(ret)
|
71
|
+
return unless ret[:extent]
|
72
|
+
|
73
|
+
ret[:extent] = Relaton.array(ret[:extent]).map do |e|
|
74
|
+
Relaton::Bib::Extent.new locality: locality(e[:locality]),
|
75
|
+
locality_stack: locality_stack(e[:locality_stack])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def locality(locality)
|
80
|
+
Relaton.array(locality).map { |l| Bib::Locality.new(**l) }
|
81
|
+
end
|
82
|
+
|
83
|
+
def locality_stack(locality_stack)
|
84
|
+
Relaton.array(locality_stack).map { |l| Bib::LocalityStack.new locality: locality(l[:locality]) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def size_hash_to_bib(ret)
|
88
|
+
return unless ret[:size]
|
89
|
+
|
90
|
+
ret[:size] = Relaton.array(ret[:size])
|
91
|
+
value = ret[:size]&.map do |val|
|
92
|
+
val[:content] = val.delete(:value)
|
93
|
+
Bib::Size::Value.new(**val)
|
94
|
+
end
|
95
|
+
ret[:size] = Bib::Size.new(value: value)
|
96
|
+
end
|
97
|
+
|
98
|
+
def title_hash_to_bib(ret)
|
99
|
+
# return unless ret[:title]
|
100
|
+
|
101
|
+
# ret[:title] = Relaton.array(ret[:title]).reduce(Bib::TitleCollection.new) do |m, t|
|
102
|
+
# m << (t.is_a?(Hash) ? Bib::Title.new(**t) : Bib::Title.new(content: t))
|
103
|
+
# end
|
104
|
+
ret[:title] &&= title_collection(ret[:title])
|
105
|
+
end
|
106
|
+
|
107
|
+
def language_hash_to_bib(ret)
|
108
|
+
return unless ret[:language]
|
109
|
+
|
110
|
+
ret[:language] = Relaton.array(ret[:language])
|
111
|
+
end
|
112
|
+
|
113
|
+
def script_hash_to_bib(ret)
|
114
|
+
return unless ret[:script]
|
115
|
+
|
116
|
+
ret[:script] = Relaton.array(ret[:script])
|
117
|
+
end
|
118
|
+
|
119
|
+
def abstract_hash_to_bib(ret)
|
120
|
+
ret[:abstract] &&= Relaton.array(ret[:abstract]).map do |a|
|
121
|
+
localized_marked_up_string a
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def link_hash_to_bib(ret)
|
126
|
+
return unless ret[:link]
|
127
|
+
|
128
|
+
ret[:source] = Relaton.array(ret[:link]).map do |l|
|
129
|
+
Bib::Uri.new(**l)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def place_hash_to_bib(ret)
|
134
|
+
ret[:place] &&= Relaton.array(ret[:place]).map { |pl| create_place(pl) }
|
135
|
+
end
|
136
|
+
|
137
|
+
def create_place(place)
|
138
|
+
if place.is_a?(String)
|
139
|
+
Bib::Place.new(formatted_place: place)
|
140
|
+
else
|
141
|
+
place[:region] &&= create_region(place[:region])
|
142
|
+
place[:country] &&= create_region(place[:country])
|
143
|
+
Bib::Place.new(**place)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def create_region(region)
|
148
|
+
Relaton.array(region).map do |r|
|
149
|
+
r[:content] ||= r.delete(:name)
|
150
|
+
r[:iso] ||= r.delete(:code)
|
151
|
+
Bib::Place::RegionType.new(**r)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def accesslocation_hash_to_bib(ret)
|
156
|
+
return unless ret[:accesslocation]
|
157
|
+
|
158
|
+
ret[:accesslocation] = Relaton.array(ret[:accesslocation])
|
159
|
+
end
|
160
|
+
|
161
|
+
def dates_hash_to_bib(ret)
|
162
|
+
ret[:date] &&= Relaton.array(ret[:date]).map do |d|
|
163
|
+
# `at` is synonym of `on`, which is reserved word in YAML
|
164
|
+
d[:at] = d.delete(:value) if d[:value]
|
165
|
+
Bib::Date.new(**d)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def docid_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize
|
170
|
+
return unless ret[:docid]
|
171
|
+
|
172
|
+
ret[:docidentifier] = Relaton.array(ret[:docid]).map do |id|
|
173
|
+
id[:type] ||= id[:id].match(/^\w+(?=\s)/)&.to_s
|
174
|
+
id[:content] = id[:id]
|
175
|
+
create_docid(**id)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def create_docid(**args)
|
180
|
+
Bib::Docidentifier.new(**args)
|
181
|
+
end
|
182
|
+
|
183
|
+
def version_hash_to_bib(ret)
|
184
|
+
return unless ret[:version]
|
185
|
+
|
186
|
+
ret[:version] = Relaton.array(ret[:version]).map do |v|
|
187
|
+
v[:revision_date] &&= ::Date.parse(v[:revision_date])
|
188
|
+
Bib::Version.new(**v)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def biblionote_hash_to_bib(ret)
|
193
|
+
ret[:note] = Relaton.array(ret.delete(:biblionote)).map do |n|
|
194
|
+
n.is_a?(String) ? Bib::Note.new(content: n) : Bib::Note.new(**n)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def formattedref_hash_to_bib(ret)
|
199
|
+
ret[:formattedref] &&
|
200
|
+
ret[:formattedref] = formattedref(ret[:formattedref])
|
201
|
+
end
|
202
|
+
|
203
|
+
def docstatus_hash_to_bib(ret)
|
204
|
+
ret[:docstatus] && ret[:status]= Bib::Status.new(
|
205
|
+
stage: stage(ret[:docstatus][:stage]),
|
206
|
+
substage: stage(ret[:docstatus][:substage]),
|
207
|
+
iteration: ret[:docstatus][:iteration],
|
208
|
+
)
|
209
|
+
end
|
210
|
+
|
211
|
+
# @param stg [Hash]
|
212
|
+
# @return [Relaton::Bib::DocumentStatus::Stage]
|
213
|
+
def stage(stg)
|
214
|
+
return unless stg
|
215
|
+
|
216
|
+
args = stg.is_a?(String) ? { content: stg } : stg
|
217
|
+
args[:content] ||= args.delete(:value)
|
218
|
+
Bib::Status::Stage.new(**args)
|
219
|
+
end
|
220
|
+
|
221
|
+
def contributors_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength,Metrics/PerceivedComplexity
|
222
|
+
ret[:contributor] &&= Relaton.array(ret[:contributor]).map do |c|
|
223
|
+
roles = Relaton.array(c[:role]).map do |r|
|
224
|
+
if r.is_a? Hash
|
225
|
+
desc = Relaton.array(r[:description]).map { |d| localized_marked_up_string d }
|
226
|
+
Bib::Contributor::Role.new(type: r[:type], description: desc)
|
227
|
+
else
|
228
|
+
Bib::Contributor::Role.new(type: r)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
c[:role] = roles
|
232
|
+
(c[:person] &&= create_person(c[:person])) ||
|
233
|
+
(c[:organization] &&= create_organization(c[:organization]))
|
234
|
+
Bib::Contributor.new(**c)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def edition_hash_to_bib(ret)
|
239
|
+
ret[:edition] &&= if ret[:edition].is_a?(Hash)
|
240
|
+
Bib::Edition.new(**ret[:edition])
|
241
|
+
else
|
242
|
+
Bib::Edition.new(content: ret[:edition])
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def create_organization(org)
|
247
|
+
return nil if org.nil?
|
248
|
+
|
249
|
+
Bib::Organization.new(**org_hash_to_bib(org))
|
250
|
+
end
|
251
|
+
|
252
|
+
def org_hash_to_bib(org) # rubocop:disable Metrics/AbcSize
|
253
|
+
org[:identifier] = create_org_identifier(org[:identifier])
|
254
|
+
org[:subdivision] = create_org_subdivision(org[:subdivision])
|
255
|
+
org[:address] = address_hash_to_bib(org[:contact])
|
256
|
+
org[:phone] = phone_hash_to_bib(org[:contact])
|
257
|
+
org[:email] = email_hash_to_bib(org[:contact])
|
258
|
+
org[:uri] = uri_hash_to_bib(org[:contact] || org)
|
259
|
+
org[:logo] = Bib::Logo.new image: Bib::Image.new(**org[:logo][:image]) if org[:logo]
|
260
|
+
org[:name] = typed_localized_string(org[:name])
|
261
|
+
org[:abbreviation] &&= localizedstring(org[:abbreviation])
|
262
|
+
org
|
263
|
+
end
|
264
|
+
|
265
|
+
def create_org_identifier(identifier)
|
266
|
+
Relaton.array(identifier).map do |id|
|
267
|
+
Bib::Organization::Identifier.new(type: id[:type], content: id[:id])
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def create_org_subdivision(subdivision)
|
272
|
+
Relaton.array(subdivision).map do |sub|
|
273
|
+
if sub.is_a? String
|
274
|
+
orgname = Bib::TypedLocalizedString.new(content: sub)
|
275
|
+
Bib::Subdivision.new(name: [orgname])
|
276
|
+
elsif sub.is_a?(Hash) && sub[:content]
|
277
|
+
sub[:name] = sub.delete(:content)
|
278
|
+
Bib::Subdivision.new(**org_hash_to_bib(sub))
|
279
|
+
end
|
280
|
+
end.compact
|
281
|
+
end
|
282
|
+
|
283
|
+
def typed_localized_string(typed_strs)
|
284
|
+
Relaton.array(typed_strs).map do |args|
|
285
|
+
if args.is_a? String
|
286
|
+
Bib::TypedLocalizedString.new(content: args)
|
287
|
+
elsif args.is_a? Hash
|
288
|
+
Bib::TypedLocalizedString.new(**args)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# def create_org_name(name)
|
294
|
+
# Relaton.array(name).map do |nm|
|
295
|
+
# if nm.is_a?(Hash)
|
296
|
+
# Bib::Organization::Name.new(**nm)
|
297
|
+
# else
|
298
|
+
# Bib::Organization::Name.new(content: nm)
|
299
|
+
# end
|
300
|
+
# end
|
301
|
+
# end
|
302
|
+
|
303
|
+
def create_person(person)
|
304
|
+
Bib::Person.new(
|
305
|
+
name: fullname_hash_to_bib(person),
|
306
|
+
credential: Relaton.array(person[:credential]),
|
307
|
+
affiliation: affiliation_hash_to_bib(person),
|
308
|
+
address: address_hash_to_bib(person[:contact]),
|
309
|
+
phone: phone_hash_to_bib(person[:contact]),
|
310
|
+
email: email_hash_to_bib(person[:contact]),
|
311
|
+
uri: uri_hash_to_bib(person[:contact]),
|
312
|
+
identifier: person_identifiers_hash_to_bib(person),
|
313
|
+
)
|
314
|
+
end
|
315
|
+
|
316
|
+
def fullname_hash_to_bib(person) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
317
|
+
n = person[:name]
|
318
|
+
fname = given_hash_to_bib n[:given] || n # `n` is for backward compatibility
|
319
|
+
Bib::FullName.new(
|
320
|
+
abbreviation: localizedstring(n[:abbreviation]),
|
321
|
+
forename: fname,
|
322
|
+
formatted_initials: localizedstring(n.dig(:given, :formatted_initials)),
|
323
|
+
addition: Relaton.array(n[:addition])&.map { |f| localizedstring(f) },
|
324
|
+
prefix: Relaton.array(n[:prefix])&.map { |f| localizedstring(f) },
|
325
|
+
surname: localizedstring(n[:surname]),
|
326
|
+
completename: localizedstring(n[:completename]),
|
327
|
+
)
|
328
|
+
end
|
329
|
+
|
330
|
+
def given_hash_to_bib(given)
|
331
|
+
return unless given
|
332
|
+
|
333
|
+
Relaton.array(given[:forename])&.map { |f| forename_hash_to_bib(f) }
|
334
|
+
end
|
335
|
+
|
336
|
+
def forename_hash_to_bib(fname)
|
337
|
+
case fname
|
338
|
+
when Hash
|
339
|
+
lang_scrip_array_to_string fname
|
340
|
+
FullNameType::Forename.new(**fname)
|
341
|
+
when String then FullNameType::Forename.new(content: fname)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def person_identifiers_hash_to_bib(person)
|
346
|
+
Relaton.array(person[:identifier])&.map do |a|
|
347
|
+
Bib::Person::Identifier.new(type: a[:type], content: a[:id])
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
def affiliation_hash_to_bib(person) # rubocop:disable Metrics/AbcSize
|
352
|
+
return [] unless person[:affiliation]
|
353
|
+
|
354
|
+
Relaton.array(person[:affiliation]).map do |a|
|
355
|
+
a[:description] = Relaton.array(a[:description]).map do |d|
|
356
|
+
localized_marked_up_string d
|
357
|
+
end
|
358
|
+
Bib::Affiliation.new(
|
359
|
+
organization: create_organization(a[:organization]),
|
360
|
+
description: a[:description], name: localizedstring(a[:name])
|
361
|
+
)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def address_hash_to_bib(contact)
|
366
|
+
Relaton.array(contact).reduce([]) do |a, c|
|
367
|
+
next a unless c[:address]
|
368
|
+
|
369
|
+
a << create_address(c[:address])
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
def phone_hash_to_bib(contact)
|
374
|
+
Relaton.array(contact).reduce([]) do |a, c|
|
375
|
+
next a unless c[:phone]
|
376
|
+
|
377
|
+
c[:type] ||= "work"
|
378
|
+
a << Bib::Phone.new(type: c[:type], content: c[:phone])
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
def email_hash_to_bib(contact)
|
383
|
+
Relaton.array(contact).reduce([]) do |a, c|
|
384
|
+
next a unless c[:email]
|
385
|
+
|
386
|
+
a << c[:email]
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
def uri_hash_to_bib(contact)
|
391
|
+
Relaton.array(contact).reduce([]) do |a, c|
|
392
|
+
next a unless c[:uri] || c[:url]
|
393
|
+
|
394
|
+
a << Bib::Uri.new(content: c[:uri] || c[:url])
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
# def contacts_hash_to_bib(entity) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity
|
399
|
+
# return [] unless entity[:contact]
|
400
|
+
|
401
|
+
# Relaton.array(entity[:contact]).map do |a|
|
402
|
+
# type, value = a.reject { |k, _| k == :type }.flatten
|
403
|
+
# case type
|
404
|
+
# when :street, :city, :state, :country, :postcode # it's for old version compatibility, should be removed in the future
|
405
|
+
# a[:street] = Relaton.array(a[:street])
|
406
|
+
# Bib::Address.new(**a)
|
407
|
+
# when :address then create_address(a[:address])
|
408
|
+
# when :phone, :email, :uri
|
409
|
+
# Bib::Contact.new(type: type.to_s, value: value, subtype: a[:type])
|
410
|
+
# else # it's for old version compatibility, should be removed in the future
|
411
|
+
# Bib::Contact.new(**a)
|
412
|
+
# end
|
413
|
+
# end
|
414
|
+
# end
|
415
|
+
|
416
|
+
def create_address(adr)
|
417
|
+
if adr.is_a?(Hash)
|
418
|
+
adr[:street] = Relaton.array(adr[:street])
|
419
|
+
Bib::Address.new(**adr)
|
420
|
+
else
|
421
|
+
Bib::Address.new(formatted_address: adr)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
# @param ret [Hash]
|
426
|
+
def copyright_hash_to_bib(ret)
|
427
|
+
ret[:copyright] &&= Relaton.array(ret[:copyright]).map do |c|
|
428
|
+
c[:owner] = Relaton.array(c[:owner]).map do |o|
|
429
|
+
create_contribution_info(o)
|
430
|
+
end
|
431
|
+
Bib::Copyright.new(**c)
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def create_contribution_info(contrib)
|
436
|
+
if contrib[:name].is_a?(Hash) && (contrib[:name].keys & %i[prefix forename addition surname completename]).any?
|
437
|
+
Bib::ContributionInfo.new person: create_person(contrib)
|
438
|
+
else
|
439
|
+
Bib::ContributionInfo.new organization: create_organization(contrib)
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
# @param ret [Hash]
|
444
|
+
def relations_hash_to_bib(ret) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
445
|
+
return unless ret[:relation]
|
446
|
+
|
447
|
+
ret[:relation] &&= Relaton.array(ret[:relation]).map do |rel|
|
448
|
+
rel[:description] = LocalizedMarkedUpString.new(**rel[:description]) if rel[:description]
|
449
|
+
relation_bibitem_hash_to_bib(rel)
|
450
|
+
relation_locality_hash_to_bib(rel)
|
451
|
+
relation_locality_stack_hash_to_bib(rel)
|
452
|
+
relaton_source_locality_stack_hash_to_bib(rel)
|
453
|
+
relation_source_locality_hash_to_bib(rel)
|
454
|
+
create_relation rel
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def create_relation(rel)
|
459
|
+
Bib::Relation.new(**rel)
|
460
|
+
end
|
461
|
+
|
462
|
+
# @param rel [Hash] relation
|
463
|
+
def relation_bibitem_hash_to_bib(rel)
|
464
|
+
if rel[:bibitem]
|
465
|
+
rel[:bibitem] = bib_item hash_to_bib(rel[:bibitem])
|
466
|
+
else
|
467
|
+
Util.warn "Bibitem missing: `#(rel)`"
|
468
|
+
rel[:bibitem] = nil
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
# @param item_hash [Hash]
|
473
|
+
# @return [Relaton::Bib::Item]
|
474
|
+
def bib_item(item_hash)
|
475
|
+
ItemData.new(**item_hash)
|
476
|
+
end
|
477
|
+
|
478
|
+
# @param rel [Hash] relation
|
479
|
+
# @return [Relaton::Bib::LocalityStack]
|
480
|
+
def relation_locality_hash_to_bib(rel)
|
481
|
+
return unless rel[:locality]&.any?
|
482
|
+
|
483
|
+
rel[:locality] = Relaton.array(rel[:locality]).map do |bl|
|
484
|
+
Bib::Locality.new(**bl)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
def relation_locality_stack_hash_to_bib(rel)
|
489
|
+
return unless rel[:locality_stack]&.any?
|
490
|
+
|
491
|
+
rel[:locality_stack] = Relaton.array(rel[:locality_stack]).map do |ls|
|
492
|
+
Bib::LocalityStack.new locality: relation_locality_hash_to_bib(ls)
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
# def locality_locality_stack(lls)
|
497
|
+
# if lls[:locality_stack]
|
498
|
+
# RelatonBib.array(lls[:locality_stack]).map do |lc|
|
499
|
+
# l = lc[:locality] || lc
|
500
|
+
# Locality.new(l[:type], l[:reference_from], l[:reference_to])
|
501
|
+
# end
|
502
|
+
# else
|
503
|
+
# [Locality.new(lls[:type], lls[:reference_from], lls[:reference_to])]
|
504
|
+
# end
|
505
|
+
# end
|
506
|
+
|
507
|
+
# @param rel [Hash] relation
|
508
|
+
def relation_source_locality_hash_to_bib(rel)
|
509
|
+
rel[:source_locality] = Relaton.array(rel[:source_locality]).map do |loc|
|
510
|
+
Bib::Locality.new(**loc)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
def relaton_source_locality_stack_hash_to_bib(rel) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
515
|
+
sls = Relaton.array(rel[:source_locality_stack])
|
516
|
+
Relaton.array(rel[:source_locality]).each do |loc|
|
517
|
+
sls << Relaton.array(loc[:source_locality_stack]) if loc[:source_locality_stack]
|
518
|
+
end
|
519
|
+
|
520
|
+
case rel[:source_locality]
|
521
|
+
when Hash then rel[:source_locality].delete(:source_locality_stack)
|
522
|
+
when Array then rel[:source_locality].delete_if { |loc| loc[:source_locality_stack] }
|
523
|
+
end
|
524
|
+
|
525
|
+
rel[:source_locality_stack] = sls.map do |loc|
|
526
|
+
SourceLocalityStack.new source_locality: relation_source_locality_hash_to_bib(source_locality: loc)
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
# @param ret [Hash]
|
531
|
+
def series_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
532
|
+
ret[:series] &&= Relaton.array(ret[:series]).map do |s|
|
533
|
+
s[:formattedref] && s[:formattedref] = formattedref(s[:formattedref])
|
534
|
+
s[:title] &&= title_collection(s[:title])
|
535
|
+
s[:place] &&= create_place(s[:place])
|
536
|
+
s[:abbreviation] &&= localizedstring(s[:abbreviation])
|
537
|
+
s[:from] &&= ::Date.parse(s[:from])
|
538
|
+
s[:to] &&= ::Date.parse(s[:to])
|
539
|
+
Bib::Series.new(**s)
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
#
|
544
|
+
# @param title [Hash, Strinbg, Array<Hash, String>]
|
545
|
+
#
|
546
|
+
# @return [Relaton::Bib::TitleCollection]
|
547
|
+
#
|
548
|
+
def title_collection(title)
|
549
|
+
Relaton.array(title).map do |t|
|
550
|
+
if t.is_a?(Hash)
|
551
|
+
lang_scrip_array_to_string t
|
552
|
+
Bib::Title.new(**t)
|
553
|
+
elsif t.is_a?(String)
|
554
|
+
Bib::Title.new(content: t)
|
555
|
+
end
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
# @param ret [Hash]
|
560
|
+
def medium_hash_to_bib(ret)
|
561
|
+
ret[:medium] = Bib::Medium.new(**ret[:medium]) if ret[:medium]
|
562
|
+
end
|
563
|
+
|
564
|
+
# @param ret [Hash]
|
565
|
+
def classification_hash_to_bib(ret)
|
566
|
+
if ret[:classification]
|
567
|
+
ret[:classification] = Relaton.array(ret[:classification]).map do |cls|
|
568
|
+
cls[:content] ||= cls.delete(:value)
|
569
|
+
Docidentifier.new(**cls)
|
570
|
+
end
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
# @param ret [Hash]
|
575
|
+
def validity_hash_to_bib(ret)
|
576
|
+
return unless ret[:validity]
|
577
|
+
|
578
|
+
b = parse_validity_time(ret[:validity], :begins)
|
579
|
+
e = parse_validity_time(ret[:validity], :ends)
|
580
|
+
r = parse_validity_time(ret[:validity], :revision)
|
581
|
+
ret[:validity] = Bib::Validity.new(begins: b, ends: e, revision: r)
|
582
|
+
end
|
583
|
+
|
584
|
+
def parse_validity_time(val, period)
|
585
|
+
t = val[period]&.to_s
|
586
|
+
return unless t
|
587
|
+
|
588
|
+
p = period == :ends ? -1 : 1
|
589
|
+
case t
|
590
|
+
when /^\d{4}$/
|
591
|
+
::Date.new(t.to_i, p, p).to_time
|
592
|
+
when /^(?<year>\d{4})-(?<month>\d{1,2})$/
|
593
|
+
::Date.new($~[:year].to_i, $~[:month].to_i, p).to_time
|
594
|
+
else ::Date.parse t
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
598
|
+
# @param ret [Hash]
|
599
|
+
def editorialgroup_hash_to_bib(ret)
|
600
|
+
eg = ret.dig(:ext, :editorialgroup) || ret[:editorialgroup] # @todo remove ret[:editorialgroup] in the future
|
601
|
+
return unless eg
|
602
|
+
|
603
|
+
technical_committee = workgroup_hash_to_bib eg
|
604
|
+
ret[:ext][:editorialgroup] = Bib::EditorialGroup.new technical_committee: technical_committee
|
605
|
+
end
|
606
|
+
|
607
|
+
def workgroup_hash_to_bib(wrkg)
|
608
|
+
Relaton.array(wrkg).map { |wg| create_workgroup wg }
|
609
|
+
end
|
610
|
+
|
611
|
+
def create_workgroup(wrkg)
|
612
|
+
wrkg[:content] ||= wrkg.delete(:name)
|
613
|
+
Bib::WorkGroup.new(**wrkg)
|
614
|
+
end
|
615
|
+
|
616
|
+
# @param ret [Hash]
|
617
|
+
def ics_hash_to_bib(ret)
|
618
|
+
ics = ret.dig(:ext, :ics) || ret[:ics] # @todo remove ret[:ics] in the future
|
619
|
+
return unless ics
|
620
|
+
|
621
|
+
ret[:ext][:ics] = Relaton.array(ics).map { |item| Bib::ICS.new(**item) }
|
622
|
+
end
|
623
|
+
|
624
|
+
# @param ret [Hash]
|
625
|
+
def structuredidentifier_hash_to_bib(ret)
|
626
|
+
struct_id = ret.dig(:ext, :structuredidentifier) || ret[:structuredidentifier] # @todo remove ret[:structuredidentifier] in the future
|
627
|
+
return unless struct_id
|
628
|
+
|
629
|
+
sids = Relaton.array(struct_id).map do |si|
|
630
|
+
si[:agency] = Relaton.array si[:agency]
|
631
|
+
si[:klass] = si.delete(:class)
|
632
|
+
Bib::StructuredIdentifier.new(**si)
|
633
|
+
end
|
634
|
+
ret[:ext][:structuredidentifier] = sids
|
635
|
+
end
|
636
|
+
|
637
|
+
# @param ogj [Hash, Array, String]
|
638
|
+
# @return [Hash, Array, String]
|
639
|
+
def symbolize(obj)
|
640
|
+
case obj
|
641
|
+
when Hash
|
642
|
+
obj.reduce({}) do |memo, (k, v)|
|
643
|
+
memo[k.to_sym] = symbolize(v)
|
644
|
+
memo
|
645
|
+
end
|
646
|
+
when Array then obj.reduce([]) { |memo, v| memo << symbolize(v) }
|
647
|
+
else obj
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
# @param lst [Hash, Array<Relaton::Bib::LocalizedString>, String]
|
652
|
+
# @return [Relaton::Bib::LocalizedString]
|
653
|
+
def localizedstring(lst)
|
654
|
+
return unless lst
|
655
|
+
|
656
|
+
if lst.is_a?(Hash)
|
657
|
+
lang_scrip_array_to_string lst
|
658
|
+
Bib::LocalizedString.new(**lst)
|
659
|
+
else Bib::LocalizedString.new(content: lst)
|
660
|
+
end
|
661
|
+
end
|
662
|
+
|
663
|
+
def lang_scrip_array_to_string(lst)
|
664
|
+
lst[:language] = lst[:language][0] if lst[:language].is_a?(Array)
|
665
|
+
lst[:script] = lst[:script][0] if lst[:script].is_a?(Array)
|
666
|
+
end
|
667
|
+
|
668
|
+
def localized_marked_up_string(lst)
|
669
|
+
return unless lst
|
670
|
+
|
671
|
+
if lst.is_a?(Hash)
|
672
|
+
lang_scrip_array_to_string lst
|
673
|
+
LocalizedMarkedUpString.new(**lst)
|
674
|
+
else LocalizedMarkedUpString.new(content: lst)
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
# @param frf [Hash, String]
|
679
|
+
# @return [Relaton::Bib::Formattedref]
|
680
|
+
def formattedref(frf)
|
681
|
+
if frf.is_a?(Hash)
|
682
|
+
# Relaton::Bib::Formattedref.new(**frf)
|
683
|
+
frf[:content]
|
684
|
+
else
|
685
|
+
# Relaton::Bib::Formattedref.new(content: frf)
|
686
|
+
frf
|
687
|
+
end
|
688
|
+
end
|
689
|
+
|
690
|
+
def doctype_hash_to_bib(ret)
|
691
|
+
doctype = ret.dig(:ext, :doctype) || ret[:doctype] # @todo remove ret[:doctype] in the future
|
692
|
+
return unless doctype
|
693
|
+
|
694
|
+
ret[:ext][:doctype] = create_doctype(doctype_args(doctype))
|
695
|
+
end
|
696
|
+
|
697
|
+
def doctype_args(args)
|
698
|
+
if args.is_a?(String)
|
699
|
+
{ content: args }
|
700
|
+
else
|
701
|
+
args[:content] = args.delete(:type)
|
702
|
+
args
|
703
|
+
end
|
704
|
+
end
|
705
|
+
|
706
|
+
def create_doctype(args)
|
707
|
+
Bib::Doctype.new(**args)
|
708
|
+
end
|
709
|
+
end
|
710
|
+
end
|
711
|
+
end
|