briard 2.4.1 → 2.6.0
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/.github/workflows/codeql-analysis.yml +72 -0
- data/.github/workflows/rubocop.yml +50 -0
- data/.rubocop.yml +144 -620
- data/.rubocop_todo.yml +76 -0
- data/CHANGELOG.md +22 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +43 -6
- data/Rakefile +1 -1
- data/{bolognese.gemspec → briard.gemspec} +46 -38
- 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/turtle_writer_spec.rb +47 -47
- metadata +250 -160
- 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
|