cocina_display 2.1.0 → 2.2.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/config/locales/en.yml +1 -0
- data/lib/cocina_display/concerns/geospatial.rb +8 -8
- data/lib/cocina_display/concerns/languages.rb +3 -3
- data/lib/cocina_display/concerns/notes.rb +1 -1
- data/lib/cocina_display/concerns/subjects.rb +28 -28
- data/lib/cocina_display/concerns/titles.rb +15 -14
- data/lib/cocina_display/concerns/url_helpers.rb +5 -2
- data/lib/cocina_display/contributors/contributor.rb +2 -12
- data/lib/cocina_display/contributors/name.rb +8 -93
- data/lib/cocina_display/contributors/name_value.rb +78 -0
- data/lib/cocina_display/languages/language.rb +91 -0
- data/lib/cocina_display/languages/script.rb +24 -0
- data/lib/cocina_display/notes/note.rb +37 -0
- data/lib/cocina_display/notes/note_value.rb +123 -0
- data/lib/cocina_display/parallel/parallel.rb +127 -0
- data/lib/cocina_display/parallel/parallel_value.rb +120 -0
- data/lib/cocina_display/related_resource.rb +11 -2
- data/lib/cocina_display/subjects/subject.rb +12 -57
- data/lib/cocina_display/subjects/subject_part.rb +177 -0
- data/lib/cocina_display/subjects/subject_value.rb +29 -160
- data/lib/cocina_display/titles/title.rb +49 -0
- data/lib/cocina_display/titles/title_value.rb +181 -0
- data/lib/cocina_display/version.rb +1 -1
- data/script/deep_compact.rb +2 -0
- data/script/find_records.rb +1 -1
- metadata +13 -6
- data/lib/cocina_display/language.rb +0 -53
- data/lib/cocina_display/note.rb +0 -142
- data/lib/cocina_display/title.rb +0 -213
|
@@ -1,177 +1,46 @@
|
|
|
1
1
|
module CocinaDisplay
|
|
2
2
|
module Subjects
|
|
3
|
-
# A
|
|
4
|
-
class SubjectValue
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# The type of the subject value, like "person", "title", or "time".
|
|
8
|
-
# @see https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md#subject-part-types-for-structured-value
|
|
9
|
-
attr_accessor :type
|
|
10
|
-
|
|
11
|
-
# Create SubjectValues from Cocina structured data.
|
|
12
|
-
# Pre-coordinated string values will be split into multiple SubjectValues.
|
|
13
|
-
# @param cocina [Hash] The Cocina structured data for the subject.
|
|
14
|
-
# @param type [String, nil] The type, coming from the parent Subject.
|
|
15
|
-
# @return [Array<SubjectValue>]
|
|
16
|
-
def self.from_cocina(cocina, type:)
|
|
17
|
-
split_pre_coordinated_values(cocina, type: type).map do |value|
|
|
18
|
-
SUBJECT_VALUE_TYPES.fetch(type, SubjectValue).new(value).tap do |obj|
|
|
19
|
-
obj.type ||= type
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Split a pre-coordinated subject value joined with "--" into multiple values.
|
|
25
|
-
# Ignores the "--" string for coordinate subject types, which use it differently.
|
|
26
|
-
# @param cocina [Hash] The Cocina structured data for the subject.
|
|
27
|
-
# @return [Array<Hash>] An array of Cocina hashes, one for each split value
|
|
28
|
-
def self.split_pre_coordinated_values(cocina, type:)
|
|
29
|
-
if cocina["value"].is_a?(String) && cocina["value"].include?("--") && !type&.include?("coordinates")
|
|
30
|
-
cocina["value"].split("--").map { |v| cocina.merge("value" => v.strip) }
|
|
31
|
-
else
|
|
32
|
-
[cocina]
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# All subject value types that should not be further destructured.
|
|
3
|
+
# A subject in Cocina structured data in a single language/script.
|
|
4
|
+
class SubjectValue < Parallel::ParallelValue
|
|
5
|
+
# Array of display strings for each part of the subject.
|
|
6
|
+
# Used for search, where each value should be indexed separately.
|
|
37
7
|
# @return [Array<String>]
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Initialize a SubjectValue object with Cocina structured data.
|
|
43
|
-
# @param cocina [Hash] The Cocina structured data for the subject value.
|
|
44
|
-
def initialize(cocina)
|
|
45
|
-
@cocina = cocina
|
|
46
|
-
@type = cocina["type"]
|
|
8
|
+
def values
|
|
9
|
+
subject_parts.map(&:to_s).compact_blank
|
|
47
10
|
end
|
|
48
11
|
|
|
49
|
-
# The
|
|
50
|
-
#
|
|
12
|
+
# The value to use for display.
|
|
13
|
+
# Genre values are capitalized; other subject values are not.
|
|
51
14
|
# @return [String]
|
|
52
15
|
def to_s
|
|
53
|
-
|
|
16
|
+
(type == "genre") ? flat_value&.upcase_first : flat_value
|
|
54
17
|
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# A subject value representing a named entity.
|
|
58
|
-
class NameSubjectValue < SubjectValue
|
|
59
|
-
attr_reader :name
|
|
60
|
-
|
|
61
|
-
# Initialize a NameSubjectValue object with Cocina structured data.
|
|
62
|
-
# @param cocina [Hash] The Cocina structured data for the subject.
|
|
63
|
-
def initialize(cocina)
|
|
64
|
-
super
|
|
65
|
-
@name = Contributors::Name.new(cocina)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Use the contributor name formatting rules for display.
|
|
69
|
-
# @return [String] The formatted name string, including life dates
|
|
70
|
-
# @see CocinaDisplay::Contributor::Name#to_s
|
|
71
|
-
def to_s
|
|
72
|
-
name.to_s(with_date: true)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# A subject value representing an entity with a title.
|
|
77
|
-
class TitleSubjectValue < SubjectValue
|
|
78
|
-
attr_reader :title
|
|
79
18
|
|
|
80
|
-
#
|
|
81
|
-
# @
|
|
82
|
-
def
|
|
83
|
-
|
|
84
|
-
@title = Title.new(cocina)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Construct a title string to use for display.
|
|
88
|
-
# @see CocinaDisplay::Title#to_s
|
|
89
|
-
# @return [String, nil]
|
|
90
|
-
def to_s
|
|
91
|
-
title.to_s
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# A subject value representing a date and/or time.
|
|
96
|
-
class TemporalSubjectValue < SubjectValue
|
|
97
|
-
attr_reader :date
|
|
98
|
-
|
|
99
|
-
def initialize(cocina)
|
|
100
|
-
super
|
|
101
|
-
@date = Dates::Date.from_cocina(cocina)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# @return [String] The formatted date/time string for display
|
|
105
|
-
def to_s
|
|
106
|
-
date.to_s
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# A subject value representing a named place.
|
|
111
|
-
class PlaceSubjectValue < SubjectValue
|
|
112
|
-
# A URI identifying the place, if available.
|
|
113
|
-
# @return [String, nil]
|
|
114
|
-
def uri
|
|
115
|
-
cocina["uri"]
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# True if the place has a geonames.org URI.
|
|
119
|
-
# @return [Boolean]
|
|
120
|
-
def geonames?
|
|
121
|
-
uri&.include?("sws.geonames.org")
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Unique identifier for the place in geonames.org.
|
|
125
|
-
# @return [String, nil]
|
|
126
|
-
def geonames_id
|
|
127
|
-
uri&.split("/")&.last if geonames?
|
|
19
|
+
# A string representation of the entire subject, concatenated for display.
|
|
20
|
+
# @return [String]
|
|
21
|
+
def flat_value
|
|
22
|
+
Utils.compact_and_join(values, delimiter: delimiter)
|
|
128
23
|
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# A subject value containing geographic coordinates, like a point or box.
|
|
132
|
-
class CoordinatesSubjectValue < SubjectValue
|
|
133
|
-
attr_reader :coordinates
|
|
134
24
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
25
|
+
# Delimiter used to join the individual parts of the subject for display.
|
|
26
|
+
# @return [String]
|
|
27
|
+
def delimiter
|
|
28
|
+
" > "
|
|
138
29
|
end
|
|
139
30
|
|
|
140
|
-
#
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
|
|
144
|
-
|
|
31
|
+
# Individual SubjectParts composing this subject.
|
|
32
|
+
# Can be multiple if the Cocina featured structuredValues.
|
|
33
|
+
# All SubjectParts inherit the type of their parent Subject.
|
|
34
|
+
# @return [Array<SubjectPart>]
|
|
35
|
+
def subject_parts
|
|
36
|
+
@subject_parts ||= if SubjectPart.atomic_types.include?(type)
|
|
37
|
+
SubjectPart.from_cocina(cocina, type: type)
|
|
38
|
+
else
|
|
39
|
+
Utils.flatten_nested_values(cocina, atomic_types: SubjectPart.atomic_types).flat_map do |value|
|
|
40
|
+
SubjectPart.from_cocina(value, type: value["type"] || type)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
145
43
|
end
|
|
146
44
|
end
|
|
147
45
|
end
|
|
148
46
|
end
|
|
149
|
-
|
|
150
|
-
# Map Cocina subject types to specific SubjectValue classes for rendering.
|
|
151
|
-
# @see SubjectValue#type
|
|
152
|
-
SUBJECT_VALUE_TYPES = {
|
|
153
|
-
"person" => CocinaDisplay::Subjects::NameSubjectValue,
|
|
154
|
-
"family" => CocinaDisplay::Subjects::NameSubjectValue,
|
|
155
|
-
"organization" => CocinaDisplay::Subjects::NameSubjectValue,
|
|
156
|
-
"conference" => CocinaDisplay::Subjects::NameSubjectValue,
|
|
157
|
-
"event" => CocinaDisplay::Subjects::NameSubjectValue,
|
|
158
|
-
"name" => CocinaDisplay::Subjects::NameSubjectValue,
|
|
159
|
-
"title" => CocinaDisplay::Subjects::TitleSubjectValue,
|
|
160
|
-
"time" => CocinaDisplay::Subjects::TemporalSubjectValue,
|
|
161
|
-
"area" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
162
|
-
"city" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
163
|
-
"city section" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
164
|
-
"continent" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
165
|
-
"country" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
166
|
-
"county" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
167
|
-
"coverage" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
168
|
-
"extraterrestrial area" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
169
|
-
"island" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
170
|
-
"place" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
171
|
-
"region" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
172
|
-
"state" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
173
|
-
"territory" => CocinaDisplay::Subjects::PlaceSubjectValue,
|
|
174
|
-
"point coordinates" => CocinaDisplay::Subjects::CoordinatesSubjectValue,
|
|
175
|
-
"map coordinates" => CocinaDisplay::Subjects::CoordinatesSubjectValue,
|
|
176
|
-
"bounding box coordinates" => CocinaDisplay::Subjects::CoordinatesSubjectValue
|
|
177
|
-
}.freeze
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module CocinaDisplay
|
|
2
|
+
module Titles
|
|
3
|
+
# A Title represented by one or more {TitleValue}s in various languages/scripts.
|
|
4
|
+
class Title < Parallel::Parallel
|
|
5
|
+
# Part data for digital serials, coming from elsewhere in the Cocina.
|
|
6
|
+
attr_reader :part_label, :part_numbers
|
|
7
|
+
|
|
8
|
+
# Common display methods reference the main title value. For parallel
|
|
9
|
+
# values, see #translated_value and #transliterated_value.
|
|
10
|
+
delegate :short_title, :full_title, :display_title, :sort_title, to: :main_value
|
|
11
|
+
|
|
12
|
+
# Create a new Title object.
|
|
13
|
+
# @param cocina [Hash]
|
|
14
|
+
# @param part_label [String, nil] part label for digital serials
|
|
15
|
+
# @param part_numbers [Array<String>] part numbers for related resources
|
|
16
|
+
def initialize(cocina, part_label: nil, part_numbers: nil)
|
|
17
|
+
super(cocina)
|
|
18
|
+
@part_label = part_label
|
|
19
|
+
@part_numbers = part_numbers
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Label used when displaying the title.
|
|
23
|
+
# @return [String]
|
|
24
|
+
def label
|
|
25
|
+
display_label || type_label
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The string representation of the title, for display.
|
|
29
|
+
# @return [String, nil]
|
|
30
|
+
def to_s
|
|
31
|
+
display_title
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# Type-specific label for the title, falling back to a generic "Title".
|
|
37
|
+
# @return [String]
|
|
38
|
+
def type_label
|
|
39
|
+
I18n.t(type&.parameterize&.underscore, scope: "cocina_display.field_label.title", default: :title)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# The class to use for parallel values.
|
|
43
|
+
# @return [Class]
|
|
44
|
+
def parallel_value_class
|
|
45
|
+
TitleValue
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
module CocinaDisplay
|
|
2
|
+
module Titles
|
|
3
|
+
# A Title associated with an item in a single language.
|
|
4
|
+
class TitleValue < Parallel::ParallelValue
|
|
5
|
+
# Part types for structured titles.
|
|
6
|
+
# @see https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md#title-part-types-for-structured-value
|
|
7
|
+
PART_TYPES = ["main title", "nonsorting characters", "part name", "part number", "subtitle"].freeze
|
|
8
|
+
|
|
9
|
+
# Inherit part data from the parent title.
|
|
10
|
+
delegate :part_label, :part_numbers, to: :parent, allow_nil: true
|
|
11
|
+
|
|
12
|
+
# Custom label used when displaying the title, if any.
|
|
13
|
+
# @return [String, nil]
|
|
14
|
+
def label
|
|
15
|
+
display_label || type_label
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# The string representation of the title, for display.
|
|
19
|
+
# @see #display_title
|
|
20
|
+
# @return [String, nil]
|
|
21
|
+
def to_s
|
|
22
|
+
display_title
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# The short form of the title, without subtitle, part name, etc.
|
|
26
|
+
# @note This corresponds to the "short title" in MODS XML, or MARC 245$a only.
|
|
27
|
+
# @return [String, nil]
|
|
28
|
+
# @example "M. de Courville"
|
|
29
|
+
def short_title
|
|
30
|
+
short_title_str.presence || cocina["value"]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The long form of the title, including subtitle, part name, etc.
|
|
34
|
+
# @note This corresponds to the entire MARC 245 field.
|
|
35
|
+
# @return [String, nil]
|
|
36
|
+
# @example "M. de Courville : [estampe]"
|
|
37
|
+
def full_title
|
|
38
|
+
full_title_str.presence || cocina["value"]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# The long form of the title, without trailing punctuation.
|
|
42
|
+
# @note This corresponds to the entire MARC 245 field.
|
|
43
|
+
# @return [String, nil]
|
|
44
|
+
def display_title
|
|
45
|
+
display_title_str.presence || cocina["value"]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# A string value for sorting by title.
|
|
49
|
+
# Ignores punctuation, leading/trailing spaces, and non-sorting characters.
|
|
50
|
+
# If no title is present, returns a high Unicode value so it sorts last.
|
|
51
|
+
# @return [String]
|
|
52
|
+
def sort_title
|
|
53
|
+
return "\u{10FFFF}" unless full_title
|
|
54
|
+
|
|
55
|
+
full_title[nonsorting_chars_str.length..]
|
|
56
|
+
.unicode_normalize(:nfd) # Prevent accents being stripped
|
|
57
|
+
.gsub(/[[:punct:]]*/, "")
|
|
58
|
+
.gsub(/\W{2,}/, " ") # Collapse whitespace after removing punctuation
|
|
59
|
+
.strip
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
# Generate the short title by joining main title and nonsorting characters.
|
|
65
|
+
# @return [String, nil]
|
|
66
|
+
def short_title_str
|
|
67
|
+
nonsorting_chars_str + main_title_str # pre-formatted padding
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Generate the full title by joining all title components with punctuation.
|
|
71
|
+
# @return [String, nil]
|
|
72
|
+
def full_title_str
|
|
73
|
+
title_str = main_subtitle_str
|
|
74
|
+
title_str = Utils.compact_and_join([main_subtitle_str, parts_str], delimiter: ". ") unless main_subtitle_str.end_with?(parts_str)
|
|
75
|
+
title_str = nonsorting_chars_str + title_str # pre-formatted padding
|
|
76
|
+
title_str = Utils.compact_and_join([names_str, title_str], delimiter: ". ") if names_str.present?
|
|
77
|
+
title_str += "." unless title_str&.match?(/[[:punct:]]\z/)
|
|
78
|
+
title_str.presence
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Generate the display title by stripping trailing punctuation from the full title.
|
|
82
|
+
# @return [String, nil]
|
|
83
|
+
def display_title_str
|
|
84
|
+
full_title_str&.sub(/[.,;:\/\\]+\z/, "")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# The main title and subtitle, joined together with a colon.
|
|
88
|
+
# @return [String, nil]
|
|
89
|
+
def main_subtitle_str
|
|
90
|
+
Utils.compact_and_join([main_title_str, subtitle_str], delimiter: " : ")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# All nonsorting characters joined together with padding applied.
|
|
94
|
+
# Handles languages that do not separate nonsorting characters with spaces.
|
|
95
|
+
# @return [String, nil]
|
|
96
|
+
def nonsorting_chars_str
|
|
97
|
+
pad_nonsorting(Utils.compact_and_join(Array(title_components["nonsorting characters"])))
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# The main title component(s), joined together.
|
|
101
|
+
# @return [String, nil]
|
|
102
|
+
def main_title_str
|
|
103
|
+
Utils.compact_and_join(Array(title_components["main title"]))
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# The subtitle components, joined together.
|
|
107
|
+
# @return [String, nil]
|
|
108
|
+
def subtitle_str
|
|
109
|
+
Utils.compact_and_join(Array(title_components["subtitle"]))
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# The part name, number, and label components, joined together with commas.
|
|
113
|
+
# @return [String, nil]
|
|
114
|
+
def parts_str
|
|
115
|
+
Utils.compact_and_join(
|
|
116
|
+
Array(title_components["part number"] || part_numbers) +
|
|
117
|
+
Array(title_components["part name"]) +
|
|
118
|
+
[part_label],
|
|
119
|
+
delimiter: ", "
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# The associated names, joined together with periods.
|
|
124
|
+
# @note Only present for uniform titles.
|
|
125
|
+
# @return [String, nil]
|
|
126
|
+
def names_str
|
|
127
|
+
Utils.compact_and_join(names, delimiter: ". ")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Destructured title components, organized by type.
|
|
131
|
+
# Unstructured titles and components with no type are grouped under "main title".
|
|
132
|
+
# @return [Hash<String, Array<String>>]
|
|
133
|
+
# @see https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md#title-part-types-for-structured-value
|
|
134
|
+
def title_components
|
|
135
|
+
Utils.flatten_nested_values(cocina).each_with_object({}) do |node, hash|
|
|
136
|
+
type = PART_TYPES.find { |t| t == node["type"] } || "main title"
|
|
137
|
+
hash[type] ||= []
|
|
138
|
+
hash[type] << node["value"]
|
|
139
|
+
end.compact_blank
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Uniform titles can have associated person names.
|
|
143
|
+
# @return [String, nil]
|
|
144
|
+
def names
|
|
145
|
+
Janeway.enum_for("$.note[?(@.type=='associated name')]", cocina).map do |name|
|
|
146
|
+
Contributors::Name.new(name).to_s(with_date: true)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Number of nonsorting characters to ignore at the start of the title.
|
|
151
|
+
# @return [Integer, nil]
|
|
152
|
+
def nonsorting_char_count
|
|
153
|
+
Janeway.enum_for("$.note[?(@.type=='nonsorting character count')].value", cocina).first&.to_i
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Add or remove padding from nonsorting portion of the title.
|
|
157
|
+
# @param value [String]
|
|
158
|
+
# @return [String]
|
|
159
|
+
def pad_nonsorting(value)
|
|
160
|
+
case value.strip
|
|
161
|
+
when /.*-$/, /.*'$/, "ה" # Arabic, French, Hebrew prefixes use no padding
|
|
162
|
+
value.strip
|
|
163
|
+
when "" # No nonsorting characters; return empty string
|
|
164
|
+
""
|
|
165
|
+
else # Pad to nonsorting char count if set, otherwise add a single space
|
|
166
|
+
if nonsorting_char_count.present?
|
|
167
|
+
value.ljust(nonsorting_char_count, " ")
|
|
168
|
+
else
|
|
169
|
+
value + " "
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Type-specific label for the title, falling back to a generic "Title".
|
|
175
|
+
# @return [String]
|
|
176
|
+
def type_label
|
|
177
|
+
I18n.t(type&.parameterize&.underscore, scope: "cocina_display.field_label.title", default: :title)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
data/script/deep_compact.rb
CHANGED
data/script/find_records.rb
CHANGED
|
@@ -28,7 +28,7 @@ RELEASE_TARGET = "Searchworks"
|
|
|
28
28
|
|
|
29
29
|
# Modify this expression to match the JSON path you want to search, or just
|
|
30
30
|
# modify the `examine_record` method directly.
|
|
31
|
-
PATH_EXPR = "$..[?
|
|
31
|
+
PATH_EXPR = "$..[? @.type == 'parallel' ]"
|
|
32
32
|
|
|
33
33
|
# Modify this method as needed to change what you're looking for in each record.
|
|
34
34
|
# It takes a CocinaRecord object and should return an array of [path, result] pairs.
|
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.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nick Budak
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: janeway-jsonpath
|
|
@@ -261,6 +261,7 @@ files:
|
|
|
261
261
|
- lib/cocina_display/contributors/affiliation.rb
|
|
262
262
|
- lib/cocina_display/contributors/contributor.rb
|
|
263
263
|
- lib/cocina_display/contributors/name.rb
|
|
264
|
+
- lib/cocina_display/contributors/name_value.rb
|
|
264
265
|
- lib/cocina_display/contributors/role.rb
|
|
265
266
|
- lib/cocina_display/dates/date.rb
|
|
266
267
|
- lib/cocina_display/dates/date_range.rb
|
|
@@ -278,15 +279,21 @@ files:
|
|
|
278
279
|
- lib/cocina_display/geospatial.rb
|
|
279
280
|
- lib/cocina_display/identifier.rb
|
|
280
281
|
- lib/cocina_display/json_backed_record.rb
|
|
281
|
-
- lib/cocina_display/language.rb
|
|
282
|
+
- lib/cocina_display/languages/language.rb
|
|
283
|
+
- lib/cocina_display/languages/script.rb
|
|
282
284
|
- lib/cocina_display/license.rb
|
|
283
|
-
- lib/cocina_display/note.rb
|
|
285
|
+
- lib/cocina_display/notes/note.rb
|
|
286
|
+
- lib/cocina_display/notes/note_value.rb
|
|
287
|
+
- lib/cocina_display/parallel/parallel.rb
|
|
288
|
+
- lib/cocina_display/parallel/parallel_value.rb
|
|
284
289
|
- lib/cocina_display/related_resource.rb
|
|
285
290
|
- lib/cocina_display/structural/file.rb
|
|
286
291
|
- lib/cocina_display/structural/file_set.rb
|
|
287
292
|
- lib/cocina_display/subjects/subject.rb
|
|
293
|
+
- lib/cocina_display/subjects/subject_part.rb
|
|
288
294
|
- lib/cocina_display/subjects/subject_value.rb
|
|
289
|
-
- lib/cocina_display/title.rb
|
|
295
|
+
- lib/cocina_display/titles/title.rb
|
|
296
|
+
- lib/cocina_display/titles/title_value.rb
|
|
290
297
|
- lib/cocina_display/utils.rb
|
|
291
298
|
- lib/cocina_display/version.rb
|
|
292
299
|
- script/deep_compact.rb
|
|
@@ -312,7 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
312
319
|
- !ruby/object:Gem::Version
|
|
313
320
|
version: '0'
|
|
314
321
|
requirements: []
|
|
315
|
-
rubygems_version:
|
|
322
|
+
rubygems_version: 4.0.7
|
|
316
323
|
specification_version: 4
|
|
317
324
|
summary: Helpers for rendering Cocina metadata
|
|
318
325
|
test_files: []
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module CocinaDisplay
|
|
4
|
-
# A language associated with part or all of a Cocina object.
|
|
5
|
-
class Language
|
|
6
|
-
SEARCHWORKS_LANGUAGES_FILE_PATH = CocinaDisplay.root / "config" / "searchworks_languages.yml"
|
|
7
|
-
|
|
8
|
-
attr_reader :cocina
|
|
9
|
-
|
|
10
|
-
# A hash of language codes to language names recognized by Searchworks.
|
|
11
|
-
# @return [Hash{String => String}]
|
|
12
|
-
def self.searchworks_languages
|
|
13
|
-
@searchworks_languages ||= YAML.safe_load_file(SEARCHWORKS_LANGUAGES_FILE_PATH)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Create a Language object from Cocina structured data.
|
|
17
|
-
# @param cocina [Hash]
|
|
18
|
-
def initialize(cocina)
|
|
19
|
-
@cocina = cocina
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# The language name for display.
|
|
23
|
-
# @return [String, nil]
|
|
24
|
-
def to_s
|
|
25
|
-
cocina["value"] || decoded_value
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# The language code, e.g. an ISO 639 code like "eng" or "spa".
|
|
29
|
-
# @return [String, nil]
|
|
30
|
-
def code
|
|
31
|
-
cocina["code"]
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Decoded name of the language based on the code, if present.
|
|
35
|
-
# @return [String, nil]
|
|
36
|
-
def decoded_value
|
|
37
|
-
Language.searchworks_languages[code] if searchworks_language?
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# Display label for this field.
|
|
41
|
-
# @return [String]
|
|
42
|
-
def label
|
|
43
|
-
cocina["displayLabel"].presence || I18n.t("cocina_display.field_label.language")
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# True if the language is recognized by Searchworks.
|
|
47
|
-
# @see CocinaDisplay::Language.searchworks_languages
|
|
48
|
-
# @return [Boolean]
|
|
49
|
-
def searchworks_language?
|
|
50
|
-
Language.searchworks_languages.value?(cocina["value"]) || Language.searchworks_languages.key?(code)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|