cocina_display 1.9.0 → 1.11.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/lib/cocina_display/concerns/contributors.rb +1 -0
- data/lib/cocina_display/concerns/events.rb +7 -0
- data/lib/cocina_display/concerns/forms.rb +13 -4
- data/lib/cocina_display/dates/date.rb +42 -4
- data/lib/cocina_display/forms/form.rb +5 -3
- data/lib/cocina_display/note.rb +17 -6
- data/lib/cocina_display/subjects/subject.rb +8 -6
- data/lib/cocina_display/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: add082bf5794bc0df8fc9480cae4fe320b295867ec41ee09099ba5a5333eab93
|
|
4
|
+
data.tar.gz: d0a5d92a67890c13ef0e26876655956c277c04571ccefb5ab120d5e68e058137
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2828617fb57955a4578da26efb839c038df38809417c5fe63bcc44fe7ec8d3412c7ebf8259679e984e997f28e9d535a200818e4a546b0f26b4f3df122cd96e85
|
|
7
|
+
data.tar.gz: 0a6e51f36f516c1e414f8aa2cf10828a1608509dd7f06da9be2b5a3d866141c3be02cfcf3f1a282c08d00097880ee96e79d4cf0d4e61bdd4c6084d4322f65c2d
|
|
@@ -88,6 +88,7 @@ module CocinaDisplay
|
|
|
88
88
|
|
|
89
89
|
# DisplayData for Contributors, one per role (excluding publisher).
|
|
90
90
|
# Contributors with no role are grouped under a default heading.
|
|
91
|
+
# @note For displaying publisher information, use {publication_display_data}.
|
|
91
92
|
# @return [Array<DisplayData>]
|
|
92
93
|
def contributor_display_data
|
|
93
94
|
contributors_by_role.except("publisher").map do |role, contributors|
|
|
@@ -135,6 +135,13 @@ module CocinaDisplay
|
|
|
135
135
|
CocinaDisplay::DisplayData.from_objects(event_dates)
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
+
# DisplayData for publisher and publication place.
|
|
139
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
140
|
+
def publication_display_data
|
|
141
|
+
CocinaDisplay::DisplayData.from_strings(publication_places, label: "Place") +
|
|
142
|
+
CocinaDisplay::DisplayData.from_strings(publisher_names, label: "Publisher")
|
|
143
|
+
end
|
|
144
|
+
|
|
138
145
|
# The earliest preferred publication date as a CocinaDisplay::Dates::Date object.
|
|
139
146
|
# Considers publication, creation, and capture dates in that order.
|
|
140
147
|
# Prefers dates marked as primary and those with a declared encoding.
|
|
@@ -9,6 +9,7 @@ module CocinaDisplay
|
|
|
9
9
|
def searchworks_resource_types
|
|
10
10
|
mapped_values = resource_type_values.flat_map { |resource_type| searchworks_resource_type(resource_type) }
|
|
11
11
|
mapped_values << "Dataset" if dataset?
|
|
12
|
+
mapped_values << "Software/Multimedia" if digital_only?
|
|
12
13
|
mapped_values.uniq
|
|
13
14
|
end
|
|
14
15
|
|
|
@@ -187,13 +188,21 @@ module CocinaDisplay
|
|
|
187
188
|
|
|
188
189
|
private
|
|
189
190
|
|
|
190
|
-
#
|
|
191
|
+
# Is the object a digital resource without a more specific resource type?
|
|
192
|
+
# @return [Boolean]
|
|
193
|
+
def digital_only?
|
|
194
|
+
resource_type_values.all?("digital")
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Map a MODS or LC resource type to SearchWorks format value(s).
|
|
191
198
|
# @param resource_type [String] The resource type to map.
|
|
192
199
|
# @return [Array<String>]
|
|
193
200
|
def searchworks_resource_type(resource_type)
|
|
194
201
|
values = []
|
|
195
202
|
|
|
196
203
|
case resource_type
|
|
204
|
+
when "dataset"
|
|
205
|
+
values << "Dataset"
|
|
197
206
|
when "cartographic"
|
|
198
207
|
values << "Map"
|
|
199
208
|
when "manuscript", "mixed material"
|
|
@@ -202,10 +211,10 @@ module CocinaDisplay
|
|
|
202
211
|
values << "Video/Film"
|
|
203
212
|
when "notated music"
|
|
204
213
|
values << "Music score"
|
|
205
|
-
when "software, multimedia"
|
|
214
|
+
when "software, multimedia", "multimedia"
|
|
206
215
|
# Prevent GIS datasets from being labeled as "Software"
|
|
207
216
|
values << "Software/Multimedia" unless cartographic? || dataset?
|
|
208
|
-
when "sound recording-musical", "sound recording-nonmusical", "sound recording"
|
|
217
|
+
when "sound recording-musical", "sound recording-nonmusical", "sound recording", "audio"
|
|
209
218
|
values << "Sound recording"
|
|
210
219
|
when "still image"
|
|
211
220
|
values << "Image"
|
|
@@ -219,7 +228,7 @@ module CocinaDisplay
|
|
|
219
228
|
else
|
|
220
229
|
values << "Book"
|
|
221
230
|
end
|
|
222
|
-
when "three dimensional object"
|
|
231
|
+
when "three dimensional object", "artifact", "tactile"
|
|
223
232
|
values << "Object"
|
|
224
233
|
end
|
|
225
234
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "edtf"
|
|
2
|
+
require "iso8601"
|
|
2
3
|
|
|
3
4
|
require "active_support"
|
|
4
5
|
require "active_support/core_ext/object/blank"
|
|
@@ -486,11 +487,48 @@ module CocinaDisplay
|
|
|
486
487
|
|
|
487
488
|
# Strict ISO8601-encoded date parser.
|
|
488
489
|
class Iso8601Format < Date
|
|
490
|
+
def self.normalize_to_edtf(value)
|
|
491
|
+
# Remove time component if there is one
|
|
492
|
+
value = value.split("T").first if value.include?("T")
|
|
493
|
+
|
|
494
|
+
# Datetime without "T" was valid until 2019, but iso8601 gem rejects it.
|
|
495
|
+
# YYYYMMDD is valid but EDTF needs dashes to parse it.
|
|
496
|
+
if /^\d{14}$/.match?(value) || /^\d{8}$/.match?(value)
|
|
497
|
+
"#{value[0..3]}-#{value[4..5]}-#{value[6..7]}"
|
|
498
|
+
else
|
|
499
|
+
super
|
|
500
|
+
end
|
|
501
|
+
end
|
|
502
|
+
|
|
489
503
|
def self.parse_date(value)
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
504
|
+
value = normalize_to_edtf(value)
|
|
505
|
+
|
|
506
|
+
# Bail out if ISO8601 gem doesn't validate it
|
|
507
|
+
begin
|
|
508
|
+
date = ISO8601::Date.new(value)
|
|
509
|
+
rescue ISO8601::Errors::UnknownPattern
|
|
510
|
+
notifier&.notify("Invalid date value \"#{value}\" for iso8601 encoding")
|
|
511
|
+
return nil
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
case value
|
|
515
|
+
# Calendar dates already match EDTF format
|
|
516
|
+
when /^\d{4}-\d{2}-\d{2}$/, /^\d{4}-\d{2}$/, /^\d{4}$/
|
|
517
|
+
super
|
|
518
|
+
# Weeks with no day become a 7-day range
|
|
519
|
+
when /^\d{4}-W\d{2}$/, /^\d{4}W\d{2}$/
|
|
520
|
+
week_end = date + 6
|
|
521
|
+
::Date.edtf("#{date}/#{week_end}")
|
|
522
|
+
# Weeks with day become a single day
|
|
523
|
+
when /^\d{4}-W\d{2}-\d$/, /^\d{4}W\d{3}$/
|
|
524
|
+
::Date.edtf(date.to_s)
|
|
525
|
+
# Ordinal dates become a single day
|
|
526
|
+
when /^\d{4}-\d{3}$/, /^\d{7}$/
|
|
527
|
+
::Date.edtf(date.to_s)
|
|
528
|
+
else
|
|
529
|
+
notifier&.notify("Unhandled date value \"#{value}\" for iso8601 encoding")
|
|
530
|
+
nil
|
|
531
|
+
end
|
|
494
532
|
end
|
|
495
533
|
end
|
|
496
534
|
|
|
@@ -5,7 +5,7 @@ module CocinaDisplay
|
|
|
5
5
|
module Forms
|
|
6
6
|
# A form associated with part or all of a Cocina object.
|
|
7
7
|
class Form
|
|
8
|
-
attr_reader :cocina
|
|
8
|
+
attr_reader :cocina, :delimiter
|
|
9
9
|
|
|
10
10
|
# Create a Form object from Cocina structured data.
|
|
11
11
|
# Delegates to subclasses for specific types.
|
|
@@ -24,8 +24,10 @@ module CocinaDisplay
|
|
|
24
24
|
|
|
25
25
|
# Create a Form object from Cocina structured data.
|
|
26
26
|
# @param cocina [Hash]
|
|
27
|
-
|
|
27
|
+
# @param delimiter [String] The delimiter to use when flattening for display
|
|
28
|
+
def initialize(cocina, delimiter: " > ")
|
|
28
29
|
@cocina = cocina
|
|
30
|
+
@delimiter = delimiter
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
# The value to use for display.
|
|
@@ -37,7 +39,7 @@ module CocinaDisplay
|
|
|
37
39
|
# Single concatenated string value for the form.
|
|
38
40
|
# @return [String]
|
|
39
41
|
def flat_value
|
|
40
|
-
Utils.compact_and_join(values, delimiter:
|
|
42
|
+
Utils.compact_and_join(values, delimiter: delimiter)
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
# The raw values from the Cocina data, flattened if nested.
|
data/lib/cocina_display/note.rb
CHANGED
|
@@ -8,24 +8,35 @@ module CocinaDisplay
|
|
|
8
8
|
TOC_TYPES = ["table of contents"].freeze
|
|
9
9
|
TOC_DISPLAY_LABEL_REGEX = /Table of contents/i
|
|
10
10
|
|
|
11
|
-
attr_reader :cocina
|
|
11
|
+
attr_reader :cocina, :delimiter
|
|
12
12
|
|
|
13
13
|
# Initialize a Note from Cocina structured data.
|
|
14
14
|
# @param cocina [Hash]
|
|
15
|
-
|
|
15
|
+
# @param delimiter [String] Delimiter to use when joining for display.
|
|
16
|
+
def initialize(cocina, delimiter: " -- ")
|
|
16
17
|
@cocina = cocina
|
|
18
|
+
@delimiter = delimiter
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
#
|
|
21
|
+
# The value to use for display.
|
|
20
22
|
# @return [String, nil]
|
|
21
23
|
def to_s
|
|
22
|
-
|
|
24
|
+
flat_value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Single concatenated string value for the note.
|
|
28
|
+
# @return [String, nil]
|
|
29
|
+
def flat_value
|
|
30
|
+
Utils.compact_and_join(values, delimiter: delimiter).presence
|
|
23
31
|
end
|
|
24
32
|
|
|
25
33
|
# The raw values from the Cocina data, flattened if nested.
|
|
26
|
-
#
|
|
34
|
+
# Strips excess whitespace and the delimiter if present.
|
|
35
|
+
# @return [Array<String>]
|
|
27
36
|
def values
|
|
28
|
-
Utils.flatten_nested_values(cocina).pluck("value")
|
|
37
|
+
Utils.flatten_nested_values(cocina).pluck("value")
|
|
38
|
+
.map { |value| value.gsub(delimiter.strip, "").strip }
|
|
39
|
+
.compact_blank
|
|
29
40
|
end
|
|
30
41
|
|
|
31
42
|
# The raw values from the Cocina data as a hash with type as key.
|
|
@@ -2,12 +2,14 @@ module CocinaDisplay
|
|
|
2
2
|
module Subjects
|
|
3
3
|
# Base class for subjects in Cocina structured data.
|
|
4
4
|
class Subject
|
|
5
|
-
attr_reader :cocina
|
|
5
|
+
attr_reader :cocina, :delimiter
|
|
6
6
|
|
|
7
7
|
# Initialize a Subject object with Cocina structured data.
|
|
8
8
|
# @param cocina [Hash] The Cocina structured data for the subject.
|
|
9
|
-
|
|
9
|
+
# @param delimiter [String] The delimiter to use when flattening for display
|
|
10
|
+
def initialize(cocina, delimiter: " > ")
|
|
10
11
|
@cocina = cocina
|
|
12
|
+
@delimiter = delimiter
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
# The top-level type of the subject.
|
|
@@ -20,7 +22,7 @@ module CocinaDisplay
|
|
|
20
22
|
# Array of display strings for each value in the subject.
|
|
21
23
|
# Used for search, where each value should be indexed separately.
|
|
22
24
|
# @return [Array<String>]
|
|
23
|
-
def
|
|
25
|
+
def values
|
|
24
26
|
subject_values.map(&:to_s).compact_blank
|
|
25
27
|
end
|
|
26
28
|
|
|
@@ -28,13 +30,13 @@ module CocinaDisplay
|
|
|
28
30
|
# Genre values are capitalized; other subject values are not.
|
|
29
31
|
# @return [String]
|
|
30
32
|
def to_s
|
|
31
|
-
(type == "genre") ?
|
|
33
|
+
(type == "genre") ? flat_value&.upcase_first : flat_value
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
# A string representation of the entire subject, concatenated for display.
|
|
35
37
|
# @return [String]
|
|
36
|
-
def
|
|
37
|
-
Utils.compact_and_join(
|
|
38
|
+
def flat_value
|
|
39
|
+
Utils.compact_and_join(values, delimiter: delimiter)
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
# Label used to render the subject for display.
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cocina_display
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nick Budak
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-03-03 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: janeway-jsonpath
|
|
@@ -51,6 +51,20 @@ dependencies:
|
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '3.2'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: iso8601
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 0.13.0
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 0.13.0
|
|
54
68
|
- !ruby/object:Gem::Dependency
|
|
55
69
|
name: i18n
|
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -298,7 +312,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
298
312
|
- !ruby/object:Gem::Version
|
|
299
313
|
version: '0'
|
|
300
314
|
requirements: []
|
|
301
|
-
rubygems_version: 3.6.
|
|
315
|
+
rubygems_version: 3.6.2
|
|
302
316
|
specification_version: 4
|
|
303
317
|
summary: Helpers for rendering Cocina metadata
|
|
304
318
|
test_files: []
|