cff 0.8.0 → 1.0.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/CHANGES.md +91 -0
- data/CITATION.cff +62 -5
- data/CONTRIBUTING.md +71 -0
- data/LICENCE +1 -1
- data/README.md +57 -17
- data/Rakefile +9 -8
- data/cff.gemspec +12 -11
- data/lib/cff/citable.rb +72 -0
- data/lib/cff/entity.rb +11 -31
- data/lib/cff/errors.rb +14 -9
- data/lib/cff/file.rb +101 -31
- data/lib/cff/formatters/all.rb +26 -0
- data/lib/cff/formatters/apalike.rb +145 -0
- data/lib/cff/formatters/bibtex.rb +205 -0
- data/lib/cff/formatters/formatter.rb +98 -0
- data/lib/cff/formatters.rb +61 -0
- data/lib/cff/identifier.rb +14 -8
- data/lib/cff/{model.rb → index.rb} +73 -66
- data/lib/cff/licensable.rb +4 -5
- data/lib/cff/model_part.rb +46 -10
- data/lib/cff/person.rb +8 -10
- data/lib/cff/reference.rb +76 -112
- data/lib/cff/schema.rb +23 -0
- data/lib/{schema → cff/schemas}/1.2.0.json +1 -1
- data/lib/cff/util.rb +63 -6
- data/lib/cff/validatable.rb +13 -13
- data/lib/cff/version.rb +2 -2
- data/lib/cff.rb +4 -27
- metadata +37 -31
- data/lib/cff/formatter/apa_formatter.rb +0 -77
- data/lib/cff/formatter/bibtex_formatter.rb +0 -122
- data/lib/cff/formatter/formatter.rb +0 -63
data/lib/cff/licensable.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2018-
|
3
|
+
# Copyright (c) 2018-2022 The Ruby Citation File Format Developers.
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
@@ -14,14 +14,13 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require_relative 'schema'
|
18
|
+
|
17
19
|
##
|
18
20
|
module CFF
|
19
|
-
|
20
21
|
# Functionality to add licence(s) to parts of the CFF model.
|
21
22
|
module Licensable
|
22
|
-
|
23
|
-
# :nodoc:
|
24
|
-
LICENSES = SCHEMA_FILE['definitions']['license-enum']['enum'].dup.freeze
|
23
|
+
LICENSES = SCHEMA_FILE['definitions']['license-enum']['enum'].dup.freeze # :nodoc:
|
25
24
|
|
26
25
|
# :call-seq:
|
27
26
|
# license = license
|
data/lib/cff/model_part.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2018-
|
3
|
+
# Copyright (c) 2018-2022 The Ruby Citation File Format Developers.
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
@@ -14,18 +14,16 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require 'date'
|
18
|
+
|
17
19
|
##
|
18
20
|
module CFF
|
19
|
-
|
20
|
-
#
|
21
|
-
# This includes Model, Person, Entity and Reference.
|
21
|
+
# ModelPart is the superclass of anything that makes up part of the CFF Index.
|
22
|
+
# This includes Index, Person, Entity and Reference.
|
22
23
|
#
|
23
|
-
# ModelPart
|
24
|
+
# ModelPart provides only one method for the public API: `empty?`.
|
24
25
|
class ModelPart
|
25
|
-
|
26
26
|
# :stopdoc:
|
27
|
-
include Util
|
28
|
-
|
29
27
|
attr_reader :fields
|
30
28
|
|
31
29
|
def method_missing(name, *args)
|
@@ -35,7 +33,7 @@ module CFF
|
|
35
33
|
if n.end_with?('=')
|
36
34
|
@fields[n.chomp('=')] = args[0] || ''
|
37
35
|
else
|
38
|
-
@fields[n]
|
36
|
+
@fields[n].nil? ? '' : @fields[n]
|
39
37
|
end
|
40
38
|
end
|
41
39
|
|
@@ -43,7 +41,45 @@ module CFF
|
|
43
41
|
n = method_to_field(name.id2name)
|
44
42
|
self.class::ALLOWED_FIELDS.include?(n.chomp('=')) || super
|
45
43
|
end
|
46
|
-
|
47
44
|
# :startdoc:
|
45
|
+
|
46
|
+
# :call-seq:
|
47
|
+
# empty? -> false
|
48
|
+
#
|
49
|
+
# Define `empty?` for CFF classes so that they can be tested in the
|
50
|
+
# same way as strings and arrays.
|
51
|
+
#
|
52
|
+
# This always returns `false` because CFF classes always return something
|
53
|
+
# from all of their methods.
|
54
|
+
def empty?
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.attr_date(*symbols) # :nodoc:
|
59
|
+
symbols.each do |symbol|
|
60
|
+
field = symbol.to_s.tr('_', '-')
|
61
|
+
|
62
|
+
class_eval(
|
63
|
+
# def date_end=(date)
|
64
|
+
# date = (date.is_a?(Date) ? date.dup : Date.parse(date))
|
65
|
+
#
|
66
|
+
# @fields['date-end'] = date
|
67
|
+
# end
|
68
|
+
<<-END_SETTER, __FILE__, __LINE__ + 1
|
69
|
+
def #{symbol}=(date)
|
70
|
+
date = (date.is_a?(Date) ? date.dup : Date.parse(date))
|
71
|
+
|
72
|
+
@fields['#{field}'] = date
|
73
|
+
end
|
74
|
+
END_SETTER
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def method_to_field(name)
|
82
|
+
name.tr('_', '-')
|
83
|
+
end
|
48
84
|
end
|
49
85
|
end
|
data/lib/cff/person.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2018-
|
3
|
+
# Copyright (c) 2018-2022 The Ruby Citation File Format Developers.
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
@@ -14,9 +14,11 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require_relative 'model_part'
|
18
|
+
require_relative 'schema'
|
19
|
+
|
17
20
|
##
|
18
21
|
module CFF
|
19
|
-
|
20
22
|
# A Person represents a person in a CITATION.cff file. A Person might have a
|
21
23
|
# number of roles, such as author, contact, editor, etc.
|
22
24
|
#
|
@@ -43,12 +45,7 @@ module CFF
|
|
43
45
|
# * `tel`
|
44
46
|
# * `website`
|
45
47
|
class Person < ModelPart
|
46
|
-
|
47
|
-
ALLOWED_FIELDS = [
|
48
|
-
'address', 'affiliation', 'alias', 'city', 'country', 'email',
|
49
|
-
'family-names', 'fax', 'given-names', 'name-particle', 'name-suffix',
|
50
|
-
'orcid', 'post-code', 'region', 'tel', 'website'
|
51
|
-
].freeze # :nodoc:
|
48
|
+
ALLOWED_FIELDS = SCHEMA_FILE['definitions']['person']['properties'].keys.freeze # :nodoc:
|
52
49
|
|
53
50
|
# :call-seq:
|
54
51
|
# new -> Person
|
@@ -58,11 +55,12 @@ module CFF
|
|
58
55
|
#
|
59
56
|
# Create a new Person with the optionally supplied given and family names.
|
60
57
|
def initialize(param = nil, *more)
|
58
|
+
super()
|
59
|
+
|
61
60
|
if param.is_a?(Hash)
|
62
61
|
@fields = param
|
63
|
-
@fields.default = ''
|
64
62
|
else
|
65
|
-
@fields =
|
63
|
+
@fields = {}
|
66
64
|
|
67
65
|
unless param.nil?
|
68
66
|
@fields['family-names'] = more[0]
|
data/lib/cff/reference.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2018-
|
3
|
+
# Copyright (c) 2018-2022 The Ruby Citation File Format Developers.
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
@@ -14,9 +14,13 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require_relative 'licensable'
|
18
|
+
require_relative 'model_part'
|
19
|
+
require_relative 'schema'
|
20
|
+
require_relative 'util'
|
21
|
+
|
17
22
|
##
|
18
23
|
module CFF
|
19
|
-
|
20
24
|
# Reference provides a reference pertaining to the software version or the
|
21
25
|
# software itself, e.g., a software paper describing the abstract concepts of
|
22
26
|
# the software, a paper describing an algorithm that has been implemented in
|
@@ -74,12 +78,13 @@ module CFF
|
|
74
78
|
# * `pmcid`
|
75
79
|
# * `publisher`
|
76
80
|
# * `repository`
|
77
|
-
# * `repository_code`
|
78
81
|
# * `repository_artifact`
|
82
|
+
# * `repository_code`
|
79
83
|
# * `scope`
|
80
84
|
# * `section`
|
81
85
|
# * `start`
|
82
86
|
# * `status` - *Note:* see documentation for `status =` below
|
87
|
+
# * `term`
|
83
88
|
# * `thesis_type`
|
84
89
|
# * `title`
|
85
90
|
# * `type` - *Note:* see documentation for `type =` below
|
@@ -90,44 +95,24 @@ module CFF
|
|
90
95
|
# * `year`
|
91
96
|
# * `year_original`
|
92
97
|
class Reference < ModelPart
|
93
|
-
|
94
98
|
include Licensable
|
95
99
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
'
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
'
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
'
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
# The [defined set of reference types](https://github.com/citation-file-format/citation-file-format#reference-types).
|
113
|
-
REFERENCE_TYPES = [
|
114
|
-
'art', 'article', 'audiovisual', 'bill', 'blog', 'book', 'catalogue',
|
115
|
-
'conference', 'conference-paper', 'data', 'database', 'dictionary',
|
116
|
-
'edited-work', 'encyclopedia', 'film-broadcast', 'generic',
|
117
|
-
'government-document', 'grant', 'hearing', 'historical-work',
|
118
|
-
'legal-case', 'legal-rule', 'magazine-article', 'manual', 'map',
|
119
|
-
'multimedia', 'music', 'newspaper-article', 'pamphlet', 'patent',
|
120
|
-
'personal-communication', 'proceedings', 'report', 'serial', 'slides',
|
121
|
-
'software', 'software-code', 'software-container', 'software-executable',
|
122
|
-
'software-virtual-machine', 'sound-recording', 'standard', 'statute',
|
123
|
-
'thesis', 'unpublished', 'video', 'website'
|
124
|
-
].freeze
|
125
|
-
|
126
|
-
# The [defined set of reference status types](https://github.com/citation-file-format/citation-file-format#status-strings).
|
127
|
-
REFERENCE_STATUS_TYPES = [
|
128
|
-
'abstract', 'advance-online', 'in-preparation', 'in-press',
|
129
|
-
'pre-print', 'submitted'
|
130
|
-
].freeze
|
100
|
+
# This list does not include `format` for reasons explained below, where
|
101
|
+
# the `format` method is defined!
|
102
|
+
ALLOWED_FIELDS = (
|
103
|
+
SCHEMA_FILE['definitions']['reference']['properties'].keys - %w[format languages]
|
104
|
+
).freeze # :nodoc:
|
105
|
+
|
106
|
+
# The [defined set of reference types](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreferencetype).
|
107
|
+
REFERENCE_TYPES =
|
108
|
+
SCHEMA_FILE['definitions']['reference']['properties']['type']['enum'].dup.freeze
|
109
|
+
|
110
|
+
# The [defined set of reference status types](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreferencestatus).
|
111
|
+
REFERENCE_STATUS_TYPES =
|
112
|
+
SCHEMA_FILE['definitions']['reference']['properties']['status']['enum'].dup.freeze
|
113
|
+
|
114
|
+
attr_date :date_accessed, :date_downloaded, :date_published,
|
115
|
+
:date_released, :issue_date
|
131
116
|
|
132
117
|
# :call-seq:
|
133
118
|
# new(title) -> Reference
|
@@ -137,29 +122,53 @@ module CFF
|
|
137
122
|
#
|
138
123
|
# Create a new Reference with the supplied title and, optionally, type.
|
139
124
|
# If type is not given, or is not one of the
|
140
|
-
# [defined set of reference types](https://github.com/citation-file-format/citation-file-format#
|
125
|
+
# [defined set of reference types](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreferencetype),
|
141
126
|
# 'generic' will be used by default.
|
142
|
-
def initialize(param, *more) # rubocop:disable Metrics
|
127
|
+
def initialize(param, *more) # rubocop:disable Metrics
|
128
|
+
super()
|
129
|
+
|
143
130
|
if param.is_a?(Hash)
|
144
131
|
@fields = build_model(param)
|
145
|
-
@fields.default = ''
|
146
132
|
else
|
147
|
-
@fields =
|
133
|
+
@fields = {}
|
148
134
|
type = more[0] &&= more[0].downcase
|
149
135
|
@fields['type'] = REFERENCE_TYPES.include?(type) ? type : 'generic'
|
150
136
|
@fields['title'] = param
|
151
137
|
end
|
152
138
|
|
153
|
-
[
|
154
|
-
|
155
|
-
|
139
|
+
%w[
|
140
|
+
authors contact editors editors-series identifiers
|
141
|
+
keywords patent-states recipients senders translators
|
156
142
|
].each do |field|
|
157
|
-
@fields[field] = [] if @fields[field].empty?
|
143
|
+
@fields[field] = [] if @fields[field].nil? || @fields[field].empty?
|
158
144
|
end
|
159
145
|
|
160
146
|
yield self if block_given?
|
161
147
|
end
|
162
148
|
|
149
|
+
# :call-seq:
|
150
|
+
# from_cff(File, type: 'software') -> Reference
|
151
|
+
# from_cff(Index, type: 'software') -> Reference
|
152
|
+
#
|
153
|
+
# Create a Reference from another CFF File or Index. This is useful for
|
154
|
+
# easily adding a reference to something with its own CITATION.cff file
|
155
|
+
# already.
|
156
|
+
#
|
157
|
+
# This method assumes that the type of the Reference should be `software`,
|
158
|
+
# but this can be overridden with the `type` parameter.
|
159
|
+
def self.from_cff(model, type: 'software')
|
160
|
+
new(model.title, type) do |ref|
|
161
|
+
%w[
|
162
|
+
abstract authors contact commit date_released doi
|
163
|
+
identifiers keywords license license_url repository
|
164
|
+
repository_artifact repository_code url version
|
165
|
+
].each do |field|
|
166
|
+
value = model.send(field)
|
167
|
+
ref.send("#{field}=", value.dup) unless value == ''
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
163
172
|
# :call-seq:
|
164
173
|
# add_language language
|
165
174
|
#
|
@@ -167,12 +176,13 @@ module CFF
|
|
167
176
|
# three letter language code, so `GER` becomes `deu`, `french` becomes
|
168
177
|
# `fra` and `en` becomes `eng`.
|
169
178
|
def add_language(lang)
|
170
|
-
|
179
|
+
require 'language_list'
|
180
|
+
@fields['languages'] = [] if @fields['languages'].nil? || @fields['languages'].empty?
|
171
181
|
lang = LanguageList::LanguageInfo.find(lang)
|
172
182
|
return if lang.nil?
|
173
183
|
|
174
184
|
lang = lang.iso_639_3
|
175
|
-
@fields['languages'] << lang unless @fields['languages'].include?
|
185
|
+
@fields['languages'] << lang unless @fields['languages'].include?(lang)
|
176
186
|
end
|
177
187
|
|
178
188
|
# :call-seq:
|
@@ -188,51 +198,7 @@ module CFF
|
|
188
198
|
#
|
189
199
|
# Return the list of languages associated with this Reference.
|
190
200
|
def languages
|
191
|
-
@fields['languages'].empty? ? [] : @fields['languages'].dup
|
192
|
-
end
|
193
|
-
|
194
|
-
# :call-seq:
|
195
|
-
# date_accessed = date
|
196
|
-
#
|
197
|
-
# Set the `date-accessed` field. If a non-Date object is passed in it will
|
198
|
-
# be parsed into a Date.
|
199
|
-
def date_accessed=(date)
|
200
|
-
date = Date.parse(date) unless date.is_a?(Date)
|
201
|
-
|
202
|
-
@fields['date-accessed'] = date
|
203
|
-
end
|
204
|
-
|
205
|
-
# :call-seq:
|
206
|
-
# date_downloaded = date
|
207
|
-
#
|
208
|
-
# Set the `date-downloaded` field. If a non-Date object is passed in it will
|
209
|
-
# be parsed into a Date.
|
210
|
-
def date_downloaded=(date)
|
211
|
-
date = Date.parse(date) unless date.is_a?(Date)
|
212
|
-
|
213
|
-
@fields['date-downloaded'] = date
|
214
|
-
end
|
215
|
-
|
216
|
-
# :call-seq:
|
217
|
-
# date_published = date
|
218
|
-
#
|
219
|
-
# Set the `date-published` field. If a non-Date object is passed in it will
|
220
|
-
# be parsed into a Date.
|
221
|
-
def date_published=(date)
|
222
|
-
date = Date.parse(date) unless date.is_a?(Date)
|
223
|
-
|
224
|
-
@fields['date-published'] = date
|
225
|
-
end
|
226
|
-
|
227
|
-
# :call-seq:
|
228
|
-
# date_released = date
|
229
|
-
#
|
230
|
-
# Set the `date-released` field. If a non-Date object is passed in it will
|
231
|
-
# be parsed into a Date.
|
232
|
-
def date_released=(date)
|
233
|
-
date = Date.parse(date) unless date.is_a?(Date)
|
234
|
-
|
235
|
-
@fields['date-released'] = date
|
201
|
+
@fields['languages'].nil? || @fields['languages'].empty? ? [] : @fields['languages'].dup
|
236
202
|
end
|
237
203
|
|
238
204
|
# Returns the format of this Reference.
|
@@ -240,7 +206,7 @@ module CFF
|
|
240
206
|
# This method is explicitly defined to override the private format method
|
241
207
|
# that all objects seem to have.
|
242
208
|
def format # :nodoc:
|
243
|
-
@fields['format']
|
209
|
+
@fields['format'].nil? ? '' : @fields['format']
|
244
210
|
end
|
245
211
|
|
246
212
|
# Sets the format of this Reference.
|
@@ -255,7 +221,7 @@ module CFF
|
|
255
221
|
# status = status
|
256
222
|
#
|
257
223
|
# Sets the status of this Reference. The status is restricted to a
|
258
|
-
# [defined set of status types](https://github.com/citation-file-format/citation-file-format#
|
224
|
+
# [defined set of status types](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreferencestatus).
|
259
225
|
def status=(status)
|
260
226
|
status = status.downcase
|
261
227
|
@fields['status'] = status if REFERENCE_STATUS_TYPES.include?(status)
|
@@ -265,7 +231,7 @@ module CFF
|
|
265
231
|
# type = type
|
266
232
|
#
|
267
233
|
# Sets the type of this Reference. The type is restricted to a
|
268
|
-
# [defined set of reference types](https://github.com/citation-file-format/citation-file-format#
|
234
|
+
# [defined set of reference types](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreferencetype).
|
269
235
|
def type=(type)
|
270
236
|
type = type.downcase
|
271
237
|
@fields['type'] = type if REFERENCE_TYPES.include?(type)
|
@@ -273,29 +239,27 @@ module CFF
|
|
273
239
|
|
274
240
|
# Override superclass #fields as References contain model parts too.
|
275
241
|
def fields # :nodoc:
|
276
|
-
[
|
277
|
-
|
278
|
-
|
242
|
+
%w[
|
243
|
+
authors contact editors editors-series identifiers
|
244
|
+
recipients senders translators
|
279
245
|
].each do |field|
|
280
|
-
normalize_modelpart_array!(@fields[field])
|
246
|
+
Util.normalize_modelpart_array!(@fields[field])
|
281
247
|
end
|
282
248
|
|
283
|
-
fields_to_hash(@fields)
|
249
|
+
Util.fields_to_hash(@fields)
|
284
250
|
end
|
285
251
|
|
286
252
|
private
|
287
253
|
|
288
254
|
def build_model(fields) # :nodoc:
|
289
|
-
[
|
290
|
-
|
291
|
-
'senders', 'translators'
|
255
|
+
%w[
|
256
|
+
authors contact editors editors-series recipients senders translators
|
292
257
|
].each do |field|
|
293
|
-
build_actor_collection!(fields[field]) if fields.include?(field)
|
258
|
+
Util.build_actor_collection!(fields[field]) if fields.include?(field)
|
294
259
|
end
|
295
260
|
|
296
|
-
[
|
297
|
-
|
298
|
-
'publisher'
|
261
|
+
%w[
|
262
|
+
conference database-provider institution location publisher
|
299
263
|
].each do |field|
|
300
264
|
fields[field] &&= Entity.new(fields[field])
|
301
265
|
end
|
@@ -413,7 +377,7 @@ module CFF
|
|
413
377
|
# the list, use:
|
414
378
|
#
|
415
379
|
# ```
|
416
|
-
#
|
380
|
+
# reference.identifiers << identifier
|
417
381
|
# ```
|
418
382
|
|
419
383
|
##
|
@@ -432,7 +396,7 @@ module CFF
|
|
432
396
|
# list, use:
|
433
397
|
#
|
434
398
|
# ```
|
435
|
-
#
|
399
|
+
# reference.keywords << keyword
|
436
400
|
# ```
|
437
401
|
#
|
438
402
|
# Keywords will be converted to Strings on output.
|
@@ -455,7 +419,7 @@ module CFF
|
|
455
419
|
# state to the list, use:
|
456
420
|
#
|
457
421
|
# ```
|
458
|
-
#
|
422
|
+
# reference.patent_states << patent_state
|
459
423
|
# ```
|
460
424
|
#
|
461
425
|
# Patent states will be converted to Strings on output.
|
data/lib/cff/schema.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018-2022 The Ruby Citation File Format Developers.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'json'
|
18
|
+
|
19
|
+
##
|
20
|
+
module CFF
|
21
|
+
SCHEMA_PATH = ::File.join(__dir__, 'schemas', '1.2.0.json') # :nodoc:
|
22
|
+
SCHEMA_FILE = JSON.parse(::File.read(SCHEMA_PATH)) # :nodoc:
|
23
|
+
end
|
data/lib/cff/util.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2018-
|
3
|
+
# Copyright (c) 2018-2022 The Ruby Citation File Format Developers.
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
@@ -14,17 +14,22 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require_relative 'entity'
|
18
|
+
require_relative 'person'
|
19
|
+
require_relative 'version'
|
20
|
+
|
17
21
|
require 'rubygems'
|
18
22
|
|
19
23
|
##
|
20
24
|
module CFF
|
21
|
-
|
22
25
|
# Util provides utility methods useful throughout the rest of the CFF library.
|
23
26
|
#
|
24
27
|
# Util does not provide any methods or fields for the public API.
|
25
28
|
module Util
|
26
29
|
# :stopdoc:
|
27
30
|
|
31
|
+
module_function
|
32
|
+
|
28
33
|
def update_cff_version(version)
|
29
34
|
return '' if version.nil? || version.empty?
|
30
35
|
|
@@ -35,10 +40,6 @@ module CFF
|
|
35
40
|
end
|
36
41
|
end
|
37
42
|
|
38
|
-
def method_to_field(name)
|
39
|
-
name.tr('_', '-')
|
40
|
-
end
|
41
|
-
|
42
43
|
def build_actor_collection!(source)
|
43
44
|
source.map! do |s|
|
44
45
|
s.has_key?('given-names') ? Person.new(s) : Entity.new(s)
|
@@ -67,6 +68,62 @@ module CFF
|
|
67
68
|
hash
|
68
69
|
end
|
69
70
|
|
71
|
+
DEFAULT_CHAR_APPROXIMATIONS = {
|
72
|
+
'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A',
|
73
|
+
'Æ' => 'AE', 'Ç' => 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E',
|
74
|
+
'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ð' => 'D', 'Ñ' => 'N',
|
75
|
+
'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', '×' => 'x',
|
76
|
+
'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y',
|
77
|
+
'Þ' => 'Th', 'ß' => 'ss', 'à' => 'a', 'á' => 'a', 'â' => 'a',
|
78
|
+
'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'ae', 'ç' => 'c', 'è' => 'e',
|
79
|
+
'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i',
|
80
|
+
'ï' => 'i', 'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o',
|
81
|
+
'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u',
|
82
|
+
'ü' => 'u', 'ý' => 'y', 'þ' => 'th', 'ÿ' => 'y', 'Ā' => 'A', 'ā' => 'a',
|
83
|
+
'Ă' => 'A', 'ă' => 'a', 'Ą' => 'A', 'ą' => 'a', 'Ć' => 'C', 'ć' => 'c',
|
84
|
+
'Ĉ' => 'C', 'ĉ' => 'c', 'Ċ' => 'C', 'ċ' => 'c', 'Č' => 'C', 'č' => 'c',
|
85
|
+
'Ď' => 'D', 'ď' => 'd', 'Đ' => 'D', 'đ' => 'd', 'Ē' => 'E', 'ē' => 'e',
|
86
|
+
'Ĕ' => 'E', 'ĕ' => 'e', 'Ė' => 'E', 'ė' => 'e', 'Ę' => 'E', 'ę' => 'e',
|
87
|
+
'Ě' => 'E', 'ě' => 'e', 'ệ' => 'e', 'Ĝ' => 'G', 'ĝ' => 'g', 'Ğ' => 'G',
|
88
|
+
'ğ' => 'g', 'Ġ' => 'G', 'ġ' => 'g', 'Ģ' => 'G', 'ģ' => 'g', 'Ĥ' => 'H',
|
89
|
+
'ĥ' => 'h', 'Ħ' => 'H', 'ħ' => 'h', 'Ĩ' => 'I', 'ĩ' => 'i', 'Ī' => 'I',
|
90
|
+
'ī' => 'i', 'Ĭ' => 'I', 'ĭ' => 'i', 'Į' => 'I', 'į' => 'i', 'İ' => 'I',
|
91
|
+
'ı' => 'i', 'IJ' => 'IJ', 'ij' => 'ij', 'Ĵ' => 'J', 'ĵ' => 'j',
|
92
|
+
'Ķ' => 'K', 'ķ' => 'k', 'ĸ' => 'k', 'Ĺ' => 'L', 'ĺ' => 'l', 'Ļ' => 'L',
|
93
|
+
'ļ' => 'l', 'Ľ' => 'L', 'ľ' => 'l', 'Ŀ' => 'L', 'ŀ' => 'l', 'Ł' => 'L',
|
94
|
+
'ł' => 'l', 'Ń' => 'N', 'ń' => 'n', 'Ņ' => 'N', 'ņ' => 'n', 'Ň' => 'N',
|
95
|
+
'ň' => 'n', 'ʼn' => "'n", 'Ŋ' => 'NG', 'ŋ' => 'ng', 'Ō' => 'O',
|
96
|
+
'ō' => 'o', 'Ŏ' => 'O', 'ŏ' => 'o', 'Ő' => 'O', 'ő' => 'o', 'Œ' => 'OE',
|
97
|
+
'œ' => 'oe', 'Ŕ' => 'R', 'ŕ' => 'r', 'Ŗ' => 'R', 'ŗ' => 'r', 'Ř' => 'R',
|
98
|
+
'ř' => 'r', 'Ś' => 'S', 'ś' => 's', 'Ŝ' => 'S', 'ŝ' => 's', 'Ş' => 'S',
|
99
|
+
'ş' => 's', 'Š' => 'S', 'š' => 's', 'Ţ' => 'T', 'ţ' => 't', 'Ť' => 'T',
|
100
|
+
'ť' => 't', 'Ŧ' => 'T', 'ŧ' => 't', 'Ũ' => 'U', 'ũ' => 'u', 'Ū' => 'U',
|
101
|
+
'ū' => 'u', 'Ŭ' => 'U', 'ŭ' => 'u', 'Ů' => 'U', 'ů' => 'u', 'Ű' => 'U',
|
102
|
+
'ű' => 'u', 'Ų' => 'U', 'ų' => 'u', 'Ŵ' => 'W', 'ŵ' => 'w', 'Ŷ' => 'Y',
|
103
|
+
'ŷ' => 'y', 'Ÿ' => 'Y', 'Ź' => 'Z', 'ź' => 'z', 'Ż' => 'Z', 'ż' => 'z',
|
104
|
+
'Ž' => 'Z', 'ž' => 'z'
|
105
|
+
}.freeze
|
106
|
+
|
107
|
+
def transliterate(string, fallback: '')
|
108
|
+
string.gsub(/[^\x00-\x7f]/u) do |char|
|
109
|
+
DEFAULT_CHAR_APPROXIMATIONS[char] || fallback
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def parameterize(string, separator: '_')
|
114
|
+
# Normalize into ASCII.
|
115
|
+
param = transliterate(string)
|
116
|
+
|
117
|
+
# Remove unwanted chars by turning them into the separator.
|
118
|
+
param.gsub!(/[^a-z0-9\-_]+/i, separator)
|
119
|
+
|
120
|
+
# Only one separator at a time.
|
121
|
+
param.gsub!(/#{separator}{2,}/, separator)
|
122
|
+
|
123
|
+
# No leading/trailing separators.
|
124
|
+
param.gsub(/^#{separator}|#{separator}$/i, '')
|
125
|
+
end
|
126
|
+
|
70
127
|
# :startdoc:
|
71
128
|
end
|
72
129
|
end
|