briard 2.4.2 → 2.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/codeql-analysis.yml +72 -0
- data/.github/workflows/rubocop.yml +50 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +144 -620
- data/.rubocop_todo.yml +76 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +43 -9
- data/Rakefile +1 -1
- data/{bolognese.gemspec → briard.gemspec} +46 -39
- data/lib/briard/array.rb +2 -2
- data/lib/briard/author_utils.rb +79 -71
- data/lib/briard/cli.rb +12 -13
- data/lib/briard/crossref_utils.rb +73 -61
- data/lib/briard/datacite_utils.rb +132 -106
- data/lib/briard/doi_utils.rb +10 -10
- data/lib/briard/metadata.rb +96 -106
- data/lib/briard/metadata_utils.rb +87 -78
- data/lib/briard/readers/bibtex_reader.rb +65 -65
- data/lib/briard/readers/cff_reader.rb +88 -70
- data/lib/briard/readers/citeproc_reader.rb +90 -84
- data/lib/briard/readers/codemeta_reader.rb +68 -50
- data/lib/briard/readers/crosscite_reader.rb +2 -2
- data/lib/briard/readers/crossref_reader.rb +249 -210
- data/lib/briard/readers/datacite_json_reader.rb +3 -3
- data/lib/briard/readers/datacite_reader.rb +225 -189
- data/lib/briard/readers/npm_reader.rb +49 -42
- data/lib/briard/readers/ris_reader.rb +82 -80
- data/lib/briard/readers/schema_org_reader.rb +182 -159
- data/lib/briard/string.rb +1 -1
- data/lib/briard/utils.rb +4 -4
- data/lib/briard/version.rb +3 -1
- data/lib/briard/whitelist_scrubber.rb +11 -4
- data/lib/briard/writers/bibtex_writer.rb +14 -8
- data/lib/briard/writers/cff_writer.rb +33 -26
- data/lib/briard/writers/codemeta_writer.rb +19 -15
- data/lib/briard/writers/csv_writer.rb +6 -4
- data/lib/briard/writers/datacite_json_writer.rb +8 -2
- data/lib/briard/writers/jats_writer.rb +33 -28
- data/lib/briard/writers/rdf_xml_writer.rb +1 -1
- data/lib/briard/writers/ris_writer.rb +30 -18
- data/lib/briard/writers/turtle_writer.rb +1 -1
- data/lib/briard.rb +6 -6
- data/rubocop.sarif +0 -0
- data/spec/array_spec.rb +5 -5
- data/spec/author_utils_spec.rb +151 -132
- data/spec/datacite_utils_spec.rb +135 -83
- data/spec/doi_utils_spec.rb +168 -164
- data/spec/find_from_format_spec.rb +69 -69
- data/spec/fixtures/vcr_cassettes/Briard_Metadata/sanitize/onlies_keep_specific_tags.yml +65 -0
- data/spec/fixtures/vcr_cassettes/Briard_Metadata/sanitize/removes_a_tags.yml +65 -0
- data/spec/metadata_spec.rb +91 -90
- data/spec/readers/bibtex_reader_spec.rb +43 -38
- data/spec/readers/cff_reader_spec.rb +165 -153
- data/spec/readers/citeproc_reader_spec.rb +45 -40
- data/spec/readers/codemeta_reader_spec.rb +128 -115
- data/spec/readers/crosscite_reader_spec.rb +34 -24
- data/spec/readers/crossref_reader_spec.rb +1098 -939
- data/spec/readers/datacite_json_reader_spec.rb +53 -40
- data/spec/readers/datacite_reader_spec.rb +1541 -1337
- data/spec/readers/npm_reader_spec.rb +48 -43
- data/spec/readers/ris_reader_spec.rb +53 -47
- data/spec/readers/schema_org_reader_spec.rb +329 -267
- data/spec/spec_helper.rb +6 -5
- data/spec/utils_spec.rb +371 -347
- data/spec/writers/bibtex_writer_spec.rb +143 -143
- data/spec/writers/cff_writer_spec.rb +96 -90
- data/spec/writers/citation_writer_spec.rb +34 -33
- data/spec/writers/citeproc_writer_spec.rb +226 -224
- data/spec/writers/codemeta_writer_spec.rb +18 -16
- data/spec/writers/crosscite_writer_spec.rb +91 -73
- data/spec/writers/crossref_writer_spec.rb +99 -91
- data/spec/writers/csv_writer_spec.rb +70 -70
- data/spec/writers/datacite_json_writer_spec.rb +78 -68
- data/spec/writers/datacite_writer_spec.rb +417 -322
- data/spec/writers/jats_writer_spec.rb +177 -161
- data/spec/writers/rdf_xml_writer_spec.rb +68 -63
- data/spec/writers/ris_writer_spec.rb +162 -162
- data/spec/writers/schema_org_writer_spec.rb +329 -294
- data/spec/writers/turtle_writer_spec.rb +47 -47
- metadata +242 -166
- data/.github/workflows/release.yml +0 -47
data/lib/briard/metadata.rb
CHANGED
@@ -6,17 +6,13 @@ module Briard
|
|
6
6
|
class Metadata
|
7
7
|
include Briard::MetadataUtils
|
8
8
|
|
9
|
-
attr_accessor :string, :from, :sandbox, :meta, :regenerate, :issue, :show_errors
|
9
|
+
attr_accessor :string, :from, :sandbox, :meta, :regenerate, :issue, :show_errors, :depositor,
|
10
|
+
:email, :registrant
|
10
11
|
attr_reader :doc, :page_start, :page_end
|
11
|
-
attr_writer :id, :provider_id, :client_id, :doi, :identifiers, :creators, :contributors,
|
12
|
-
:rights_list, :dates, :publication_year, :volume, :url, :version_info,
|
13
|
-
|
14
|
-
|
15
|
-
:format, :funding_references, :state, :geo_locations,
|
16
|
-
:types, :content_url, :related_identifiers, :related_items, :style, :locale, :date_registered,
|
17
|
-
:depositor, :email, :registrant
|
18
|
-
|
19
|
-
def initialize(options={})
|
12
|
+
attr_writer :id, :provider_id, :client_id, :doi, :identifiers, :creators, :contributors,
|
13
|
+
:titles, :publisher, :rights_list, :dates, :publication_year, :volume, :url, :version_info, :subjects, :contributor, :descriptions, :language, :sizes, :formats, :schema_version, :meta, :container, :agency, :format, :funding_references, :state, :geo_locations, :types, :content_url, :related_identifiers, :related_items, :style, :locale, :date_registered
|
14
|
+
|
15
|
+
def initialize(options = {})
|
20
16
|
options.symbolize_keys!
|
21
17
|
|
22
18
|
id = normalize_id(options[:input], options)
|
@@ -26,64 +22,69 @@ module Briard
|
|
26
22
|
@from = options[:from] || find_from_format(id: id)
|
27
23
|
|
28
24
|
# mEDRA, KISTI, JaLC and OP DOIs are found in the Crossref index
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
25
|
+
case @from
|
26
|
+
when 'medra'
|
27
|
+
ra = 'mEDRA'
|
28
|
+
when 'kisti'
|
29
|
+
ra = 'KISTI'
|
30
|
+
when 'jalc'
|
31
|
+
ra = 'JaLC'
|
32
|
+
when 'op'
|
33
|
+
ra = 'OP'
|
37
34
|
end
|
38
35
|
|
39
36
|
# generate name for method to call dynamically
|
40
|
-
hsh = @from.present? ? send("get_
|
41
|
-
string = hsh.fetch(
|
37
|
+
hsh = @from.present? ? send("get_#{@from}", id: id, sandbox: options[:sandbox]) : {}
|
38
|
+
string = hsh.fetch('string', nil)
|
42
39
|
|
43
40
|
elsif options[:input].present? && File.exist?(options[:input])
|
44
41
|
filename = File.basename(options[:input])
|
45
42
|
ext = File.extname(options[:input])
|
46
|
-
if %w
|
43
|
+
if %w[.bib .ris .xml .json .cff].include?(ext)
|
47
44
|
hsh = {
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
45
|
+
'url' => options[:url],
|
46
|
+
'state' => options[:state],
|
47
|
+
'date_registered' => options[:date_registered],
|
48
|
+
'date_updated' => options[:date_updated],
|
49
|
+
'provider_id' => options[:provider_id],
|
50
|
+
'client_id' => options[:client_id],
|
51
|
+
'depositor' => options[:depositor],
|
52
|
+
'email' => options[:email],
|
53
|
+
'registrant' => options[:registrant],
|
54
|
+
'content_url' => options[:content_url]
|
55
|
+
}
|
56
|
+
string = File.read(options[:input])
|
59
57
|
@from = options[:from] || find_from_format(string: string, filename: filename, ext: ext)
|
60
58
|
else
|
61
|
-
|
59
|
+
warn "File type #{ext} not supported"
|
62
60
|
exit 1
|
63
61
|
end
|
64
62
|
else
|
65
63
|
hsh = {
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
64
|
+
'url' => options[:url],
|
65
|
+
'state' => options[:state],
|
66
|
+
'date_registered' => options[:date_registered],
|
67
|
+
'date_updated' => options[:date_updated],
|
68
|
+
'provider_id' => options[:provider_id],
|
69
|
+
'client_id' => options[:client_id],
|
70
|
+
'depositor' => options[:depositor],
|
71
|
+
'email' => options[:email],
|
72
|
+
'registrant' => options[:registrant],
|
73
|
+
'content_url' => options[:content_url],
|
74
|
+
'creators' => options[:creators],
|
75
|
+
'contributors' => options[:contributors],
|
76
|
+
'titles' => options[:titles],
|
77
|
+
'publisher' => options[:publisher],
|
78
|
+
'publication_year' => options[:publication_year]
|
79
|
+
}
|
81
80
|
string = options[:input]
|
82
81
|
@from = options[:from] || find_from_format(string: string)
|
83
82
|
end
|
84
83
|
|
85
84
|
# make sure input is encoded as utf8
|
86
|
-
|
85
|
+
if string.present? && string.is_a?(String)
|
86
|
+
dup_string = string.dup.force_encoding('UTF-8').encode!
|
87
|
+
end
|
87
88
|
@string = dup_string
|
88
89
|
|
89
90
|
# input options for citation formatting
|
@@ -93,19 +94,19 @@ module Briard
|
|
93
94
|
@sandbox = options[:sandbox]
|
94
95
|
|
95
96
|
# options that come from the datacite database
|
96
|
-
@url = hsh.to_h[
|
97
|
-
@state = hsh.to_h[
|
98
|
-
@date_registered = hsh.to_h[
|
99
|
-
@date_updated = hsh.to_h[
|
100
|
-
@provider_id = hsh.to_h[
|
101
|
-
@client_id = hsh.to_h[
|
102
|
-
@content_url = hsh.to_h[
|
97
|
+
@url = hsh.to_h['url'].presence || options[:url].presence
|
98
|
+
@state = hsh.to_h['state'].presence
|
99
|
+
@date_registered = hsh.to_h['date_registered'].presence
|
100
|
+
@date_updated = hsh.to_h['date_updated'].presence
|
101
|
+
@provider_id = hsh.to_h['provider_id'].presence
|
102
|
+
@client_id = hsh.to_h['client_id'].presence
|
103
|
+
@content_url = hsh.to_h['content_url'].presence
|
103
104
|
|
104
105
|
# options that come from the submission, needed
|
105
106
|
# for crossref doi registration
|
106
|
-
@depositor = hsh.to_h[
|
107
|
-
@email = hsh.to_h[
|
108
|
-
@registrant = hsh.to_h[
|
107
|
+
@depositor = hsh.to_h['depositor'].presence
|
108
|
+
@email = hsh.to_h['email'].presence
|
109
|
+
@registrant = hsh.to_h['registrant'].presence
|
109
110
|
|
110
111
|
# set attributes directly
|
111
112
|
read_options = options.slice(
|
@@ -133,40 +134,29 @@ module Briard
|
|
133
134
|
|
134
135
|
@regenerate = options[:regenerate] || read_options.present?
|
135
136
|
# generate name for method to call dynamically
|
136
|
-
opts = { string: string, sandbox: options[:sandbox], doi: options[:doi], id: id,
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
def depositor
|
141
|
-
@depositor
|
142
|
-
end
|
143
|
-
|
144
|
-
def email
|
145
|
-
@email
|
146
|
-
end
|
147
|
-
|
148
|
-
def registrant
|
149
|
-
@registrant
|
137
|
+
opts = { string: string, sandbox: options[:sandbox], doi: options[:doi], id: id,
|
138
|
+
ra: ra }.merge(read_options)
|
139
|
+
@meta = @from.present? ? send("read_#{@from}", **opts) : {}
|
150
140
|
end
|
151
141
|
|
152
142
|
def id
|
153
|
-
@id ||= meta.fetch(
|
143
|
+
@id ||= meta.fetch('id', nil)
|
154
144
|
end
|
155
145
|
|
156
146
|
def doi
|
157
|
-
@doi ||= meta.fetch(
|
147
|
+
@doi ||= meta.fetch('doi', nil)
|
158
148
|
end
|
159
149
|
|
160
150
|
def provider_id
|
161
|
-
@provider_id ||= meta.fetch(
|
151
|
+
@provider_id ||= meta.fetch('provider_id', nil)
|
162
152
|
end
|
163
153
|
|
164
154
|
def client_id
|
165
|
-
@client_id ||= meta.fetch(
|
155
|
+
@client_id ||= meta.fetch('client_id', nil)
|
166
156
|
end
|
167
157
|
|
168
158
|
def exists?
|
169
|
-
(@state || meta.fetch(
|
159
|
+
(@state || meta.fetch('state', nil)) != 'not_found'
|
170
160
|
end
|
171
161
|
|
172
162
|
def valid?
|
@@ -175,111 +165,111 @@ module Briard
|
|
175
165
|
|
176
166
|
# validate against DataCite schema, unless already errors in the reader
|
177
167
|
def errors
|
178
|
-
meta.fetch(
|
168
|
+
meta.fetch('errors', nil) || datacite_errors(xml: datacite, schema_version: schema_version)
|
179
169
|
end
|
180
170
|
|
181
171
|
def descriptions
|
182
|
-
@descriptions ||= meta.fetch(
|
172
|
+
@descriptions ||= meta.fetch('descriptions', nil)
|
183
173
|
end
|
184
174
|
|
185
175
|
def rights_list
|
186
|
-
@rights_list ||= meta.fetch(
|
176
|
+
@rights_list ||= meta.fetch('rights_list', nil)
|
187
177
|
end
|
188
178
|
|
189
179
|
def subjects
|
190
|
-
@subjects ||= meta.fetch(
|
180
|
+
@subjects ||= meta.fetch('subjects', nil)
|
191
181
|
end
|
192
182
|
|
193
183
|
def language
|
194
|
-
@language ||= meta.fetch(
|
184
|
+
@language ||= meta.fetch('language', nil)
|
195
185
|
end
|
196
186
|
|
197
187
|
def sizes
|
198
|
-
@sizes ||= meta.fetch(
|
188
|
+
@sizes ||= meta.fetch('sizes', nil)
|
199
189
|
end
|
200
190
|
|
201
191
|
def formats
|
202
|
-
@formats ||= meta.fetch(
|
192
|
+
@formats ||= meta.fetch('formats', nil)
|
203
193
|
end
|
204
194
|
|
205
195
|
def schema_version
|
206
|
-
@schema_version ||= meta.fetch(
|
196
|
+
@schema_version ||= meta.fetch('schema_version', nil)
|
207
197
|
end
|
208
198
|
|
209
199
|
def funding_references
|
210
|
-
@funding_references ||= meta.fetch(
|
200
|
+
@funding_references ||= meta.fetch('funding_references', nil)
|
211
201
|
end
|
212
202
|
|
213
203
|
def related_identifiers
|
214
|
-
@related_identifiers ||= meta.fetch(
|
204
|
+
@related_identifiers ||= meta.fetch('related_identifiers', nil)
|
215
205
|
end
|
216
206
|
|
217
207
|
def related_items
|
218
|
-
@related_items ||= meta.fetch(
|
208
|
+
@related_items ||= meta.fetch('related_items', nil)
|
219
209
|
end
|
220
210
|
|
221
211
|
def url
|
222
|
-
@url ||= meta.fetch(
|
212
|
+
@url ||= meta.fetch('url', nil)
|
223
213
|
end
|
224
214
|
|
225
215
|
def version_info
|
226
|
-
@version_info ||= meta.fetch(
|
216
|
+
@version_info ||= meta.fetch('version_info', nil) || meta.fetch('version', nil)
|
227
217
|
end
|
228
218
|
|
229
219
|
def publication_year
|
230
|
-
@publication_year ||= meta.fetch(
|
220
|
+
@publication_year ||= meta.fetch('publication_year', nil)
|
231
221
|
end
|
232
222
|
|
233
223
|
def container
|
234
|
-
@container ||= meta.fetch(
|
224
|
+
@container ||= meta.fetch('container', nil)
|
235
225
|
end
|
236
226
|
|
237
227
|
def geo_locations
|
238
|
-
@geo_locations ||= meta.fetch(
|
228
|
+
@geo_locations ||= meta.fetch('geo_locations', nil)
|
239
229
|
end
|
240
230
|
|
241
231
|
def dates
|
242
|
-
@dates ||= meta.fetch(
|
232
|
+
@dates ||= meta.fetch('dates', nil)
|
243
233
|
end
|
244
234
|
|
245
235
|
def publisher
|
246
|
-
@publisher ||= meta.fetch(
|
236
|
+
@publisher ||= meta.fetch('publisher', nil)
|
247
237
|
end
|
248
238
|
|
249
239
|
def identifiers
|
250
|
-
@identifiers ||= meta.fetch(
|
240
|
+
@identifiers ||= meta.fetch('identifiers', nil)
|
251
241
|
end
|
252
242
|
|
253
243
|
def content_url
|
254
|
-
@content_url ||= meta.fetch(
|
244
|
+
@content_url ||= meta.fetch('content_url', nil)
|
255
245
|
end
|
256
246
|
|
257
247
|
def agency
|
258
|
-
@agency ||= meta.fetch(
|
248
|
+
@agency ||= meta.fetch('agency', nil)
|
259
249
|
end
|
260
250
|
|
261
251
|
def state
|
262
|
-
@state ||= meta.fetch(
|
252
|
+
@state ||= meta.fetch('state', nil)
|
263
253
|
end
|
264
254
|
|
265
255
|
def date_registered
|
266
|
-
@date_registered ||= meta.fetch(
|
256
|
+
@date_registered ||= meta.fetch('date_registered', nil)
|
267
257
|
end
|
268
258
|
|
269
259
|
def types
|
270
|
-
@types ||= meta.fetch(
|
260
|
+
@types ||= meta.fetch('types', nil)
|
271
261
|
end
|
272
262
|
|
273
263
|
def titles
|
274
|
-
@titles ||= meta.fetch(
|
264
|
+
@titles ||= meta.fetch('titles', nil)
|
275
265
|
end
|
276
266
|
|
277
267
|
def creators
|
278
|
-
@creators ||= meta.fetch(
|
268
|
+
@creators ||= meta.fetch('creators', nil)
|
279
269
|
end
|
280
270
|
|
281
271
|
def contributors
|
282
|
-
@contributors ||= meta.fetch(
|
272
|
+
@contributors ||= meta.fetch('contributors', nil)
|
283
273
|
end
|
284
274
|
end
|
285
|
-
end
|
275
|
+
end
|
@@ -86,25 +86,23 @@ module Briard
|
|
86
86
|
# replace DOI in XML if provided in options
|
87
87
|
def raw
|
88
88
|
r = string.present? ? string.strip : nil
|
89
|
-
return r unless
|
89
|
+
return r unless from == 'datacite' && r.present?
|
90
90
|
|
91
91
|
doc = Nokogiri::XML(string, nil, 'UTF-8', &:noblanks)
|
92
|
-
node = doc.at_css(
|
92
|
+
node = doc.at_css('identifier')
|
93
93
|
node.content = doi.to_s.upcase if node.present? && doi.present?
|
94
94
|
doc.to_xml.strip
|
95
95
|
end
|
96
96
|
|
97
97
|
def should_passthru
|
98
|
-
(from ==
|
98
|
+
(from == 'datacite') && regenerate.blank? && raw.present?
|
99
99
|
end
|
100
100
|
|
101
101
|
def container_title
|
102
102
|
if container.present?
|
103
|
-
container[
|
104
|
-
elsif types[
|
103
|
+
container['title']
|
104
|
+
elsif types['citeproc'] == 'article-journal'
|
105
105
|
publisher
|
106
|
-
else
|
107
|
-
nil
|
108
106
|
end
|
109
107
|
end
|
110
108
|
|
@@ -114,16 +112,20 @@ module Briard
|
|
114
112
|
end
|
115
113
|
|
116
114
|
def reverse
|
117
|
-
{
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
115
|
+
{ 'citation' => Array.wrap(related_identifiers).select do |ri|
|
116
|
+
ri['relationType'] == 'IsReferencedBy'
|
117
|
+
end.map do |r|
|
118
|
+
{ '@id' => normalize_doi(r['relatedIdentifier']),
|
119
|
+
'@type' => r['resourceTypeGeneral'] || 'ScholarlyArticle',
|
120
|
+
'identifier' => r['relatedIdentifierType'] == 'DOI' ? nil : to_identifier(r) }.compact
|
121
|
+
end.unwrap,
|
122
|
+
'isBasedOn' => Array.wrap(related_identifiers).select do |ri|
|
123
|
+
ri['relationType'] == 'IsSupplementTo'
|
124
|
+
end.map do |r|
|
125
|
+
{ '@id' => normalize_doi(r['relatedIdentifier']),
|
126
|
+
'@type' => r['resourceTypeGeneral'] || 'ScholarlyArticle',
|
127
|
+
'identifier' => r['relatedIdentifierType'] == 'DOI' ? nil : to_identifier(r) }.compact
|
128
|
+
end.unwrap }.compact
|
127
129
|
end
|
128
130
|
|
129
131
|
def graph
|
@@ -139,81 +141,88 @@ module Briard
|
|
139
141
|
end
|
140
142
|
|
141
143
|
def citeproc_hsh
|
142
|
-
page = container.to_h[
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
144
|
+
page = if container.to_h['firstPage'].present?
|
145
|
+
[container['firstPage'], container['lastPage']].compact.join('-')
|
146
|
+
end
|
147
|
+
author = if Array.wrap(creators).size == 1 && Array.wrap(creators).first.fetch('name',
|
148
|
+
nil) == ':(unav)'
|
149
|
+
nil
|
150
|
+
else
|
151
|
+
to_citeproc(creators)
|
152
|
+
end
|
153
|
+
|
154
|
+
type = if types['resourceTypeGeneral'] == 'Software' && version_info.present?
|
155
|
+
'book'
|
156
|
+
else
|
157
|
+
types['citeproc']
|
158
|
+
end
|
154
159
|
|
155
160
|
{
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
161
|
+
'type' => type,
|
162
|
+
'id' => normalize_doi(doi),
|
163
|
+
'categories' => Array.wrap(subjects).map do |k|
|
164
|
+
parse_attributes(k, content: 'subject', first: true)
|
165
|
+
end.presence,
|
166
|
+
'language' => language,
|
167
|
+
'author' => author,
|
168
|
+
'contributor' => to_citeproc(contributors),
|
169
|
+
'issued' => get_date_parts(get_date(dates, 'Issued') || publication_year.to_s),
|
170
|
+
'submitted' => Array.wrap(dates).find do |d|
|
171
|
+
d['dateType'] == 'Submitted'
|
172
|
+
end.to_h.fetch('__content__', nil),
|
173
|
+
'abstract' => parse_attributes(descriptions, content: 'description', first: true),
|
174
|
+
'container-title' => container_title,
|
175
|
+
'DOI' => doi,
|
176
|
+
'volume' => container.to_h['volume'],
|
177
|
+
'issue' => container.to_h['issue'],
|
178
|
+
'page' => page,
|
179
|
+
'publisher' => publisher,
|
180
|
+
'title' => parse_attributes(titles, content: 'title', first: true),
|
181
|
+
'URL' => url,
|
182
|
+
'copyright' => Array.wrap(rights_list).map { |l| l['rights'] }.first,
|
183
|
+
'version' => version_info
|
175
184
|
}.compact.symbolize_keys
|
176
185
|
end
|
177
186
|
|
178
187
|
def crosscite_hsh
|
179
188
|
{
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
189
|
+
'id' => normalize_doi(doi),
|
190
|
+
'doi' => doi,
|
191
|
+
'url' => url,
|
192
|
+
'types' => types,
|
193
|
+
'creators' => creators,
|
194
|
+
'titles' => titles,
|
195
|
+
'publisher' => publisher,
|
196
|
+
'container' => container,
|
197
|
+
'subjects' => subjects,
|
198
|
+
'contributors' => contributors,
|
199
|
+
'dates' => dates,
|
200
|
+
'publication_year' => publication_year,
|
201
|
+
'language' => language,
|
202
|
+
'identifiers' => identifiers,
|
203
|
+
'sizes' => sizes,
|
204
|
+
'formats' => formats,
|
205
|
+
'version' => version_info,
|
206
|
+
'rights_list' => rights_list,
|
207
|
+
'descriptions' => descriptions,
|
208
|
+
'geo_locations' => geo_locations,
|
209
|
+
'funding_references' => funding_references,
|
210
|
+
'related_identifiers' => related_identifiers,
|
211
|
+
'related_items' => related_items,
|
212
|
+
'schema_version' => schema_version,
|
213
|
+
'provider_id' => provider_id,
|
214
|
+
'client_id' => client_id,
|
215
|
+
'agency' => agency,
|
216
|
+
'state' => state
|
208
217
|
}.compact
|
209
218
|
end
|
210
219
|
|
211
220
|
def style
|
212
|
-
@style ||=
|
221
|
+
@style ||= 'apa'
|
213
222
|
end
|
214
223
|
|
215
224
|
def locale
|
216
|
-
@locale ||=
|
225
|
+
@locale ||= 'en-US'
|
217
226
|
end
|
218
227
|
end
|
219
228
|
end
|