cocina_display 1.1.1 → 1.1.3
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/lib/cocina_display/concerns/contributors.rb +12 -10
- data/lib/cocina_display/contributors/contributor.rb +1 -1
- data/lib/cocina_display/dates/date.rb +13 -8
- data/lib/cocina_display/dates/date_range.rb +10 -1
- data/lib/cocina_display/geospatial.rb +11 -8
- data/lib/cocina_display/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3e38973fd7ea8399ce60829b3d11bafaa551c0f87e2bc1ccb49f55463b2c1b9
|
4
|
+
data.tar.gz: dd1398f2e2176979fdedfede55b9b09f46e42fffad1c7a16d2a4bcc9e9ef0229
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39fd439e148f6eb1dc58fdec2752519083b627bd102eb8b1f0c40a74e539fdc2799aa6caed446f1142c16ffc59220bccc94f8a1fe7cc846786dc8832ba585310
|
7
|
+
data.tar.gz: 7a6560028d3f0e75e90ac922fc15b83eeabf393f28eeca4b50a78462278dba9db5e9785a8c8ab4f93a3cabc70ab1f6cf6ce7047a5712f05dd5de8c06d3b2b7e4
|
@@ -20,20 +20,20 @@ module CocinaDisplay
|
|
20
20
|
# @param with_date [Boolean] Include life dates, if present
|
21
21
|
# @return [Array<String>]
|
22
22
|
def additional_contributor_names(with_date: false)
|
23
|
-
additional_contributors.map { |c| c.display_name(with_date: with_date) }
|
23
|
+
additional_contributors.map { |c| c.display_name(with_date: with_date) }.compact
|
24
24
|
end
|
25
25
|
|
26
26
|
# All names of publishers, formatted for display.
|
27
27
|
# @return [Array<String>]
|
28
28
|
def publisher_names
|
29
|
-
publisher_contributors.map(&:display_name)
|
29
|
+
publisher_contributors.map(&:display_name).compact
|
30
30
|
end
|
31
31
|
|
32
|
-
# All names of
|
32
|
+
# All names of contributors who are people, formatted for display.
|
33
33
|
# @param with_date [Boolean] Include life dates, if present
|
34
34
|
# @return [Array<String>]
|
35
35
|
def person_contributor_names(with_date: false)
|
36
|
-
contributors.filter(&:person?).map { |c| c.display_name(with_date: with_date) }
|
36
|
+
contributors.filter(&:person?).map { |c| c.display_name(with_date: with_date) }.compact
|
37
37
|
end
|
38
38
|
|
39
39
|
# All names of non-person contributors, formatted for display.
|
@@ -41,19 +41,19 @@ module CocinaDisplay
|
|
41
41
|
# @return [Array<String>]
|
42
42
|
# @see https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md#contributor-types
|
43
43
|
def impersonal_contributor_names
|
44
|
-
contributors.reject(&:person?).map(&:display_name)
|
44
|
+
contributors.reject(&:person?).map(&:display_name).compact
|
45
45
|
end
|
46
46
|
|
47
47
|
# All names of contributors that are organizations, formatted for display.
|
48
48
|
# @return [Array<String>]
|
49
49
|
def organization_contributor_names
|
50
|
-
contributors.filter(&:organization?).map(&:display_name)
|
50
|
+
contributors.filter(&:organization?).map(&:display_name).compact
|
51
51
|
end
|
52
52
|
|
53
53
|
# All names of contributors that are conferences, formatted for display.
|
54
54
|
# @return [Array<String>]
|
55
55
|
def conference_contributor_names
|
56
|
-
contributors.filter(&:conference?).map(&:display_name)
|
56
|
+
contributors.filter(&:conference?).map(&:display_name).compact
|
57
57
|
end
|
58
58
|
|
59
59
|
# A hash mapping role names to the names of contributors with that role.
|
@@ -61,9 +61,11 @@ module CocinaDisplay
|
|
61
61
|
# @return [Hash<String, Array<String>>]
|
62
62
|
def contributor_names_by_role(with_date: false)
|
63
63
|
contributors.each_with_object({}) do |contributor, hash|
|
64
|
-
contributor.
|
65
|
-
|
66
|
-
|
64
|
+
if (name = contributor.display_name(with_date: with_date)).present?
|
65
|
+
contributor.roles.each do |role|
|
66
|
+
hash[role.to_s] ||= []
|
67
|
+
hash[role.to_s] << name
|
68
|
+
end
|
67
69
|
end
|
68
70
|
end
|
69
71
|
end
|
@@ -80,7 +80,7 @@ module CocinaDisplay
|
|
80
80
|
# @param with_date [Boolean] Include life dates, if present
|
81
81
|
# @return [String]
|
82
82
|
def display_name(with_date: false)
|
83
|
-
names.map { |name| name.to_s(with_date: with_date) }.first
|
83
|
+
names.map { |name| name.to_s(with_date: with_date) }.compact_blank.first
|
84
84
|
end
|
85
85
|
|
86
86
|
# The full forename for the contributor from the first available name.
|
@@ -37,6 +37,7 @@ module CocinaDisplay
|
|
37
37
|
# Try to match against known date formats using their regexes
|
38
38
|
# Order matters here; more specific formats should be checked first
|
39
39
|
date_class ||= [
|
40
|
+
UndeclaredEdtfFormat,
|
40
41
|
MMDDYYYYFormat,
|
41
42
|
MMDDYYFormat,
|
42
43
|
YearRangeFormat,
|
@@ -86,10 +87,16 @@ module CocinaDisplay
|
|
86
87
|
# @return [String, nil]
|
87
88
|
attr_accessor :type
|
88
89
|
|
90
|
+
# The encoding name of this date, if specified.
|
91
|
+
# @example "iso8601"
|
92
|
+
# @return [String, nil]
|
93
|
+
attr_accessor :encoding
|
94
|
+
|
89
95
|
def initialize(cocina)
|
90
96
|
@cocina = cocina
|
91
97
|
@date = self.class.parse_date(cocina["value"])
|
92
98
|
@type = cocina["type"] unless ["start", "end"].include?(cocina["type"])
|
99
|
+
@encoding = cocina.dig("encoding", "code")
|
93
100
|
end
|
94
101
|
|
95
102
|
# Compare this date to another {Date} or {DateRange} using its {sort_key}.
|
@@ -115,14 +122,6 @@ module CocinaDisplay
|
|
115
122
|
qualifier.present?
|
116
123
|
end
|
117
124
|
|
118
|
-
# The encoding of this date, if specified.
|
119
|
-
# @example
|
120
|
-
# date.encoding #=> "iso8601"
|
121
|
-
# @return [String, nil]
|
122
|
-
def encoding
|
123
|
-
cocina.dig("encoding", "code")
|
124
|
-
end
|
125
|
-
|
126
125
|
# Was an encoding declared for this date?
|
127
126
|
# @return [Boolean]
|
128
127
|
def encoding?
|
@@ -515,6 +514,12 @@ module CocinaDisplay
|
|
515
514
|
end
|
516
515
|
end
|
517
516
|
|
517
|
+
# Extractor for dates that already match EDTF, they just didn't declare it
|
518
|
+
# Matches YYYY-MM-DD, YYYY-MM and YYYY; no further normalization needed
|
519
|
+
class UndeclaredEdtfFormat < ExtractorDateFormat
|
520
|
+
REGEX = /^(?<year>\d{4})(?:-(?<month>\d{2}))?(?:-(?<day>\d{2}))?$/
|
521
|
+
end
|
522
|
+
|
518
523
|
# Extractor for MM/DD/YYYY and MM/DD/YYY-formatted dates
|
519
524
|
class MMDDYYYYFormat < ExtractorDateFormat
|
520
525
|
REGEX = /(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{3,4})/
|
@@ -13,7 +13,16 @@ module CocinaDisplay
|
|
13
13
|
def self.from_cocina(cocina)
|
14
14
|
return unless cocina["structuredValue"].present?
|
15
15
|
|
16
|
-
dates
|
16
|
+
# Create the individual dates; if no encoding/type declared give them
|
17
|
+
# top-level encoding/type
|
18
|
+
dates = cocina["structuredValue"].map do |sv|
|
19
|
+
date = Date.from_cocina(sv)
|
20
|
+
date.encoding ||= cocina.dig("encoding", "code")
|
21
|
+
date.type ||= cocina["type"]
|
22
|
+
date
|
23
|
+
end
|
24
|
+
|
25
|
+
# Ensure we have at least a start or a stop
|
17
26
|
start = dates.find(&:start?)
|
18
27
|
stop = dates.find(&:end?)
|
19
28
|
return unless start || stop
|
@@ -150,12 +150,15 @@ module CocinaDisplay
|
|
150
150
|
# @param [String] south southern latitude
|
151
151
|
# @return [BoundingBox, nil] nil if parsing fails
|
152
152
|
def self.from_coords(west:, east:, north:, south:)
|
153
|
-
min_point = Geo::Coord.parse("#{
|
154
|
-
max_point = Geo::Coord.parse("#{
|
153
|
+
min_point = Geo::Coord.parse("#{south}, #{west}")
|
154
|
+
max_point = Geo::Coord.parse("#{north}, #{east}")
|
155
155
|
|
156
156
|
# Must be parsable
|
157
157
|
return unless min_point && max_point
|
158
158
|
|
159
|
+
# Ensure min_point is southwest and max_point is northeast
|
160
|
+
return if min_point.lat > max_point.lat || min_point.lng > max_point.lng
|
161
|
+
|
159
162
|
new(min_point: min_point, max_point: max_point)
|
160
163
|
end
|
161
164
|
|
@@ -175,7 +178,7 @@ module CocinaDisplay
|
|
175
178
|
def to_s
|
176
179
|
min_lat, min_lng = format_point(min_point)
|
177
180
|
max_lat, max_lng = format_point(max_point)
|
178
|
-
"#{min_lng} -- #{max_lng} / #{
|
181
|
+
"#{min_lng} -- #{max_lng} / #{max_lat} -- #{min_lat}"
|
179
182
|
end
|
180
183
|
|
181
184
|
# Format using the Well-Known Text (WKT) representation.
|
@@ -300,7 +303,7 @@ module CocinaDisplay
|
|
300
303
|
min_lat = normalize_coord(matches[:min_lat])
|
301
304
|
max_lat = normalize_coord(matches[:max_lat])
|
302
305
|
|
303
|
-
BoundingBox.from_coords(west: min_lng, east: max_lng, north:
|
306
|
+
BoundingBox.from_coords(west: min_lng, east: max_lng, north: max_lat, south: min_lat)
|
304
307
|
end
|
305
308
|
end
|
306
309
|
|
@@ -321,28 +324,28 @@ module CocinaDisplay
|
|
321
324
|
# @see https://www.oclc.org/bibformats/en/2xx/255.html#subfieldc
|
322
325
|
class DMSBoundingBoxParser < BoundingBoxParser
|
323
326
|
include DMSParser
|
324
|
-
PATTERN = /(?<min_lng>.+?)-+(?<max_lng>.+)\/(?<
|
327
|
+
PATTERN = /(?<min_lng>.+?)-+(?<max_lng>.+)\/(?<max_lat>.+?)-+(?<min_lat>.+)/
|
325
328
|
end
|
326
329
|
|
327
330
|
# Format that pairs hemispheres with decimal degrees.
|
328
331
|
# @example W 126.04--W 052.03/N 050.37--N 006.8
|
329
332
|
class DecimalBoundingBoxParser < BoundingBoxParser
|
330
333
|
include DecimalParser
|
331
|
-
PATTERN = /(?<min_lng>[0-9.EW]+?)-+(?<max_lng>[0-9.EW]+)\/(?<
|
334
|
+
PATTERN = /(?<min_lng>[0-9.EW]+?)-+(?<max_lng>[0-9.EW]+)\/(?<max_lat>[0-9.NS]+?)-+(?<min_lat>[0-9.NS]+)/
|
332
335
|
end
|
333
336
|
|
334
337
|
# DMS-format data that appears to come from MARC 034 subfields.
|
335
338
|
# @see https://www.oclc.org/bibformats/en/0xx/034.html
|
336
339
|
# @example $dW0963700$eW0900700$fN0433000$gN040220
|
337
340
|
class MarcDMSBoundingBoxParser < DMSBoundingBoxParser
|
338
|
-
PATTERN = /\$d(?<min_lng>[WENS].+)\$e(?<max_lng>[WENS].+)\$f(?<
|
341
|
+
PATTERN = /\$d(?<min_lng>[WENS].+)\$e(?<max_lng>[WENS].+)\$f(?<max_lat>[WENS].+)\$g(?<min_lat>[WENS].+)/
|
339
342
|
end
|
340
343
|
|
341
344
|
# Decimal degree format data that appears to come from MARC 034 subfields.
|
342
345
|
# @see https://www.oclc.org/bibformats/en/0xx/034.html
|
343
346
|
# @example $d-112.0785250$e-111.6012719$f037.6516503$g036.8583209
|
344
347
|
class MarcDecimalBoundingBoxParser < DecimalBoundingBoxParser
|
345
|
-
PATTERN = /\$d(?<min_lng>[0-9.-]+)\$e(?<max_lng>[0-9.-]+)\$f(?<
|
348
|
+
PATTERN = /\$d(?<min_lng>[0-9.-]+)\$e(?<max_lng>[0-9.-]+)\$f(?<max_lat>[0-9.-]+)\$g(?<min_lat>[0-9.-]+)/
|
346
349
|
end
|
347
350
|
end
|
348
351
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocina_display
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Budak
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: janeway-jsonpath
|