cff 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba4e9410b991789174bfa5cff1b448600aceb46a
4
- data.tar.gz: ac13ec2b66c63edeaa5eb721b88fec6a4b7fd0da
3
+ metadata.gz: 330c0177c6b7fed7915ddeddbc8ba68a9eb9f9e3
4
+ data.tar.gz: '089cd1ad45d23af25bc1ccbac3b0ffffceedb570'
5
5
  SHA512:
6
- metadata.gz: 807b056534179b4ae578259ef0c8fcc0a6a07d2782b4b134f9a790e99a682a82c9c632008ac8e76afbdd238b060f13c583b30bdb8b1c30c30a6c471230bf9661
7
- data.tar.gz: 2caf814fc16b88fc4d9d70ce664d9a233e258c4460cce6547cca02fe424a5ee4d8d0fcc0bc2309045477901130f0cad97f5fbfce9aaba3b0067ecc4113c1a1b8
6
+ metadata.gz: 290ee6b5066a2f5d016ceff0416faf00f8f12df42c72e62b4642efa2a4d5afa64b32fc1a8e7843d3aec8a4165359445e7a2fd940e523a069a6f6509b181797d3
7
+ data.tar.gz: 0a99851ff3c46441be5fc86d3317bb2bc1828c5f4e5d15dbb8e507541feb9a73e4ff751a7fbd9355a8097ae42db3ac9bfb38428bd28aa5b981b8cb42a74b4cb9
data/CHANGES.md ADDED
@@ -0,0 +1,137 @@
1
+ # Changes log for the Ruby CFF Library
2
+
3
+ ## Version 0.3.0
4
+
5
+ * Update badges for new repo location.
6
+ * Add back the coveralls badge for new repo location.
7
+ * Update gemspec with new repo location.
8
+ * Bump version number for 0.3.0 release.
9
+ * Add a Reference model to represent references.
10
+ * Wire the Reference model into Model and File.
11
+ * Add authors field to Reference.
12
+ * Read the author field properly when parsing a Reference.
13
+ * Remove the ModelPart constructor.
14
+ * Add the DOI badge to the README.
15
+ * Add the simple string fields to Reference.
16
+ * Add format field to Reference.
17
+ * Move duplicated builder methods to Util module.
18
+ * Remove the Util module from the public API.
19
+ * Restrict reference type to the defined set.
20
+ * Add Date type fields to the Reference model.
21
+ * Add contact to the Reference model.
22
+ * Add editors to the Reference model.
23
+ * Add editors-series to the Reference model.
24
+ * Add recipients to the Reference model.
25
+ * Add senders to the Reference model.
26
+ * Add translators to the Reference model.
27
+ * Refactor the Reference#fields method for complexity.
28
+ * Refactor the Model#to_yaml method for complexity.
29
+ * Restrict reference status to the defined set.
30
+ * Add languages to the Reference model.
31
+ * Restrict reference licence to the SPDX Licence List.
32
+ * Rename Util array_to_fields to expand_array_field.
33
+ * Add a Util method expand_field.
34
+ * Correctly read in the actor lists from a file.
35
+ * Update quick start example in the README.
36
+ * Add the integer fields to the Reference model.
37
+ * Refactor Reference#fields to cope with single Entities.
38
+ * Add the singular Entity fields to the Reference model.
39
+ * Add issue-date field to the Reference model.
40
+ * Add the keywords field to the Reference model.
41
+ * Refactor keyword list initialization in Reference.
42
+ * Add patent-states field to the Reference model.
43
+ * Refactor Reference#keywords to be a standard field.
44
+ * Refactor Reference#patent_states to be a field.
45
+ * Extend the tests for Reference after the refactor.
46
+ * Normalize Reference types when they are set.
47
+ * Normalize the Reference status when set.
48
+ * Add a note to the README about versioning.
49
+ * Add a CHANGES file.
50
+
51
+ ## Version 0.2.0
52
+
53
+ * Add a rubygems version badge to the README.
54
+ * Add older rubies to the CI, but allow failures.
55
+ * Add the licence to the gemspec.
56
+ * Rename the ALLOWED_METHODS list to FIELDS.
57
+ * Send missing methods straight to Model, from File.
58
+ * Fix passing through arguments for missing methods (File).
59
+ * Add a Util module with delete_from_hash as first utility.
60
+ * Move method_to_field to the Util module.
61
+ * Refactor for more complete parsing ability.
62
+ * Freeze the allowed fields constant in Model.
63
+ * Change allowed fields to be more flexible
64
+ * Add abstract to Model.
65
+ * Factor out the process of converting array fields to yaml.
66
+ * Fix test for authors that was split incorrectly.
67
+ * Add contact to Model.
68
+ * Add tests to check capitalized fields are rejected.
69
+ * Refactor model building for maintainability.
70
+ * Add commit to the Model.
71
+ * Add doi to the Model.
72
+ * Add keywords to Model.
73
+ * Fix #11: prevent serialization of empty collections.
74
+ * Add license to Model.
75
+ * Refactor testing simple fields.
76
+ * Add license-url to Model.
77
+ * Simplify parsing the keywords in Model.
78
+ * Refactor testing reading complete CFF file.
79
+ * Add repository* to Model.
80
+ * Add url to Model.
81
+ * Fix #12: typo in README example usage.
82
+ * Add to the quick start example in the README.
83
+ * Create a new base class (ModelPart) for parts of the model.
84
+ * Add ModelPart#method_missing.
85
+ * Add affiliation to Person, and tests for it too.
86
+ * Add address to Entity, and tests for it too.
87
+ * Add accessors for required fields on Person, Entity.
88
+ * Add the rest of the optional fields in Person.
89
+ * Add the rest of the simple fields in Entity.
90
+ * Add the date fields in Entity.
91
+ * Test dates in Entity with text inputs.
92
+
93
+ ## Version 0.1.0
94
+
95
+ * Add a code of conduct.
96
+ * Add Travis configuration.
97
+ * Add licence text to all source files.
98
+ * Add a Travis badge to the README.
99
+ * Add a CodeClimate badge to the README.
100
+ * Set up coveralls integration.
101
+ * Add a coveralls badge to the README.
102
+ * Add the current CFF spec version as the default.
103
+ * Add a simple model class.
104
+ * Message doesn't need to be passed to new.
105
+ * Add title to model and wire into default message.
106
+ * Add a method to set the message.
107
+ * Remove the default values on ingestion.
108
+ * Swap requires in main cff file.
109
+ * Only set a default message on construction.
110
+ * Add a File class to read and write CFF files.
111
+ * Switch to using standard accessor for message field.
112
+ * Streamline title output tests.
113
+ * Add a set title method to Model and test it.
114
+ * Turn off line wrapping in Model yaml output.
115
+ * Fix #2. Don't include title in the default message.
116
+ * Test that yaml output doesn't include the header.
117
+ * Write cff from a String or Model.
118
+ * Fix #3. Create a File from either a model or title.
119
+ * When testing file loading, compare to yaml directly.
120
+ * Test the message is loaded correctly into a File.
121
+ * Add version to the Model and File APIs.
122
+ * Add date-released to the Model and File APIs.
123
+ * Fix cff_version test.
124
+ * Move the Model class to a Hash-based implementation.
125
+ * Initialize Model with a title or a Hash.
126
+ * Update the File class to use the new Model class.
127
+ * Use a method whitelist for Model and File.
128
+ * Add a Person model to represent authors.
129
+ * Add an Entity model to represent authors.
130
+
131
+ ## About this file
132
+
133
+ This file is, at least in part, generated by the following command:
134
+
135
+ ```shell
136
+ $ git log --pretty=format:"* %s" --reverse --no-merges <commit-hash>..
137
+ ```
data/README.md CHANGED
@@ -3,10 +3,11 @@
3
3
 
4
4
  A Ruby library for manipulating CITATION.cff files.
5
5
 
6
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1184077.svg)](https://doi.org/10.5281/zenodo.1184077)
6
7
  [![Gem Version](https://badge.fury.io/rb/cff.svg)](https://badge.fury.io/rb/cff)
7
- [![Build Status](https://travis-ci.org/hainesr/ruby-cff.svg?branch=master)](https://travis-ci.org/hainesr/ruby-cff)
8
- [![Maintainability](https://api.codeclimate.com/v1/badges/7eaa3890f17664e10bc6/maintainability)](https://codeclimate.com/github/hainesr/ruby-cff/maintainability)
9
- [![Coverage Status](https://coveralls.io/repos/github/hainesr/ruby-cff/badge.svg)](https://coveralls.io/github/hainesr/ruby-cff)
8
+ [![Build Status](https://travis-ci.org/citation-file-format/ruby-cff.svg?branch=master)](https://travis-ci.org/citation-file-format/ruby-cff)
9
+ [![Maintainability](https://api.codeclimate.com/v1/badges/6bb4c661bfb4971260ba/maintainability)](https://codeclimate.com/github/citation-file-format/ruby-cff/maintainability)
10
+ [![Coverage Status](https://coveralls.io/repos/github/citation-file-format/ruby-cff/badge.svg)](https://coveralls.io/github/citation-file-format/ruby-cff)
10
11
 
11
12
  ### Synopsis
12
13
 
@@ -18,7 +19,7 @@ See the [CITATION.cff documentation](https://citation-file-format.github.io/) fo
18
19
 
19
20
  ```ruby
20
21
  cff = CFF::Model.new("Ruby CFF Library")
21
- cff.version = "0.1.0"
22
+ cff.version = CFF::VERSION
22
23
  cff.date_released = Date.today
23
24
  cff.authors << CFF::Person.new("Robert", "Haines")
24
25
  cff.license = "Apache-2.0"
@@ -34,8 +35,8 @@ Will produce a file that looks something like this:
34
35
  cff-version: 1.0.3
35
36
  message: If you use this software in your work, please cite it using the following metadata
36
37
  title: Ruby CFF Library
37
- version: 0.1.0
38
- date-released: 2018-02-24
38
+ version: 0.3.0
39
+ date-released: 2018-03-04
39
40
  license: Apache-2.0
40
41
  repository-artifact: https://rubygems.org/gems/cff
41
42
  authors:
@@ -47,6 +48,10 @@ keywords:
47
48
  - citation
48
49
  ```
49
50
 
51
+ ### Library versions
52
+
53
+ Until this library reaches version 1.0.0 the API may be subject to breaking changes. When version 1.0.0 is released, then the principles of [semantic versioning](https://semver.org/) will be applied.
54
+
50
55
  ### Licence
51
56
 
52
57
  [Apache 2.0](http://www.apache.org/licenses/). See LICENCE for details.
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ end
26
26
 
27
27
  RDoc::Task.new do |r|
28
28
  r.main = "README.md"
29
- r.rdoc_files.include("README.md", "LICENCE", "lib/**/*.rb")
29
+ r.rdoc_files.include("README.md", "LICENCE", "CHANGES.md", "lib/**/*.rb")
30
30
  r.options << "--markup=markdown"
31
31
  r.options << "--tab-width=2"
32
32
  r.options << "-t Ruby CFF Library version #{::CFF::VERSION}"
data/cff.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.summary = "A Ruby library for manipulating CITATION.cff files."
26
26
  spec.description = "See https://citation-file-format.github.io/ for more info."
27
- spec.homepage = "https://github.com/hainesr/ruby-cff"
27
+ spec.homepage = "https://github.com/citation-file-format/ruby-cff"
28
28
  spec.license = "Apache-2.0"
29
29
 
30
30
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
@@ -36,6 +36,9 @@ Gem::Specification.new do |spec|
36
36
 
37
37
  spec.required_ruby_version = ">= 2.2.0"
38
38
 
39
+ spec.add_runtime_dependency "language_list", "~> 1.2"
40
+ spec.add_runtime_dependency "spdx-licenses", "~> 1.1"
41
+
39
42
  spec.add_development_dependency "bundler", "~> 1.16"
40
43
  spec.add_development_dependency "rake", "~> 10.0"
41
44
  spec.add_development_dependency "minitest", "~> 5.0"
data/lib/cff/entity.rb CHANGED
@@ -43,7 +43,7 @@ module CFF
43
43
  # Create a new Entity with the supplied name.
44
44
  def initialize(param)
45
45
  if Hash === param
46
- super(param)
46
+ @fields = param
47
47
  else
48
48
  @fields = Hash.new('')
49
49
  @fields['name'] = param
@@ -21,10 +21,6 @@ module CFF
21
21
 
22
22
  attr_reader :fields
23
23
 
24
- def initialize(fields)
25
- @fields = fields
26
- end
27
-
28
24
  def method_missing(name, *args) # :nodoc:
29
25
  n = method_to_field(name.id2name)
30
26
  super unless self.class::ALLOWED_FIELDS.include?(n.chomp('='))
data/lib/cff/model.rb CHANGED
@@ -49,6 +49,7 @@ module CFF
49
49
  @authors = []
50
50
  @contact = []
51
51
  @keywords = []
52
+ @references = []
52
53
 
53
54
  if Hash === param
54
55
  build_model(param)
@@ -118,6 +119,19 @@ module CFF
118
119
  @keywords
119
120
  end
120
121
 
122
+ # :call-seq:
123
+ # references -> Array
124
+ #
125
+ # Return the list of references for this citation. To add a reference to the
126
+ # list, use:
127
+ #
128
+ # ```
129
+ # model.references << reference
130
+ # ```
131
+ def references
132
+ @references
133
+ end
134
+
121
135
  # :call-seq:
122
136
  # version = version
123
137
  #
@@ -127,11 +141,6 @@ module CFF
127
141
  end
128
142
 
129
143
  def to_yaml # :nodoc:
130
- fields = @fields.dup
131
- fields['authors'] = array_field_to_yaml(@authors) unless @authors.empty?
132
- fields['contact'] = array_field_to_yaml(@contact) unless @contact.empty?
133
- fields['keywords'] = @keywords.map { |k| k.to_s } unless @keywords.empty?
134
-
135
144
  YAML.dump fields, :line_width => -1, :indentation => 2
136
145
  end
137
146
 
@@ -148,24 +157,29 @@ module CFF
148
157
 
149
158
  private
150
159
 
151
- def build_model(fields)
152
- build_entity_collection(@authors, fields['authors'])
153
- build_entity_collection(@contact, fields['contact'])
154
- @keywords = fields['keywords']
160
+ def fields
161
+ model = @fields.dup
162
+ [
163
+ ['authors', @authors],
164
+ ['contact', @contact],
165
+ ['references', @references]
166
+ ].each do |field, var|
167
+ model[field] = expand_array_field(var) unless var.empty?
168
+ end
169
+ model['keywords'] = @keywords.map { |k| k.to_s } unless @keywords.empty?
155
170
 
156
- @fields = delete_from_hash(fields, 'authors', 'contact', 'keywords')
171
+ model
157
172
  end
158
173
 
159
- def build_entity_collection(field, source)
160
- source.each do |s|
161
- field << (s.has_key?('given-names') ? Person.new(s) : Entity.new(s))
174
+ def build_model(fields)
175
+ build_actor_collection(@authors, fields['authors'])
176
+ build_actor_collection(@contact, fields['contact'])
177
+ @keywords = fields['keywords']
178
+ fields['references'].each do |r|
179
+ @references << Reference.new(r)
162
180
  end
163
- end
164
181
 
165
- def array_field_to_yaml(field)
166
- field.reject do |f|
167
- !f.respond_to?(:fields)
168
- end.map { |f| f.fields }
182
+ @fields = delete_from_hash(fields, 'authors', 'contact', 'keywords', 'references')
169
183
  end
170
184
 
171
185
  end
data/lib/cff/person.rb CHANGED
@@ -43,7 +43,7 @@ module CFF
43
43
  # Create a new Person with the supplied given and family names.
44
44
  def initialize(param, *more)
45
45
  if Hash === param
46
- super(param)
46
+ @fields = param
47
47
  else
48
48
  @fields = Hash.new('')
49
49
  @fields['family-names'] = more[0]
@@ -0,0 +1,502 @@
1
+ # Copyright (c) 2018 Robert Haines.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ #
16
+ module CFF
17
+
18
+ # Reference provides a reference pertaining to the software version or the
19
+ # software itself, e.g., a software paper describing the abstract concepts of
20
+ # the software, a paper describing an algorithm that has been implemented in
21
+ # the software version, etc.
22
+ class Reference < ModelPart
23
+
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',
84
+ 'year-original'
85
+ ].freeze # :nodoc:
86
+
87
+ # The [defined set of reference types](https://citation-file-format.github.io/1.0.3/specifications/#/reference-types).
88
+ 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'
136
+ ].freeze
137
+
138
+ # The [defined set of reference status types](https://citation-file-format.github.io/1.0.3/specifications/#/status-strings).
139
+ REFERENCE_STATUS_TYPES = [
140
+ 'abstract',
141
+ 'advance-online',
142
+ 'in-preparation',
143
+ 'in-press',
144
+ 'pre-print',
145
+ 'submitted'
146
+ ].freeze
147
+
148
+ # :call-seq:
149
+ # new(title, type) -> Reference
150
+ #
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.
152
+ 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)
163
+ else
164
+ @fields = Hash.new('')
165
+ type = more[0].downcase
166
+ @fields['type'] = REFERENCE_TYPES.include?(type) ? type : 'generic'
167
+ @fields['title'] = param
168
+ end
169
+
170
+ [
171
+ 'keywords',
172
+ 'patent-states'
173
+ ].each { |field| @fields[field] = [] if @fields[field].empty? }
174
+ end
175
+
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
+ # :call-seq:
282
+ # add_language language
283
+ #
284
+ # Add a language to this Reference. Input is converted to the ISO 639-3
285
+ # three letter language code, so `GER` becomes `deu`, `french` becomes
286
+ # `fra` and `en` becomes `eng`.
287
+ def add_language(lang)
288
+ @fields['languages'] = [] if @fields['languages'].empty?
289
+ lang = LanguageList::LanguageInfo.find(lang)
290
+ return if lang.nil?
291
+ lang = lang.iso_639_3
292
+ @fields['languages'] << lang unless @fields['languages'].include? lang
293
+ end
294
+
295
+ # :call-seq:
296
+ # reset_languages
297
+ #
298
+ # Reset the list of languages for this Reference to be empty.
299
+ def reset_languages
300
+ @fields.delete('languages')
301
+ end
302
+
303
+ # :call-seq:
304
+ # languages -> Array
305
+ #
306
+ # Return the list of languages associated with this Reference.
307
+ def languages
308
+ @fields['languages'].empty? ? [] : @fields['languages'].dup
309
+ end
310
+
311
+ # :call-seq:
312
+ # license = license
313
+ #
314
+ # Set the license of this Reference. Only licenses that conform to the
315
+ # [SPDX License List](https://spdx.org/licenses/) will be accepted. If you
316
+ # need specify a different license you should set `license-url` with a link
317
+ # to the license instead.
318
+ def license=(lic)
319
+ @fields['license'] = lic unless SpdxLicenses.lookup(lic).nil?
320
+ end
321
+
322
+ # :call-seq:
323
+ # date_accessed = date
324
+ #
325
+ # Set the `date-accessed` field. If a non-Date object is passed in it will
326
+ # be parsed into a Date.
327
+ def date_accessed=(date)
328
+ unless Date === date
329
+ date = Date.parse(date)
330
+ end
331
+
332
+ @fields['date-accessed'] = date
333
+ end
334
+
335
+ # :call-seq:
336
+ # date_downloaded = date
337
+ #
338
+ # Set the `date-downloaded` field. If a non-Date object is passed in it will
339
+ # be parsed into a Date.
340
+ def date_downloaded=(date)
341
+ unless Date === date
342
+ date = Date.parse(date)
343
+ end
344
+
345
+ @fields['date-downloaded'] = date
346
+ end
347
+
348
+ # :call-seq:
349
+ # date_published = date
350
+ #
351
+ # Set the `date-published` field. If a non-Date object is passed in it will
352
+ # be parsed into a Date.
353
+ def date_published=(date)
354
+ unless Date === date
355
+ date = Date.parse(date)
356
+ end
357
+
358
+ @fields['date-published'] = date
359
+ end
360
+
361
+ # :call-seq:
362
+ # date_released = date
363
+ #
364
+ # Set the `date-released` field. If a non-Date object is passed in it will
365
+ # be parsed into a Date.
366
+ def date_released=(date)
367
+ unless Date === date
368
+ date = Date.parse(date)
369
+ end
370
+
371
+ @fields['date-released'] = date
372
+ end
373
+
374
+ # :call-seq:
375
+ # format -> String
376
+ #
377
+ # Returns the format of this Reference.
378
+ def format
379
+ @fields['format']
380
+ end
381
+
382
+ # :call-seq:
383
+ # format = format
384
+ #
385
+ # Sets the format of this Reference.
386
+ def format=(fmt)
387
+ @fields['format'] = fmt
388
+ end
389
+
390
+ # :call-seq:
391
+ # status = status
392
+ #
393
+ # Sets the status of this Reference. The status is restricted to a
394
+ # [defined set of status types](https://citation-file-format.github.io/1.0.3/specifications/#/status-strings).
395
+ def status=(status)
396
+ status.downcase!
397
+ @fields['status'] = status if REFERENCE_STATUS_TYPES.include?(status)
398
+ end
399
+
400
+ # :call-seq:
401
+ # type = type
402
+ #
403
+ # Sets the type of this Reference. The type is restricted to a
404
+ # [defined set of reference types](https://citation-file-format.github.io/1.0.3/specifications/#/reference-types).
405
+ def type=(type)
406
+ type.downcase!
407
+ @fields['type'] = type if REFERENCE_TYPES.include?(type)
408
+ end
409
+
410
+ # Override superclass #fields as References contain model parts too.
411
+ 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
+ [
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?
432
+ end
433
+
434
+ ref
435
+ end
436
+
437
+ private
438
+
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'])
447
+
448
+ @fields = delete_from_hash(fields, 'authors', 'contact', 'editors', 'editors-series', 'recipients', 'senders', 'translators')
449
+ end
450
+
451
+ public
452
+
453
+ # Some documentation of "hidden" methods is provided here, out of the
454
+ # way of the main class code.
455
+
456
+ ##
457
+ # :method: keywords
458
+ # :call-seq:
459
+ # keywords -> Array
460
+ #
461
+ # Return the list of keywords for this reference. To add a keyword to the
462
+ # list, use:
463
+ #
464
+ # ```
465
+ # model.keywords << keyword
466
+ # ```
467
+ #
468
+ # Keywords will be converted to Strings on output.
469
+
470
+ ##
471
+ # :method: keywords=
472
+ # :call-seq:
473
+ # keywords = array_of_keywords -> Array
474
+ #
475
+ # Replace the list of keywords for this reference.
476
+ #
477
+ # Keywords will be converted to Strings on output.
478
+
479
+ ##
480
+ # :method: patent_states
481
+ # :call-seq:
482
+ # patent_states -> Array
483
+ #
484
+ # Return the list of patent states for this reference. To add a patent
485
+ # state to the list, use:
486
+ #
487
+ # ```
488
+ # model.patent_states << patent_state
489
+ # ```
490
+ #
491
+ # Patent states will be converted to Strings on output.
492
+
493
+ ##
494
+ # :method: patent_states=
495
+ # :call-seq:
496
+ # patent_states = array_of_states -> Array
497
+ #
498
+ # Replace the list of patent states for this reference.
499
+ #
500
+ # Patent states will be converted to Strings on output.
501
+ end
502
+ end
data/lib/cff/util.rb CHANGED
@@ -15,27 +15,37 @@
15
15
  #
16
16
  module CFF
17
17
 
18
+ # :stopdoc:
18
19
  # Utility methods useful throughout the rest of the CFF library.
20
+ # This module is not in the public API.
19
21
  module Util
20
22
 
21
- # :call-seq:
22
- # delete_from_hash(hash, keys...) -> Hash
23
- #
24
- # Returns a hash that includes everything but the given keys.
25
23
  def delete_from_hash(hash, *keys)
26
24
  h = hash.dup
27
25
  keys.each { |key| h.delete(key) }
28
26
  h
29
27
  end
30
28
 
31
- # :call-seq:
32
- # method_to_field(name) -> converted name
33
- #
34
- # Return the supplied name with underscores converted to dashes.
35
29
  def method_to_field(name)
36
30
  name.gsub('_', '-')
37
31
  end
38
32
 
39
- end
33
+ def build_actor_collection(field, source)
34
+ source.each do |s|
35
+ field << (s.has_key?('given-names') ? Person.new(s) : Entity.new(s))
36
+ end
37
+ end
38
+
39
+ def expand_field(field)
40
+ field.fields if field.respond_to?(:fields)
41
+ end
40
42
 
43
+ def expand_array_field(field)
44
+ field.reject do |f|
45
+ !f.respond_to?(:fields)
46
+ end.map { |f| f.fields }
47
+ end
48
+
49
+ end
50
+ # :startdoc:
41
51
  end
data/lib/cff/version.rb CHANGED
@@ -15,6 +15,6 @@
15
15
  #
16
16
  module CFF
17
17
  # :nodoc:
18
- VERSION = "0.2.0"
18
+ VERSION = "0.3.0"
19
19
  DEFAULT_SPEC_VERSION = "1.0.3"
20
20
  end
data/lib/cff.rb CHANGED
@@ -14,12 +14,15 @@
14
14
 
15
15
  require "date"
16
16
  require "yaml"
17
+ require "language_list"
18
+ require "spdx-licenses"
17
19
 
18
20
  require "cff/version"
19
21
  require "cff/util"
20
22
  require "cff/model-part"
21
23
  require "cff/person"
22
24
  require "cff/entity"
25
+ require "cff/reference"
23
26
  require "cff/model"
24
27
  require "cff/file"
25
28
 
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Haines
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-25 00:00:00.000000000 Z
11
+ date: 2018-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: language_list
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: spdx-licenses
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: bundler
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -105,6 +133,7 @@ files:
105
133
  - ".ruby-gemset"
106
134
  - ".ruby-version"
107
135
  - ".travis.yml"
136
+ - CHANGES.md
108
137
  - CODE_OF_CONDUCT.md
109
138
  - Gemfile
110
139
  - LICENCE
@@ -119,9 +148,10 @@ files:
119
148
  - lib/cff/model-part.rb
120
149
  - lib/cff/model.rb
121
150
  - lib/cff/person.rb
151
+ - lib/cff/reference.rb
122
152
  - lib/cff/util.rb
123
153
  - lib/cff/version.rb
124
- homepage: https://github.com/hainesr/ruby-cff
154
+ homepage: https://github.com/citation-file-format/ruby-cff
125
155
  licenses:
126
156
  - Apache-2.0
127
157
  metadata: {}