mods 3.0.0.alpha2 → 3.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6490e1cc58f876632e1d50065bab857eb104c4e0af18e8d1c3c18624fcdcf228
4
- data.tar.gz: 4c16e2ca22fa7803d20f521b21514317f31c13f689eca1d5d7eaee3e5d2ecd80
3
+ metadata.gz: cea16c53599001b8cede7fb85bffef53aa28de61718785af76fd5445915fc80c
4
+ data.tar.gz: fba29c21dd8bc15483de289aafb690616b6bd6af817d6252915e41238bf1ed70
5
5
  SHA512:
6
- metadata.gz: a40bedc72f0282d80f771d6808a924ece95447092a4bb9f48108977387e73b80cdc5ebd5f6c3af1aef938a2b952fde5a1ee8d320635e808b8f06a47f90cba41d
7
- data.tar.gz: a689cc2b3415bb73af3940809fca8795b0de6cbb9f9768a62a347ea7016d7e18c005b5a33a0233ee61dad9f37dc324a20fb0a8f88068ca196fe291bc02d704a9
6
+ metadata.gz: e6ec16f53b9355f57315248e6eabd57d3db32743e4235365f119a519c36abc0d47e75af9c600ac2666bc5db9b2c77a6629e1ace33b847077606ef3bd32d65f78
7
+ data.tar.gz: 2028457eec91d93b8a44d48d2da3152d6808e850dbc201a199deb43465464497d18611049b888b5a0f2029db5166e7c99e34206f9bde2480e04e4bcf3d6eb7b2
data/lib/mods/date.rb CHANGED
@@ -11,7 +11,7 @@ module Mods
11
11
  # @param [Nokogiri::XML::Element] xml A date-flavored MODS field from the XML
12
12
  # @return [Mods::Date]
13
13
  def self.from_element(xml)
14
- case xml.attr(:encoding)
14
+ case xml.attr(:encoding)&.downcase
15
15
  when 'w3cdtf'
16
16
  Mods::Date::W3cdtfFormat.new(xml)
17
17
  when 'iso8601'
@@ -23,12 +23,13 @@ module Mods
23
23
  # when 'temper'
24
24
  # Mods::Date::TemperFormat.new(xml)
25
25
  else
26
- date_class = Mods::Date if xml.text =~ /\p{Hebrew}/
26
+ date_class = UnparseableDate if xml.text =~ /\p{Hebrew}/ || xml.text =~ /^-/
27
27
  date_class ||= [
28
28
  MMDDYYYYFormat,
29
29
  MMDDYYFormat,
30
30
  YearRangeFormat,
31
31
  DecadeAsYearDashFormat,
32
+ DecadeStringFormat,
32
33
  EmbeddedBCYearFormat,
33
34
  EmbeddedYearFormat,
34
35
  EmbeddedThreeDigitYearFormat,
@@ -49,12 +50,15 @@ module Mods
49
50
  # Strict ISO8601-encoded date parser
50
51
  class Iso8601Format < Date
51
52
  def self.parse_date(text)
52
- @date = ::Date.parse(normalize_to_edtf(text))
53
+ ::Date.parse(normalize_to_edtf(text))
53
54
  end
54
55
  end
55
56
 
56
57
  # Less strict W3CDTF-encoded date parser
57
58
  class W3cdtfFormat < Date
59
+ def self.normalize_to_edtf(text)
60
+ super.gsub('-00', '')
61
+ end
58
62
  end
59
63
 
60
64
  # Strict EDTF parser
@@ -62,7 +66,16 @@ module Mods
62
66
  attr_reader :date
63
67
 
64
68
  def self.normalize_to_edtf(text)
65
- text
69
+ return '0000' if text.strip == '0'
70
+
71
+ case text
72
+ when /^\d{1,3}$/
73
+ text.rjust(4, "0") if text =~ /^\d{1,3}$/
74
+ when /^-\d{1,3}$/
75
+ "-#{text.sub(/^-/, '').rjust(4, "0")}"
76
+ else
77
+ text
78
+ end
66
79
  end
67
80
  end
68
81
 
@@ -100,6 +113,12 @@ module Mods
100
113
  end
101
114
  end
102
115
 
116
+ class UnparseableDate < ExtractorDateFormat
117
+ def self.parse_date(text)
118
+ nil
119
+ end
120
+ end
121
+
103
122
  # Full text extractor for MM/DD/YYYY and MM/DD/YYY-formatted dates
104
123
  class MMDDYYYYFormat < ExtractorDateFormat
105
124
  REGEX = /(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{3,4})/
@@ -201,7 +220,17 @@ module Mods
201
220
 
202
221
  # Full-text extractor for data formatted as YYY-
203
222
  class DecadeAsYearDashFormat < ExtractorDateFormat
204
- REGEX = /(?<!\d)(?<year>\d{3})[-_x?](?!\d)/
223
+ REGEX = /(?<!\d)(?<year>\d{3})[-_xu?](?!\d)/
224
+
225
+ def self.normalize_to_edtf(text)
226
+ matches = text.match(REGEX)
227
+ "#{matches[:year]}X"
228
+ end
229
+ end
230
+
231
+ # Full-text extractor for data formatted as YYY0s
232
+ class DecadeStringFormat < ExtractorDateFormat
233
+ REGEX = /(?<!\d)(?<year>\d{3})0s(?!\d)/
205
234
 
206
235
  def self.normalize_to_edtf(text)
207
236
  matches = text.match(REGEX)
@@ -221,42 +250,42 @@ module Mods
221
250
 
222
251
  # Full-text extractor that tries hard to pick any year present in the data
223
252
  class EmbeddedYearFormat < ExtractorDateFormat
224
- REGEX = /(?<prefix>-)?(?<!\d)(?<year>\d{4})(?!\d)/
253
+ REGEX = /(?<!\d)(?<year>\d{4})(?!\d)/
225
254
 
226
255
  def self.normalize_to_edtf(text)
227
256
  matches = text.match(REGEX)
228
- "#{matches[:prefix]}#{matches[:year].rjust(4, "0")}"
257
+ "#{matches[:year].rjust(4, "0")}"
229
258
  end
230
259
  end
231
260
 
232
261
  # Full-text extractor that tries hard to pick any year present in the data
233
262
  class EmbeddedThreeDigitYearFormat < ExtractorDateFormat
234
- REGEX = /(?<prefix>-)?(?<!\d)(?<year>\d{3})(?!\d)(?!\d)/
263
+ REGEX = /(?<!\d)(?<year>\d{3})(?!\d)(?!\d)/
235
264
 
236
265
  def self.normalize_to_edtf(text)
237
266
  matches = text.match(REGEX)
238
- "#{matches[:prefix]}#{matches[:year].rjust(4, "0")}"
267
+ "#{matches[:year].rjust(4, "0")}"
239
268
  end
240
269
  end
241
270
 
242
271
  # Full-text extractor that tries hard to pick any year present in the data
243
272
  class OneOrTwoDigitYearFormat < ExtractorDateFormat
244
- REGEX = /^(?<prefix>-)?(?<year>\d{1,2})$/
273
+ REGEX = /^(?<year>\d{1,2})$/
245
274
 
246
275
  def self.normalize_to_edtf(text)
247
276
  matches = text.match(REGEX)
248
- "#{matches[:prefix]}#{matches[:year].rjust(4, "0")}"
277
+ "#{matches[:year].rjust(4, "0")}"
249
278
  end
250
279
  end
251
280
 
252
281
  # Full-text extractor that tries hard to pick any year present in the data
253
282
  class EmbeddedYearWithBracketsFormat < ExtractorDateFormat
254
283
  # [YYY]Y Y[YYY] [YY]YY Y[YY]Y YY[YY] YYY[Y] YY[Y]Y Y[Y]YY [Y]YYY
255
- REGEX = /(?<prefix>-)?(?<year>[\d\[\]]{6})(?!\d)/
284
+ REGEX = /(?<year>[\d\[\]]{6})(?!\d)/
256
285
 
257
286
  def self.normalize_to_edtf(text)
258
287
  matches = text.match(REGEX)
259
- "#{matches[:prefix]}#{matches[:year].gsub('[', '').gsub(']', '')}"
288
+ "#{matches[:year].gsub('[', '').gsub(']', '')}"
260
289
  end
261
290
  end
262
291
 
@@ -327,7 +356,9 @@ module Mods
327
356
  #
328
357
  # @return [String]
329
358
  def type
330
- xml.attr(:type)
359
+ return if xml.attr(:type)&.empty?
360
+
361
+ xml.attr(:type)&.downcase
331
362
  end
332
363
 
333
364
  ##
@@ -335,7 +366,9 @@ module Mods
335
366
  #
336
367
  # @return [String]
337
368
  def encoding
338
- xml.attr(:encoding)
369
+ return if xml.attr(:encoding)&.empty?
370
+
371
+ xml.attr(:encoding)&.downcase
339
372
  end
340
373
 
341
374
  ##
@@ -359,7 +392,9 @@ module Mods
359
392
  #
360
393
  # @return [String]
361
394
  def point
362
- xml.attr(:point)
395
+ return if xml.attr(:point)&.empty?
396
+
397
+ xml.attr(:point)&.downcase
363
398
  end
364
399
 
365
400
  ##
@@ -391,7 +426,7 @@ module Mods
391
426
  #
392
427
  # @return [String]
393
428
  def qualifier
394
- xml.attr(:qualifier)
429
+ xml.attr(:qualifier)&.downcase
395
430
  end
396
431
 
397
432
  ##
@@ -419,10 +454,14 @@ module Mods
419
454
  end
420
455
 
421
456
  def precision
457
+ return :unknown unless date_range || date
458
+
422
459
  if date_range.is_a? EDTF::Century
423
460
  :century
424
461
  elsif date_range.is_a? EDTF::Decade
425
462
  :decade
463
+ elsif date.is_a? EDTF::Interval
464
+ date_range.precision
426
465
  else
427
466
  case date.precision
428
467
  when :month
@@ -258,7 +258,7 @@ module Mods
258
258
  n.publisher :path => 'm:publisher'
259
259
  Mods::OriginInfo::DATE_ELEMENTS.each { |date_el|
260
260
  n.send date_el, :path => "m:#{date_el}" do |d|
261
- d.as_object :path => '.', :accessor => lambda { |a| Mods::Date.from_element(a) }
261
+ d.as_object :path => '.', :single => true, :accessor => lambda { |a| Mods::Date.from_element(a) }
262
262
 
263
263
  with_attributes(d, Mods::DATE_ATTRIBS)
264
264
 
data/lib/mods/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Mods
2
2
  # this is the Ruby Gem version
3
- VERSION = '3.0.0.alpha2'.freeze
3
+ VERSION = '3.0.2'.freeze
4
4
  end
@@ -101,6 +101,7 @@ RSpec.describe Mods::Date do
101
101
  '1900-06' => :month,
102
102
  '1900-06-uu' => :month,
103
103
  '1900-06-15' => :day,
104
+ '2014-01-01/2020-12-31' => :day
104
105
  }.each do |data, expected|
105
106
  describe "with #{data}" do
106
107
  let(:date_element) { "<dateCreated encoding=\"edtf\">#{data}</dateCreated>" }
@@ -209,6 +210,9 @@ RSpec.describe Mods::Date do
209
210
  '1900-uu-uu' => Date.parse('1900-01-01')..Date.parse('1900-12-31'),
210
211
  '1900-uu-15' => Date.parse('1900-01-15')..Date.parse('1900-12-15'),
211
212
  '1900-06-uu' => Date.parse('1900-06-01')..Date.parse('1900-06-30'),
213
+ '-250' => Date.parse('-250-01-01')..Date.parse('-250-12-31'), # EDTF requires a 4 digit year, but what can you do.
214
+ '63' => Date.parse('0063-01-01')..Date.parse('0063-12-31'),
215
+ '125' => Date.parse('125-01-01')..Date.parse('125-12-31'),
212
216
  }.each do |data, expected|
213
217
  describe "with #{data}" do
214
218
  let(:date_element) { "<dateCreated encoding=\"edtf\">#{data}</dateCreated>" }
@@ -226,6 +230,7 @@ RSpec.describe Mods::Date do
226
230
  {
227
231
  '1753' => Date.parse('1753-01-01')..Date.parse('1753-12-31'),
228
232
  '-1753' => Date.parse('-1753-01-01')..Date.parse('-1753-12-31'),
233
+ '1992-00-00' => Date.parse('1992-01-01')..Date.parse('1992-12-31'),
229
234
  '1992-05-06' => Date.parse('1992-05-06')..Date.parse('1992-05-06'),
230
235
  '1992-04' => Date.parse('1992-04-01')..Date.parse('1992-04-30'),
231
236
  '2004-02' => Date.parse('2004-02-01')..Date.parse('2004-02-29'),
@@ -303,7 +308,8 @@ RSpec.describe Mods::Date do
303
308
  {
304
309
  'Minguo 19 [1930]' => Date.parse('1930-01-01')..Date.parse('1930-12-31'),
305
310
  '1745 mag. 14' => Date.parse('1745-01-01')..Date.parse('1745-12-31'),
306
- '-745' => Date.parse('-745-01-01')..Date.parse('-745-12-31'),
311
+ '-745' => '', # too ambiguious to even attempt.
312
+ '-1999' => '', # too ambiguious to even attempt.
307
313
  '[1923]' => Date.parse('1923-01-01')..Date.parse('1923-12-31'),
308
314
  '1532.' => Date.parse('1532-01-01')..Date.parse('1532-12-31'),
309
315
  '[ca 1834]' => Date.parse('1834-01-01')..Date.parse('1834-12-31'),
@@ -319,8 +325,11 @@ RSpec.describe Mods::Date do
319
325
  '193-' => Date.parse('1930-01-01')..Date.parse('1939-12-31'),
320
326
  '196_' => Date.parse('1960-01-01')..Date.parse('1969-12-31'),
321
327
  '196x' => Date.parse('1960-01-01')..Date.parse('1969-12-31'),
328
+ '196u' => Date.parse('1960-01-01')..Date.parse('1969-12-31'),
329
+ '1960s' => Date.parse('1960-01-01')..Date.parse('1969-12-31'),
322
330
  '186?' => Date.parse('1860-01-01')..Date.parse('1869-12-31'),
323
331
  '1700?' => Date.parse('1700-01-01')..Date.parse('1700-12-31'),
332
+ 'early 1730s' => Date.parse('1730-01-01')..Date.parse('1739-12-31'),
324
333
  '[1670-1684]' => Date.parse('1670-01-01')..Date.parse('1684-12-31'),
325
334
  '[18]74' => Date.parse('1874-01-01')..Date.parse('1874-12-31'),
326
335
  '250 B.C.' => Date.parse('-0249-01-01')..Date.parse('-249-12-31'),
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mods
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.alpha2
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Naomi Dushay
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-01-27 00:00:00.000000000 Z
12
+ date: 2022-04-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -218,9 +218,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
218
218
  version: '0'
219
219
  required_rubygems_version: !ruby/object:Gem::Requirement
220
220
  requirements:
221
- - - ">"
221
+ - - ">="
222
222
  - !ruby/object:Gem::Version
223
- version: 1.3.1
223
+ version: '0'
224
224
  requirements: []
225
225
  rubygems_version: 3.2.32
226
226
  signing_key: