cocina_display 2.0.0 → 2.1.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac41e805ba8d1ab521f7d647a0407c7c0cc02840bd3bde547c4ef5a017b32dca
|
|
4
|
+
data.tar.gz: ca2d3190ea5e1b9e83f504343fbfc9af462cdd0b4a51e615c623a33ceaef7e21
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6962854fc5bffc3288692a8feb183f098adba9f3c0f4f424db58d326e87a2d63f534fc06ea644124d6e37fd2fb0846f2970e49348b70f96a4269b2a0f0c53ab0
|
|
7
|
+
data.tar.gz: 1650a3791e4236bc2cc9fdbbcd9b4920c670a5c5fb52acc3122b3bea5755efe69d31a61496f3c41f1d8f4defa125791fd38a872d2a75f58055acf5ab41cde0f2
|
|
@@ -126,7 +126,10 @@ module CocinaDisplay
|
|
|
126
126
|
# All root level events associated with the object.
|
|
127
127
|
# @return [Array<CocinaDisplay::Events::Event>]
|
|
128
128
|
def events
|
|
129
|
-
@events ||= path("$.description.event.*").map
|
|
129
|
+
@events ||= path("$.description.event.*").map do |cocina|
|
|
130
|
+
event = CocinaDisplay::Events::Event.new(cocina)
|
|
131
|
+
event.imprint? ? CocinaDisplay::Events::Imprint.new(cocina) : event
|
|
132
|
+
end
|
|
130
133
|
end
|
|
131
134
|
|
|
132
135
|
# The adminMetadata creation event (When was it was deposited?)
|
|
@@ -144,12 +147,9 @@ module CocinaDisplay
|
|
|
144
147
|
end
|
|
145
148
|
|
|
146
149
|
# Array of CocinaDisplay::Imprint objects for all relevant Cocina events.
|
|
147
|
-
#
|
|
148
|
-
# Considers event types as well as date types if the event is untyped.
|
|
149
|
-
# Prefers events where the date was not encoded, if any.
|
|
150
|
-
# @return [Array<CocinaDisplay::Imprint>] The list of Imprint objects
|
|
150
|
+
# @return [Array<CocinaDisplay::Imprint>]
|
|
151
151
|
def imprint_events
|
|
152
|
-
events.filter
|
|
152
|
+
events.filter { |event| event.is_a? CocinaDisplay::Events::Imprint }
|
|
153
153
|
end
|
|
154
154
|
|
|
155
155
|
# All dates associated with the object via an event.
|
|
@@ -16,7 +16,7 @@ module CocinaDisplay
|
|
|
16
16
|
# @note Also supports `event1.between?(event2, event3)` via {Comparable}.
|
|
17
17
|
# @return [Integer, nil]
|
|
18
18
|
def <=>(other)
|
|
19
|
-
[
|
|
19
|
+
[dates] <=> [other.dates] if other.is_a?(Event)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# The display label for the event.
|
|
@@ -26,7 +26,6 @@ module CocinaDisplay
|
|
|
26
26
|
# @return [String]
|
|
27
27
|
def label
|
|
28
28
|
return cocina["displayLabel"] if cocina["displayLabel"].present?
|
|
29
|
-
return "Imprint" if imprint?
|
|
30
29
|
return dates.map(&:label).first if date_only?
|
|
31
30
|
|
|
32
31
|
type&.capitalize || date_types.first&.capitalize || "Event"
|
|
@@ -80,7 +79,10 @@ module CocinaDisplay
|
|
|
80
79
|
# @note Unencoded dates or no dates often indicate an imprint statement.
|
|
81
80
|
# @return [Boolean]
|
|
82
81
|
def imprint?
|
|
83
|
-
|
|
82
|
+
contributors.present? &&
|
|
83
|
+
locations.present? &&
|
|
84
|
+
(has_type?("publication") || types.empty?) &&
|
|
85
|
+
(dates.any? { |date| !date.encoding? } || dates.none?)
|
|
84
86
|
end
|
|
85
87
|
|
|
86
88
|
# All contributors associated with this event.
|
|
@@ -107,49 +109,11 @@ module CocinaDisplay
|
|
|
107
109
|
end
|
|
108
110
|
end
|
|
109
111
|
|
|
110
|
-
# String representation of the event using
|
|
111
|
-
# Format is inspired by typical imprint statements for books.
|
|
112
|
+
# String representation of the event using date and location.
|
|
112
113
|
# @return [String]
|
|
113
|
-
# @example "
|
|
114
|
+
# @example "John Doe, New York (State), 1999"
|
|
114
115
|
def to_s
|
|
115
|
-
|
|
116
|
-
note_place_contrib = Utils.compact_and_join([edition_note_str, place_contrib], delimiter: " - ")
|
|
117
|
-
Utils.compact_and_join([note_place_contrib, date_str, copyright_note_str], delimiter: ", ")
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# Filter dates for uniqueness using base value according to predefined rules.
|
|
121
|
-
# 1. For a group of dates with the same base value, choose a single one
|
|
122
|
-
# 2. Prefer unencoded dates over encoded ones when choosing a single date
|
|
123
|
-
# 3. Remove date ranges that duplicate any unencoded non-range dates
|
|
124
|
-
# @return [Array<CocinaDisplay::Dates::Date>]
|
|
125
|
-
# @see CocinaDisplay::Dates::Date#base_value
|
|
126
|
-
# @see https://consul.stanford.edu/display/chimera/MODS+display+rules#MODSdisplayrules-3b.%3CoriginInfo%3E
|
|
127
|
-
def unique_dates_for_display
|
|
128
|
-
# Choose a single date for each group with the same base value
|
|
129
|
-
deduped_dates = dates.group_by(&:base_value).map do |base_value, group|
|
|
130
|
-
if (unencoded = group.reject(&:encoding?)).any?
|
|
131
|
-
unencoded.first
|
|
132
|
-
else
|
|
133
|
-
group.first
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# Remove any ranges that duplicate part of an unencoded non-range date
|
|
138
|
-
ranges, singles = deduped_dates.partition { |date| date.is_a?(CocinaDisplay::Dates::DateRange) }
|
|
139
|
-
unencoded_singles_dates = singles.reject(&:encoding?).flat_map(&:to_a)
|
|
140
|
-
ranges.reject! { |date_range| unencoded_singles_dates.any? { |date| date_range.as_range.include?(date) } }
|
|
141
|
-
|
|
142
|
-
(singles + ranges).sort
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# Filter locations to display according to predefined rules.
|
|
146
|
-
# 1. Prefer unencoded locations (plain value) over encoded ones
|
|
147
|
-
# 2. If no unencoded locations but there are MARC country codes, decode them
|
|
148
|
-
# 3. Keep only unique locations after decoding
|
|
149
|
-
def locations_for_display
|
|
150
|
-
unencoded_locs, encoded_locs = locations.partition { |loc| loc.unencoded_value? }
|
|
151
|
-
locs_for_display = unencoded_locs.presence || encoded_locs
|
|
152
|
-
locs_for_display.map(&:to_s).compact_blank.uniq
|
|
116
|
+
Utils.compact_and_join([place_str, date_str], delimiter: ", ")
|
|
153
117
|
end
|
|
154
118
|
|
|
155
119
|
# Union of event's type and its date types.
|
|
@@ -168,34 +132,38 @@ module CocinaDisplay
|
|
|
168
132
|
to_s == date_str
|
|
169
133
|
end
|
|
170
134
|
|
|
171
|
-
# The
|
|
172
|
-
#
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
135
|
+
# The dates associated with this event that should be used for display.
|
|
136
|
+
# Prefers encoded dates when there are duplicates.
|
|
137
|
+
# @return [Array<CocinaDisplay::Dates::Date>]
|
|
138
|
+
def display_dates
|
|
139
|
+
# Choose a single date for each group with the same base value;
|
|
140
|
+
# prefer encoded dates when there are duplicates.
|
|
141
|
+
deduped_dates = dates.group_by(&:base_value).map do |base_value, group|
|
|
142
|
+
if (encoded = group.filter(&:encoding?)).any?
|
|
143
|
+
encoded.first
|
|
144
|
+
else
|
|
145
|
+
group.first
|
|
146
|
+
end
|
|
147
|
+
end
|
|
176
148
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
end
|
|
149
|
+
# Remove any ranges that duplicate part of an encoded non-range date
|
|
150
|
+
ranges, singles = deduped_dates.partition { |date| date.is_a?(CocinaDisplay::Dates::DateRange) }
|
|
151
|
+
encoded_singles_dates = singles.filter(&:encoding?).flat_map(&:to_a)
|
|
152
|
+
ranges.reject! { |date_range| encoded_singles_dates.any? { |date| date_range.as_range.include?(date) } }
|
|
182
153
|
|
|
183
|
-
|
|
184
|
-
# @return [String]
|
|
185
|
-
def copyright_note_str
|
|
186
|
-
Utils.compact_and_join(notes.filter { |note| note.type == "copyright statement" }.map(&:to_s), delimiter: ", ")
|
|
154
|
+
(singles + ranges).sort
|
|
187
155
|
end
|
|
188
156
|
|
|
189
|
-
#
|
|
157
|
+
# Dates associated with this event as a single string.
|
|
190
158
|
# @return [String]
|
|
191
|
-
def
|
|
192
|
-
|
|
159
|
+
def date_str
|
|
160
|
+
display_dates.map(&:qualified_value).compact_blank.uniq.to_sentence
|
|
193
161
|
end
|
|
194
162
|
|
|
195
|
-
#
|
|
163
|
+
# Locations associated with this event as a single string.
|
|
196
164
|
# @return [String]
|
|
197
165
|
def place_str
|
|
198
|
-
|
|
166
|
+
locations.map(&:to_s).compact_blank.uniq.join(", ")
|
|
199
167
|
end
|
|
200
168
|
end
|
|
201
169
|
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module CocinaDisplay
|
|
2
|
+
module Events
|
|
3
|
+
# An imprint statement associated with an object.
|
|
4
|
+
class Imprint < Event
|
|
5
|
+
# Imprints are labelled "Imprint" unless overridden by a displayLabel.
|
|
6
|
+
# @return [String]
|
|
7
|
+
def label
|
|
8
|
+
cocina["displayLabel"].presence || "Imprint"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Imprint statement for a book, formatted using typical conventions.
|
|
12
|
+
# @return [String]
|
|
13
|
+
# @example "2nd ed. - New York : John Doe, 1999"
|
|
14
|
+
def to_s
|
|
15
|
+
place_contrib = Utils.compact_and_join([place_str, contributor_str], delimiter: " : ")
|
|
16
|
+
note_place_contrib = Utils.compact_and_join([edition_note_str, place_contrib], delimiter: " - ")
|
|
17
|
+
Utils.compact_and_join([note_place_contrib, date_str, copyright_note_str], delimiter: ", ")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
# Filter dates for uniqueness using base value according to predefined rules.
|
|
23
|
+
# 1. For a group of dates with the same base value, choose a single one
|
|
24
|
+
# 2. Prefer unencoded dates over encoded ones when choosing a single date
|
|
25
|
+
# 3. Remove date ranges that duplicate any unencoded non-range dates
|
|
26
|
+
# @return [Array<CocinaDisplay::Dates::Date>]
|
|
27
|
+
# @see CocinaDisplay::Dates::Date#base_value
|
|
28
|
+
# @see https://consul.stanford.edu/display/chimera/MODS+display+rules#MODSdisplayrules-3b.%3CoriginInfo%3E
|
|
29
|
+
def display_dates
|
|
30
|
+
# Choose a single date for each group with the same base value
|
|
31
|
+
deduped_dates = dates.group_by(&:base_value).map do |base_value, group|
|
|
32
|
+
if (unencoded = group.reject(&:encoding?)).any?
|
|
33
|
+
unencoded.first
|
|
34
|
+
else
|
|
35
|
+
group.first
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Remove any ranges that duplicate part of an unencoded non-range date
|
|
40
|
+
ranges, singles = deduped_dates.partition { |date| date.is_a?(CocinaDisplay::Dates::DateRange) }
|
|
41
|
+
unencoded_singles_dates = singles.reject(&:encoding?).flat_map(&:to_a)
|
|
42
|
+
ranges.reject! { |date_range| unencoded_singles_dates.any? { |date| date_range.as_range.include?(date) } }
|
|
43
|
+
|
|
44
|
+
(singles + ranges).sort
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Filter locations to display according to predefined rules.
|
|
48
|
+
# 1. Prefer unencoded locations (plain value) over encoded ones
|
|
49
|
+
# 2. If no unencoded locations but there are MARC country codes, decode them
|
|
50
|
+
# 3. Keep only unique locations after decoding
|
|
51
|
+
# @return [Array<String>]
|
|
52
|
+
def display_locations
|
|
53
|
+
unencoded_locs, encoded_locs = locations.partition { |loc| loc.unencoded_value? }
|
|
54
|
+
locs_for_display = unencoded_locs.presence || encoded_locs
|
|
55
|
+
locs_for_display.map(&:to_s).compact_blank.uniq
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Dates associated with this event as a single string.
|
|
59
|
+
# @return [String]
|
|
60
|
+
def date_str
|
|
61
|
+
Utils.compact_and_join(display_dates.map(&:to_s), delimiter: "; ")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Edition notes associated with the event as a single string.
|
|
65
|
+
# @return [String]
|
|
66
|
+
def edition_note_str
|
|
67
|
+
Utils.compact_and_join(notes.filter { |note| note.type == "edition" }.map(&:to_s), delimiter: ", ")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Copyright notes associated with the event as a single string.
|
|
71
|
+
# @return [String]
|
|
72
|
+
def copyright_note_str
|
|
73
|
+
Utils.compact_and_join(notes.filter { |note| note.type == "copyright statement" }.map(&:to_s), delimiter: ", ")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# All contributors associated with the event as a single string.
|
|
77
|
+
# @return [String]
|
|
78
|
+
def contributor_str
|
|
79
|
+
Utils.compact_and_join(contributors.map(&:display_name), delimiter: " : ")
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# The place of publication, combining all location values.
|
|
83
|
+
# @return [String]
|
|
84
|
+
def place_str
|
|
85
|
+
Utils.compact_and_join(display_locations, delimiter: " : ")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
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: 2.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nick Budak
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-03-
|
|
10
|
+
date: 2026-03-26 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: janeway-jsonpath
|
|
@@ -269,6 +269,7 @@ files:
|
|
|
269
269
|
- lib/cocina_display/description/url.rb
|
|
270
270
|
- lib/cocina_display/display_data.rb
|
|
271
271
|
- lib/cocina_display/events/event.rb
|
|
272
|
+
- lib/cocina_display/events/imprint.rb
|
|
272
273
|
- lib/cocina_display/events/location.rb
|
|
273
274
|
- lib/cocina_display/events/note.rb
|
|
274
275
|
- lib/cocina_display/forms/form.rb
|