cff 0.3.0 → 0.4.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.
@@ -12,16 +12,21 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- #
15
+ ##
16
16
  module CFF
17
17
 
18
- # :stopdoc:
18
+ # ModelPart is the superclass of anything that makes up part of the CFF Model.
19
+ # This includes Model, Person, Entity and Reference.
20
+ #
21
+ # ModelPart does not provide any methods or fields for the public API.
19
22
  class ModelPart
23
+
24
+ # :stopdoc:
20
25
  include Util
21
26
 
22
27
  attr_reader :fields
23
28
 
24
- def method_missing(name, *args) # :nodoc:
29
+ def method_missing(name, *args)
25
30
  n = method_to_field(name.id2name)
26
31
  super unless self.class::ALLOWED_FIELDS.include?(n.chomp('='))
27
32
 
@@ -32,6 +37,11 @@ module CFF
32
37
  end
33
38
  end
34
39
 
40
+ def respond_to_missing?(name, *)
41
+ n = method_to_field(name.id2name)
42
+ self.class::ALLOWED_FIELDS.include?(n.chomp('=')) || super
43
+ end
44
+
45
+ # :startdoc:
35
46
  end
36
- # :startdoc:
37
47
  end
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- #
15
+ ##
16
16
  module CFF
17
17
 
18
18
  # A Person represents a person in a CITATION.cff file. A Person might have a
@@ -20,21 +20,9 @@ module CFF
20
20
  class Person < ModelPart
21
21
 
22
22
  ALLOWED_FIELDS = [
23
- 'address',
24
- 'affiliation',
25
- 'city',
26
- 'country',
27
- 'email',
28
- 'family-names',
29
- 'fax',
30
- 'given-names',
31
- 'name-particle',
32
- 'name-suffix',
33
- 'orcid',
34
- 'post-code',
35
- 'region',
36
- 'tel',
37
- 'website'
23
+ 'address', 'affiliation', 'city', 'country', 'email', 'family-names',
24
+ 'fax', 'given-names', 'name-particle', 'name-suffix', 'orcid',
25
+ 'post-code', 'region', 'tel', 'website'
38
26
  ].freeze # :nodoc:
39
27
 
40
28
  # :call-seq:
@@ -42,7 +30,7 @@ module CFF
42
30
  #
43
31
  # Create a new Person with the supplied given and family names.
44
32
  def initialize(param, *more)
45
- if Hash === param
33
+ if param.is_a?(Hash)
46
34
  @fields = param
47
35
  else
48
36
  @fields = Hash.new('')
@@ -50,6 +38,5 @@ module CFF
50
38
  @fields['given-names'] = param
51
39
  end
52
40
  end
53
-
54
41
  end
55
42
  end
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- #
15
+ ##
16
16
  module CFF
17
17
 
18
18
  # Reference provides a reference pertaining to the software version or the
@@ -22,262 +22,65 @@ module CFF
22
22
  class Reference < ModelPart
23
23
 
24
24
  ALLOWED_FIELDS = [
25
- 'abbreviation',
26
- 'abstract',
27
- 'collection-doi',
28
- 'collection-title',
29
- 'collection-type',
30
- 'commit',
31
- 'conference',
32
- 'copyright',
33
- 'data-type',
34
- 'database',
35
- 'database-provider',
36
- 'date-accessed',
37
- 'date-downloaded',
38
- 'date-published',
39
- 'date-released',
40
- 'department',
41
- 'doi',
42
- 'edition',
43
- 'end',
44
- 'entry',
45
- 'filename',
46
- 'institution',
47
- 'isbn',
48
- 'issn',
49
- 'issue',
50
- 'issue-date',
51
- 'issue-title',
52
- 'journal',
53
- 'keywords',
54
- 'license',
55
- 'license-url',
56
- 'loc-end',
57
- 'loc-start',
58
- 'location',
59
- 'medium',
60
- 'month',
61
- 'nihmsid',
62
- 'notes',
63
- 'number',
64
- 'number-volumes',
65
- 'pages',
66
- 'patent-states',
67
- 'pmcid',
68
- 'publisher',
69
- 'repository',
70
- 'repository-code',
71
- 'repository-artifact',
72
- 'scope',
73
- 'section',
74
- 'start',
75
- 'status',
76
- 'thesis-type',
77
- 'title',
78
- 'type',
79
- 'url',
80
- 'version',
81
- 'volume',
82
- 'volume-title',
83
- 'year',
25
+ 'abbreviation', 'abstract', 'authors', 'collection-doi',
26
+ 'collection-title', 'collection-type', 'commit', 'conference', 'contact',
27
+ 'copyright', 'data-type', 'database', 'database-provider',
28
+ 'date-accessed', 'date-downloaded', 'date-published', 'date-released',
29
+ 'department', 'doi', 'edition', 'editors', 'editors-series', 'end',
30
+ 'entry', 'filename', 'institution', 'isbn', 'issn', 'issue', 'issue-date',
31
+ 'issue-title', 'journal', 'keywords', 'license', 'license-url', 'loc-end',
32
+ 'loc-start', 'location', 'medium', 'month', 'nihmsid', 'notes', 'number',
33
+ 'number-volumes', 'pages', 'patent-states', 'pmcid', 'publisher',
34
+ 'recipients', 'repository', 'repository-code', 'repository-artifact',
35
+ 'scope', 'section', 'senders', 'start', 'status', 'thesis-type', 'title',
36
+ 'translators', 'type', 'url', 'version', 'volume', 'volume-title', 'year',
84
37
  'year-original'
85
38
  ].freeze # :nodoc:
86
39
 
87
40
  # The [defined set of reference types](https://citation-file-format.github.io/1.0.3/specifications/#/reference-types).
88
41
  REFERENCE_TYPES = [
89
- 'art',
90
- 'article',
91
- 'audiovisual',
92
- 'bill',
93
- 'blog',
94
- 'book',
95
- 'catalogue',
96
- 'conference',
97
- 'conference-paper',
98
- 'data',
99
- 'database',
100
- 'dictionary',
101
- 'edited-work',
102
- 'encyclopedia',
103
- 'film-broadcast',
104
- 'generic',
105
- 'government-document',
106
- 'grant',
107
- 'hearing',
108
- 'historical-work',
109
- 'legal-case',
110
- 'legal-rule',
111
- 'magazine-article',
112
- 'manual',
113
- 'map',
114
- 'multimedia',
115
- 'music',
116
- 'newspaper-article',
117
- 'pamphlet',
118
- 'patent',
119
- 'personal-communication',
120
- 'proceedings',
121
- 'report',
122
- 'serial',
123
- 'slides',
124
- 'software',
125
- 'software-code',
126
- 'software-container',
127
- 'software-executable',
128
- 'software-virtual-machine',
129
- 'sound-recording',
130
- 'standard',
131
- 'statute',
132
- 'thesis',
133
- 'unpublished',
134
- 'video',
135
- 'website'
42
+ 'art', 'article', 'audiovisual', 'bill', 'blog', 'book', 'catalogue',
43
+ 'conference', 'conference-paper', 'data', 'database', 'dictionary',
44
+ 'edited-work', 'encyclopedia', 'film-broadcast', 'generic',
45
+ 'government-document', 'grant', 'hearing', 'historical-work',
46
+ 'legal-case', 'legal-rule', 'magazine-article', 'manual', 'map',
47
+ 'multimedia', 'music', 'newspaper-article', 'pamphlet', 'patent',
48
+ 'personal-communication', 'proceedings', 'report', 'serial', 'slides',
49
+ 'software', 'software-code', 'software-container', 'software-executable',
50
+ 'software-virtual-machine', 'sound-recording', 'standard', 'statute',
51
+ 'thesis', 'unpublished', 'video', 'website'
136
52
  ].freeze
137
53
 
138
54
  # The [defined set of reference status types](https://citation-file-format.github.io/1.0.3/specifications/#/status-strings).
139
55
  REFERENCE_STATUS_TYPES = [
140
- 'abstract',
141
- 'advance-online',
142
- 'in-preparation',
143
- 'in-press',
144
- 'pre-print',
145
- 'submitted'
56
+ 'abstract', 'advance-online', 'in-preparation', 'in-press',
57
+ 'pre-print', 'submitted'
146
58
  ].freeze
147
59
 
148
60
  # :call-seq:
61
+ # new(title) -> Reference
149
62
  # new(title, type) -> Reference
150
63
  #
151
- # Create a new Reference with the supplied title and type. If type is not one of the [defined set of reference types](https://citation-file-format.github.io/1.0.3/specifications/#/reference-types), 'generic' will be used by default.
64
+ # Create a new Reference with the supplied title and, optionally, type.
65
+ # If type is not given, or is not one of the
66
+ # [defined set of reference types](https://citation-file-format.github.io/1.0.3/specifications/#/reference-types),
67
+ # 'generic' will be used by default.
152
68
  def initialize(param, *more)
153
- @authors = []
154
- @contact = []
155
- @editors = []
156
- @editors_series = []
157
- @recipients = []
158
- @senders = []
159
- @translators = []
160
-
161
- if Hash === param
162
- build_model(param)
69
+ if param.is_a?(Hash)
70
+ @fields = build_model(param)
163
71
  else
164
72
  @fields = Hash.new('')
165
- type = more[0].downcase
73
+ type = more[0] &&= more[0].downcase
166
74
  @fields['type'] = REFERENCE_TYPES.include?(type) ? type : 'generic'
167
75
  @fields['title'] = param
168
76
  end
169
77
 
170
78
  [
171
- 'keywords',
172
- 'patent-states'
79
+ 'authors', 'contact', 'editors', 'editors-series', 'keywords',
80
+ 'patent-states', 'recipients', 'senders', 'translators'
173
81
  ].each { |field| @fields[field] = [] if @fields[field].empty? }
174
82
  end
175
83
 
176
- # :call-seq:
177
- # authors -> Array
178
- #
179
- # Return the list of authors for this Reference. To add an author to the
180
- # list, use:
181
- #
182
- # ```
183
- # reference.authors << author
184
- # ```
185
- #
186
- # Authors can be a Person or Entity.
187
- def authors
188
- @authors
189
- end
190
-
191
- # :call-seq:
192
- # contact -> Array
193
- #
194
- # Return the list of contacts for this Reference. To add a contact to the
195
- # list, use:
196
- #
197
- # ```
198
- # reference.contact << contact
199
- # ```
200
- #
201
- # Contacts can be a Person or Entity.
202
- def contact
203
- @contact
204
- end
205
-
206
- # :call-seq:
207
- # editors -> Array
208
- #
209
- # Return the list of editors for this Reference. To add an editor to the
210
- # list, use:
211
- #
212
- # ```
213
- # reference.editors << editor
214
- # ```
215
- #
216
- # An editor can be a Person or Entity.
217
- def editors
218
- @editors
219
- end
220
-
221
- # :call-seq:
222
- # editors_series -> Array
223
- #
224
- # Return the list of series editors for this Reference. To add a series
225
- # editor to the list, use:
226
- #
227
- # ```
228
- # reference.editors_series << editor
229
- # ```
230
- #
231
- # An editor can be a Person or Entity.
232
- def editors_series
233
- @editors_series
234
- end
235
-
236
- # :call-seq:
237
- # recipients -> Array
238
- #
239
- # Return the list of recipients for this Reference. To add a recipient
240
- # to the list, use:
241
- #
242
- # ```
243
- # reference.recipients << recipient
244
- # ```
245
- #
246
- # Recipients can be a Person or Entity.
247
- def recipients
248
- @recipients
249
- end
250
-
251
- # :call-seq:
252
- # senders -> Array
253
- #
254
- # Return the list of senders for this Reference. To add a sender to the
255
- # list, use:
256
- #
257
- # ```
258
- # reference.senders << sender
259
- # ```
260
- #
261
- # Senders can be a Person or Entity.
262
- def senders
263
- @senders
264
- end
265
-
266
- # :call-seq:
267
- # translators -> Array
268
- #
269
- # Return the list of translators for this Reference. To add a translator
270
- # to the list, use:
271
- #
272
- # ```
273
- # reference.translators << translator
274
- # ```
275
- #
276
- # Translators can be a Person or Entity.
277
- def translators
278
- @translators
279
- end
280
-
281
84
  # :call-seq:
282
85
  # add_language language
283
86
  #
@@ -325,9 +128,7 @@ module CFF
325
128
  # Set the `date-accessed` field. If a non-Date object is passed in it will
326
129
  # be parsed into a Date.
327
130
  def date_accessed=(date)
328
- unless Date === date
329
- date = Date.parse(date)
330
- end
131
+ date = Date.parse(date) unless date.is_a?(Date)
331
132
 
332
133
  @fields['date-accessed'] = date
333
134
  end
@@ -338,9 +139,7 @@ module CFF
338
139
  # Set the `date-downloaded` field. If a non-Date object is passed in it will
339
140
  # be parsed into a Date.
340
141
  def date_downloaded=(date)
341
- unless Date === date
342
- date = Date.parse(date)
343
- end
142
+ date = Date.parse(date) unless date.is_a?(Date)
344
143
 
345
144
  @fields['date-downloaded'] = date
346
145
  end
@@ -351,9 +150,7 @@ module CFF
351
150
  # Set the `date-published` field. If a non-Date object is passed in it will
352
151
  # be parsed into a Date.
353
152
  def date_published=(date)
354
- unless Date === date
355
- date = Date.parse(date)
356
- end
153
+ date = Date.parse(date) unless date.is_a?(Date)
357
154
 
358
155
  @fields['date-published'] = date
359
156
  end
@@ -364,9 +161,7 @@ module CFF
364
161
  # Set the `date-released` field. If a non-Date object is passed in it will
365
162
  # be parsed into a Date.
366
163
  def date_released=(date)
367
- unless Date === date
368
- date = Date.parse(date)
369
- end
164
+ date = Date.parse(date) unless date.is_a?(Date)
370
165
 
371
166
  @fields['date-released'] = date
372
167
  end
@@ -409,43 +204,27 @@ module CFF
409
204
 
410
205
  # Override superclass #fields as References contain model parts too.
411
206
  def fields # :nodoc:
412
- ref = {}
413
-
414
- @fields.each do |field, value|
415
- if value.respond_to?(:map)
416
- ref[field] = value.map { |v| v.to_s } unless value.empty?
417
- else
418
- ref[field] = value.respond_to?(:fields) ? value.fields : value
419
- end
420
- end
421
-
422
207
  [
423
- ['authors', @authors],
424
- ['contact', @contact],
425
- ['editors', @editors],
426
- ['editors-series', @editors_series],
427
- ['recipients', @recipients],
428
- ['senders', @senders],
429
- ['translators', @translators]
430
- ].each do |field, var|
431
- ref[field] = expand_array_field(var) unless var.empty?
208
+ 'authors', 'contact', 'editors', 'editors-series', 'recipients',
209
+ 'senders', 'translators'
210
+ ].each do |field|
211
+ normalize_modelpart_array!(@fields[field])
432
212
  end
433
213
 
434
- ref
214
+ fields_to_hash(@fields)
435
215
  end
436
216
 
437
217
  private
438
218
 
439
- def build_model(fields)
440
- build_actor_collection(@authors, fields['authors'])
441
- build_actor_collection(@contact, fields['contact'])
442
- build_actor_collection(@editors, fields['editors'])
443
- build_actor_collection(@editors_series, fields['editors-series'])
444
- build_actor_collection(@recipients, fields['recipients'])
445
- build_actor_collection(@senders, fields['senders'])
446
- build_actor_collection(@translators, fields['translators'])
219
+ def build_model(fields) # :nodoc:
220
+ [
221
+ 'authors', 'contact', 'editors', 'editors-series', 'recipients',
222
+ 'senders', 'translators'
223
+ ].each do |field|
224
+ build_actor_collection!(fields[field])
225
+ end
447
226
 
448
- @fields = delete_from_hash(fields, 'authors', 'contact', 'editors', 'editors-series', 'recipients', 'senders', 'translators')
227
+ fields
449
228
  end
450
229
 
451
230
  public
@@ -453,6 +232,98 @@ module CFF
453
232
  # Some documentation of "hidden" methods is provided here, out of the
454
233
  # way of the main class code.
455
234
 
235
+ ##
236
+ # :method: authors
237
+ # :call-seq:
238
+ # authors -> Array
239
+ #
240
+ # Return the list of authors for this Reference. To add an author to the
241
+ # list, use:
242
+ #
243
+ # ```
244
+ # reference.authors << author
245
+ # ```
246
+ #
247
+ # Authors can be a Person or Entity.
248
+
249
+ ##
250
+ # :method: authors=
251
+ # :call-seq:
252
+ # authors = array_of_authors -> Array
253
+ #
254
+ # Replace the list of authors for this reference.
255
+ #
256
+ # Authors can be a Person or Entity.
257
+
258
+ ##
259
+ # :method: contact
260
+ # :call-seq:
261
+ # contact -> Array
262
+ #
263
+ # Return the list of contacts for this Reference. To add a contact to the
264
+ # list, use:
265
+ #
266
+ # ```
267
+ # reference.contact << contact
268
+ # ```
269
+ #
270
+ # Contacts can be a Person or Entity.
271
+
272
+ ##
273
+ # :method: contact=
274
+ # :call-seq:
275
+ # contact = array_of_contacts -> Array
276
+ #
277
+ # Replace the list of contacts for this reference.
278
+ #
279
+ # Contacts can be a Person or Entity.
280
+
281
+ ##
282
+ # :method: editors
283
+ # :call-seq:
284
+ # editors -> Array
285
+ #
286
+ # Return the list of editors for this Reference. To add an editor to the
287
+ # list, use:
288
+ #
289
+ # ```
290
+ # reference.editors << editor
291
+ # ```
292
+ #
293
+ # An editor can be a Person or Entity.
294
+
295
+ ##
296
+ # :method: editors=
297
+ # :call-seq:
298
+ # editors = array_of_editors -> Array
299
+ #
300
+ # Replace the list of editors for this reference.
301
+ #
302
+ # Editors can be a Person or Entity.
303
+
304
+ ##
305
+ # :method: editors_series
306
+ # :call-seq:
307
+ # editors_series -> Array
308
+ #
309
+ # Return the list of series editors for this Reference. To add a series
310
+ # editor to the list, use:
311
+ #
312
+ # ```
313
+ # reference.editors_series << editor
314
+ # ```
315
+ #
316
+ # An editor can be a Person or Entity.
317
+
318
+ ##
319
+ # :method: editors_series=
320
+ # :call-seq:
321
+ # editors_series = array_of_series_editors -> Array
322
+ #
323
+ # Replace the list of series editors for this reference.
324
+ #
325
+ # Series editors can be a Person or Entity.
326
+
456
327
  ##
457
328
  # :method: keywords
458
329
  # :call-seq:
@@ -498,5 +369,74 @@ module CFF
498
369
  # Replace the list of patent states for this reference.
499
370
  #
500
371
  # Patent states will be converted to Strings on output.
372
+
373
+ ##
374
+ # :method: recipients
375
+ # :call-seq:
376
+ # recipients -> Array
377
+ #
378
+ # Return the list of recipients for this Reference. To add a recipient
379
+ # to the list, use:
380
+ #
381
+ # ```
382
+ # reference.recipients << recipient
383
+ # ```
384
+ #
385
+ # Recipients can be a Person or Entity.
386
+
387
+ ##
388
+ # :method: recipients=
389
+ # :call-seq:
390
+ # recipients = array_of_recipients -> Array
391
+ #
392
+ # Replace the list of recipients for this reference.
393
+ #
394
+ # Recipients can be a Person or Entity.
395
+
396
+ ##
397
+ # :method: senders
398
+ # :call-seq:
399
+ # senders -> Array
400
+ #
401
+ # Return the list of senders for this Reference. To add a sender to the
402
+ # list, use:
403
+ #
404
+ # ```
405
+ # reference.senders << sender
406
+ # ```
407
+ #
408
+ # Senders can be a Person or Entity.
409
+
410
+ ##
411
+ # :method: senders=
412
+ # :call-seq:
413
+ # senders = array_of_senders -> Array
414
+ #
415
+ # Replace the list of senders for this reference.
416
+ #
417
+ # Senders can be a Person or Entity.
418
+
419
+ ##
420
+ # :method: translators
421
+ # :call-seq:
422
+ # translators -> Array
423
+ #
424
+ # Return the list of translators for this Reference. To add a translator
425
+ # to the list, use:
426
+ #
427
+ # ```
428
+ # reference.translators << translator
429
+ # ```
430
+ #
431
+ # Translators can be a Person or Entity.
432
+
433
+ ##
434
+ # :method: translators=
435
+ # :call-seq:
436
+ # translators = array_of_translators -> Array
437
+ #
438
+ # Replace the list of translators for this reference.
439
+ #
440
+ # Translators can be a Person or Entity.
501
441
  end
502
442
  end