pennmarc 1.0.18 → 1.0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pennmarc/helpers/creator.rb +55 -58
- data/lib/pennmarc/helpers/edition.rb +1 -1
- data/lib/pennmarc/helpers/format.rb +58 -66
- data/lib/pennmarc/helpers/genre.rb +4 -6
- data/lib/pennmarc/helpers/identifier.rb +1 -1
- data/lib/pennmarc/helpers/note.rb +8 -8
- data/lib/pennmarc/helpers/production.rb +1 -1
- data/lib/pennmarc/helpers/relation.rb +33 -35
- data/lib/pennmarc/helpers/title.rb +5 -5
- data/lib/pennmarc/mappings/locations.yml +4 -0
- data/lib/pennmarc/util.rb +63 -2
- data/lib/pennmarc/version.rb +1 -1
- data/spec/lib/pennmarc/helpers/creator_spec.rb +140 -56
- data/spec/lib/pennmarc/helpers/format_spec.rb +156 -27
- data/spec/lib/pennmarc/helpers/genre_spec.rb +3 -7
- data/spec/lib/pennmarc/helpers/note_spec.rb +3 -2
- data/spec/lib/pennmarc/helpers/relation_spec.rb +47 -3
- data/spec/lib/pennmarc/marc_util_spec.rb +118 -0
- 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: 5cec796509d9822289de751b33395fa6de1c1c23fdbdf78de54de11152674733
|
4
|
+
data.tar.gz: 9a2aa7d1ca7c7bd27627fac7f676492100eb36cb823469fd5b7e987244795cee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2076675bbbc9bc38f3c36ba0932211ee4726d618de8d3781cae5d314576162b13bd256918910e534b638cd601a5f0e2db0936c7e8fd7fb58f1788ef1f28552d2
|
7
|
+
data.tar.gz: d963b043b08eff3567d904b18d938cddd3edc7a8d5238c720203cce52657cc86f6f20445e3d1c0de7221c628822990c87ea4cb0a2191b33b49992f8d6fa87ac9
|
@@ -19,6 +19,8 @@ module PennMARC
|
|
19
19
|
# subfields NOT to join when combining raw subfield values
|
20
20
|
NAME_EXCLUDED_SUBFIELDS = %w[a 1 4 5 6 8 t].freeze
|
21
21
|
|
22
|
+
CONTRIBUTOR_TAGS = %w[700 710].freeze
|
23
|
+
|
22
24
|
# Author/Creator search field. Includes all subfield values (even ǂ0 URIs) from
|
23
25
|
# {https://www.oclc.org/bibformats/en/1xx/100.html 100 Main Entry--Personal Name} and
|
24
26
|
# {https://www.oclc.org/bibformats/en/1xx/110.html 110 Main Entry--Corporate Name}. Maps any relator codes found
|
@@ -48,27 +50,29 @@ module PennMARC
|
|
48
50
|
name_search_values record: record, tags: AUX_TAGS, relator_map: relator_map
|
49
51
|
end
|
50
52
|
|
51
|
-
#
|
52
|
-
#
|
53
|
+
# Retrieve creator values for display from fields {https://www.loc.gov/marc/bibliographic/bd100.html 100}
|
54
|
+
# and {https://www.loc.gov/marc/bibliographic/bd110.html 110} and their linked alternates. Appends any encoded
|
55
|
+
# relationships found in $4. If there are no valid encoded relationships, uses the value found in $e.
|
53
56
|
# @param [MARC::Record] record
|
54
|
-
# @param [Hash] relator_map
|
55
57
|
# @return [Array<String>] array of author/creator values for display
|
56
|
-
def
|
57
|
-
record.fields(TAGS)
|
58
|
-
|
59
|
-
|
58
|
+
def show(record, relator_map: Mappers.relator)
|
59
|
+
fields = record.fields(TAGS)
|
60
|
+
fields += record.fields('880').select { |field| subfield_value?(field, '6', /^(#{TAGS.join('|')})/) }
|
61
|
+
fields.filter_map { |field|
|
62
|
+
creator = join_subfields(field, &subfield_not_in?(%w[0 1 4 6 8 e w]))
|
63
|
+
append_relator(field: field, joined_subfields: creator, relator_term_sf: 'e', relator_map: relator_map)
|
64
|
+
}.uniq
|
60
65
|
end
|
61
66
|
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
67
|
+
# All author/creator values for display (like #show, but multivalued?) - no 880 linkage
|
68
|
+
# Performs additional normalization of author names
|
69
|
+
# @note ported from get_author_creator_values (indexed as author_creator_a) - shown on results page
|
65
70
|
# @param [MARC::Record] record
|
71
|
+
# @param [Hash] relator_map
|
66
72
|
# @return [Array<String>] array of author/creator values for display
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
fields.filter_map { |field|
|
71
|
-
join_subfields(field, &subfield_not_in?(%w[0 1 4 6 8 e w]))
|
73
|
+
def show_aux(record, relator_map: Mappers.relator)
|
74
|
+
record.fields(TAGS).map { |field|
|
75
|
+
name_from_main_entry(field, relator_map)
|
72
76
|
}.uniq
|
73
77
|
end
|
74
78
|
|
@@ -118,8 +122,8 @@ module PennMARC
|
|
118
122
|
# @todo what is ǂi for?
|
119
123
|
# @param [MARC::Record] record
|
120
124
|
# @return [Array<String>] array of conference values
|
121
|
-
def conference_detail_show(record)
|
122
|
-
|
125
|
+
def conference_detail_show(record, relator_map: Mappers.relator)
|
126
|
+
conferences = record.fields(%w[111 711]).filter_map do |field|
|
123
127
|
next unless field.indicator2.in? ['', ' ']
|
124
128
|
|
125
129
|
conf = if subfield_undefined? field, 'i'
|
@@ -127,17 +131,21 @@ module PennMARC
|
|
127
131
|
else
|
128
132
|
''
|
129
133
|
end
|
130
|
-
|
131
|
-
|
134
|
+
sub_unit = join_subfields(field, &subfield_in?(%w[e w]))
|
135
|
+
conf = [conf, sub_unit].compact_blank.join(' ')
|
136
|
+
|
137
|
+
append_relator(field: field, joined_subfields: conf, relator_term_sf: 'j', relator_map: relator_map)
|
132
138
|
end
|
133
|
-
conferences
|
134
|
-
next unless
|
139
|
+
conferences += record.fields('880').filter_map do |field|
|
140
|
+
next unless subfield_value? field, '6', /^(111|711)/
|
135
141
|
|
136
142
|
next if subfield_defined? field, 'i'
|
137
143
|
|
138
144
|
conf = join_subfields(field, &subfield_not_in?(%w[0 4 5 6 8 e j w]))
|
139
|
-
|
140
|
-
|
145
|
+
sub_unit = join_subfields(field, &subfield_in?(%w[e w]))
|
146
|
+
conf = [conf, sub_unit].compact_blank.join(' ')
|
147
|
+
|
148
|
+
append_relator(field: field, joined_subfields: conf, relator_term_sf: 'j', relator_map: relator_map)
|
141
149
|
end
|
142
150
|
conferences.uniq
|
143
151
|
end
|
@@ -153,39 +161,24 @@ module PennMARC
|
|
153
161
|
|
154
162
|
# Retrieve contributor values for display from fields {https://www.oclc.org/bibformats/en/7xx/700.html 700}
|
155
163
|
# and {https://www.oclc.org/bibformats/en/7xx/710.html 710} and their linked alternates. Joins subfields
|
156
|
-
# 'a', 'b', 'c', 'd', 'j', and 'q'. Then appends resulting string with
|
164
|
+
# 'a', 'b', 'c', 'd', 'j', and 'q', 'u', and '3'. Then appends resulting string with any encoded relationships
|
165
|
+
# found in $4. If there are no valid encoded relationships, uses the value found in $e.
|
157
166
|
# @note legacy version returns array of hash objects including data for display link
|
167
|
+
# @todo is it okay to include 880 $4 here? Legacy includes $4 in main author display 880 but not here.
|
158
168
|
# @param [MARC::Record] record
|
159
169
|
# @ param [Hash] relator_map
|
160
170
|
# @return [Array<String>]
|
161
171
|
def contributor_show(record, relator_map: Mappers.relator)
|
162
172
|
indicator_2_options = ['', ' ', '0']
|
163
|
-
|
164
|
-
|
173
|
+
fields = record.fields(CONTRIBUTOR_TAGS)
|
174
|
+
fields += record.fields('880').select { |f| subfield_value?(f, '6', /^(#{CONTRIBUTOR_TAGS.join('|')})/) }
|
175
|
+
fields.filter_map { |field|
|
176
|
+
next if indicator_2_options.exclude?(field.indicator2) && field.tag.in?(CONTRIBUTOR_TAGS)
|
165
177
|
next if subfield_defined? field, 'i'
|
166
178
|
|
167
|
-
contributor = join_subfields(field, &subfield_in?(%w[a b c d j q]))
|
168
|
-
|
169
|
-
|
170
|
-
next unless contributor_append_subfields.member?(subfield.code)
|
171
|
-
|
172
|
-
if subfield.code == '4'
|
173
|
-
", #{translate_relator(subfield.value, relator_map)}"
|
174
|
-
else
|
175
|
-
" #{subfield.value}"
|
176
|
-
end
|
177
|
-
}.join
|
178
|
-
"#{contributor} #{contributor_append}".squish
|
179
|
-
end
|
180
|
-
contributors = values + record.fields('880').filter_map do |field|
|
181
|
-
next unless subfield_value_in?(field, '6', %w[700 710])
|
182
|
-
next if subfield_defined?(field, 'i')
|
183
|
-
|
184
|
-
contributor = join_subfields(field, &subfield_in?(%w[a b c d j q]))
|
185
|
-
contributor_append = join_subfields(field, &subfield_in?(%w[e u 3]))
|
186
|
-
"#{contributor} #{contributor_append}".squish
|
187
|
-
end
|
188
|
-
contributors.uniq
|
179
|
+
contributor = join_subfields(field, &subfield_in?(%w[a b c d j q u 3]))
|
180
|
+
append_relator(field: field, joined_subfields: contributor, relator_term_sf: 'e', relator_map: relator_map)
|
181
|
+
}.uniq
|
189
182
|
end
|
190
183
|
|
191
184
|
private
|
@@ -204,7 +197,7 @@ module PennMARC
|
|
204
197
|
end
|
205
198
|
|
206
199
|
acc += record.fields(['880']).filter_map do |field|
|
207
|
-
next unless field
|
200
|
+
next unless subfield_value?(field, '6', /^(#{tags.join('|')})/)
|
208
201
|
|
209
202
|
suba = field.find_all(&subfield_in?(%w[a])).filter_map { |sf|
|
210
203
|
convert_name_order(sf.value)
|
@@ -242,19 +235,23 @@ module PennMARC
|
|
242
235
|
# @param [Boolean] should_convert_name_order
|
243
236
|
# @return [String] joined subfield values for value from field
|
244
237
|
def name_from_main_entry(field, mapping, should_convert_name_order: false)
|
245
|
-
|
238
|
+
relator_term_sf = relator_term_subfield(field)
|
239
|
+
name = field.filter_map { |sf|
|
246
240
|
if sf.code == 'a'
|
247
241
|
should_convert_name_order ? convert_name_order(sf.value) : sf.value
|
242
|
+
elsif sf.code == relator_term_sf
|
243
|
+
next
|
248
244
|
elsif NAME_EXCLUDED_SUBFIELDS.exclude?(sf.code)
|
249
|
-
|
250
|
-
elsif sf.code == '4'
|
251
|
-
relator = translate_relator(sf.value, mapping)
|
252
|
-
next if relator.blank?
|
253
|
-
|
254
|
-
", #{relator}"
|
245
|
+
sf.value
|
255
246
|
end
|
256
|
-
}.join
|
257
|
-
|
247
|
+
}.join(' ')
|
248
|
+
|
249
|
+
name_and_relator = append_relator(field: field,
|
250
|
+
joined_subfields: name,
|
251
|
+
relator_term_sf: relator_term_sf,
|
252
|
+
relator_map: mapping)
|
253
|
+
|
254
|
+
name_and_relator + (%w[. -].member?(name_and_relator.last) ? '' : '.')
|
258
255
|
end
|
259
256
|
|
260
257
|
# Convert "Lastname, First" to "First Lastname"
|
@@ -44,7 +44,7 @@ module PennMARC
|
|
44
44
|
other_edition_value(field, relator_map)
|
45
45
|
end
|
46
46
|
editions = values + record.fields('880').filter_map do |field|
|
47
|
-
next unless field.indicator2.blank? &&
|
47
|
+
next unless field.indicator2.blank? && subfield_value?(field, '6', /^775/) &&
|
48
48
|
subfield_defined?(field, 'i')
|
49
49
|
|
50
50
|
other_edition_value(field, relator_map)
|
@@ -26,6 +26,9 @@ module PennMARC
|
|
26
26
|
VIDEO = 'Video'
|
27
27
|
WEBSITE_DATABASE = 'Website/Database'
|
28
28
|
|
29
|
+
# Values encoded in MARC that we use to determine "Archive" format
|
30
|
+
ARCHIVE_LOCATIONS = %w[archarch musearch scfreed univarch archivcoll].freeze
|
31
|
+
|
29
32
|
# Get any Format values from {https://www.oclc.org/bibformats/en/3xx/300.html 300},
|
30
33
|
# 254, 255, 310, 342, 352, 362 or {https://www.oclc.org/bibformats/en/3xx/340.html 340} field. based on the source
|
31
34
|
# field, different subfields are used.
|
@@ -40,7 +43,7 @@ module PennMARC
|
|
40
43
|
results += record.fields('340').map { |f| join_subfields(f, &subfield_not_in?(%w[0 2 6 8])) }
|
41
44
|
results += record.fields('880').map do |f|
|
42
45
|
# skip any 880s associated with non format fields
|
43
|
-
next unless
|
46
|
+
next unless subfield_value?(f, '6', /^(254|255|300|310|340|342|352|362)/)
|
44
47
|
|
45
48
|
subfield_to_ignore = if subfield_value?(f, 6, /^300/)
|
46
49
|
%w[3 6 8]
|
@@ -74,7 +77,7 @@ module PennMARC
|
|
74
77
|
# @param [Hash] location_map
|
75
78
|
# @return [Array<String>] format values for faceting
|
76
79
|
|
77
|
-
def facet(record
|
80
|
+
def facet(record)
|
78
81
|
formats = []
|
79
82
|
format_code = leader_format(record.leader)
|
80
83
|
f007 = record.fields('007').map(&:value)
|
@@ -83,49 +86,29 @@ module PennMARC
|
|
83
86
|
title_medium = subfield_values_for tag: '245', subfield: :h, record: record
|
84
87
|
media_type = subfield_values_for tag: '337', subfield: :a, record: record
|
85
88
|
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
if
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
MUSICAL_SCORE
|
110
|
-
elsif map_atlas?(format_code)
|
111
|
-
MAP_ATLAS
|
112
|
-
elsif graphical_media?(format_code)
|
113
|
-
graphical_media_type(f007)
|
114
|
-
elsif sound_recording?(format_code)
|
115
|
-
SOUND_RECORDING
|
116
|
-
elsif image?(format_code)
|
117
|
-
IMAGE
|
118
|
-
elsif datafile?(format_code)
|
119
|
-
DATAFILE
|
120
|
-
elsif journal_periodical?(format_code)
|
121
|
-
JOURNAL_PERIODICAL
|
122
|
-
elsif three_d_object?(format_code)
|
123
|
-
THREE_D_OBJECT
|
124
|
-
else
|
125
|
-
OTHER
|
126
|
-
end
|
127
|
-
end
|
128
|
-
formats.concat(curated_format(record)).uniq
|
89
|
+
# any of these
|
90
|
+
formats << MANUSCRIPT if include_manuscripts?(format_code)
|
91
|
+
formats << ARCHIVE if archive?(record)
|
92
|
+
formats << MICROFORMAT if micro_or_microform?(call_nums(record), f007, f008, media_type, title_medium)
|
93
|
+
formats << THESIS_DISSERTATION if thesis_or_dissertation?(format_code, record)
|
94
|
+
formats << CONFERENCE_EVENT if conference_event?(record)
|
95
|
+
formats << NEWSPAPER if newspaper?(f008, format_code)
|
96
|
+
formats << GOVDOC if government_document?(f008, record, format_code)
|
97
|
+
formats << WEBSITE_DATABASE if website_database?(f006_forms, format_code)
|
98
|
+
formats << BOOK if book?(format_code, media_type, record)
|
99
|
+
formats << MUSICAL_SCORE if musical_score?(format_code)
|
100
|
+
formats << MAP_ATLAS if map_atlas?(format_code)
|
101
|
+
formats << graphical_media_type(f007) if graphical_media?(format_code)
|
102
|
+
formats << SOUND_RECORDING if sound_recording?(format_code)
|
103
|
+
formats << IMAGE if image?(format_code)
|
104
|
+
formats << DATAFILE if datafile?(format_code)
|
105
|
+
formats << JOURNAL_PERIODICAL if journal_periodical?(format_code)
|
106
|
+
formats << THREE_D_OBJECT if three_d_object?(format_code)
|
107
|
+
formats.concat(curated_format(record))
|
108
|
+
|
109
|
+
formats << OTHER if formats.empty?
|
110
|
+
|
111
|
+
formats.uniq
|
129
112
|
end
|
130
113
|
|
131
114
|
# Show "Other Format" values from {https://www.oclc.org/bibformats/en/7xx/776.html 776} and any 880 linkage.
|
@@ -155,11 +138,11 @@ module PennMARC
|
|
155
138
|
}.uniq
|
156
139
|
end
|
157
140
|
|
158
|
-
# Check if
|
159
|
-
# @param [
|
141
|
+
# Check if leader format code is either 't', 'f', or 'd'
|
142
|
+
# @param [String] format_code
|
160
143
|
# @return [Boolean]
|
161
|
-
def include_manuscripts?(
|
162
|
-
|
144
|
+
def include_manuscripts?(format_code)
|
145
|
+
format_code.first.in? %w[t f d]
|
163
146
|
end
|
164
147
|
|
165
148
|
private
|
@@ -242,18 +225,18 @@ module PennMARC
|
|
242
225
|
# @param [String] format_code
|
243
226
|
# @return [Boolean]
|
244
227
|
def musical_score?(format_code)
|
245
|
-
format_code.in?(%w[ca cb cd cm cs dm])
|
228
|
+
format_code.in?(%w[ca cb cc cd cm cs dc dm])
|
246
229
|
end
|
247
230
|
|
248
231
|
# @param [String] format_code
|
249
|
-
# @param [Array<String>]
|
232
|
+
# @param [Array<String>] media_type
|
250
233
|
# @param [MARC::Record] record
|
251
234
|
# @return [Boolean]
|
252
|
-
def book?(format_code,
|
235
|
+
def book?(format_code, media_type, record)
|
253
236
|
title_forms = subfield_values_for tag: '245', subfield: :k, record: record
|
254
237
|
format_code.in?(%w[aa ac am tm]) &&
|
255
238
|
title_forms.none? { |v| v =~ /kit/i } &&
|
256
|
-
|
239
|
+
media_type.none? { |val| val =~ /micro/i }
|
257
240
|
end
|
258
241
|
|
259
242
|
# @param [Array<String>] f006_forms
|
@@ -293,29 +276,38 @@ module PennMARC
|
|
293
276
|
# @param [String] format_code
|
294
277
|
# @return [Boolean]
|
295
278
|
def thesis_or_dissertation?(format_code, record)
|
296
|
-
record.fields('502').any? && format_code
|
279
|
+
record.fields('502').any? && format_code.in?(%w[am tm dm])
|
297
280
|
end
|
298
281
|
|
282
|
+
# @param [Array<String>] call_nums
|
283
|
+
# @param [Array<String>] f007
|
284
|
+
# @param [String] f008
|
299
285
|
# @param [Array<String>] title_medium
|
300
286
|
# @param [Array<String>] media_type
|
301
|
-
# @param [Array<String>] locations
|
302
|
-
# @param [Array<String>] call_nums
|
303
287
|
# @return [Boolean]
|
304
|
-
def micro_or_microform?(call_nums,
|
305
|
-
|
288
|
+
def micro_or_microform?(call_nums, f007, f008, media_type, title_medium)
|
289
|
+
[f008[23], f008[29]].any? { |v| v.in?(%w[a b c]) } ||
|
290
|
+
f007.any? { |v| v.start_with?('h') } ||
|
306
291
|
title_medium.any? { |val| val =~ /micro/i } ||
|
307
292
|
call_nums.any? { |val| val =~ /micro/i } ||
|
308
|
-
media_type.any? { |val| val =~ /
|
293
|
+
media_type.any? { |val| val =~ /micro/i }
|
309
294
|
end
|
310
295
|
|
311
|
-
#
|
312
|
-
#
|
313
|
-
#
|
296
|
+
# Determine archive format by checking if {https://www.loc.gov/marc/bibliographic/hd852.html 852} and
|
297
|
+
# {PennMARC::Enriched} Publishing Tag 'ITM' have values that match any of the following archive locations:
|
298
|
+
# archarch, musearch, scfreed, univarch, archivcoll
|
299
|
+
# @param [MARC::Record] record
|
314
300
|
# @return [Boolean]
|
315
|
-
def
|
316
|
-
|
317
|
-
|
318
|
-
|
301
|
+
def archive?(record)
|
302
|
+
enriched_tag = Enriched::Pub::ITEM_TAG
|
303
|
+
enriched_sf = Enriched::Pub::ITEM_CURRENT_LOCATION
|
304
|
+
|
305
|
+
record.fields([enriched_tag, '852']).each do |field|
|
306
|
+
return true if field.tag == enriched_tag && subfield_value_in?(field, enriched_sf, ARCHIVE_LOCATIONS)
|
307
|
+
|
308
|
+
return true if field.tag == '852' && subfield_value_in?(field, 'c', ARCHIVE_LOCATIONS)
|
309
|
+
end
|
310
|
+
false
|
319
311
|
end
|
320
312
|
|
321
313
|
# Consider {https://www.loc.gov/marc/bibliographic/bd007g.html 007} to determine graphical media format
|
@@ -32,7 +32,7 @@ module PennMARC
|
|
32
32
|
record.fields(%w[655 880]).filter_map { |field|
|
33
33
|
next unless allowed_genre_field?(field)
|
34
34
|
|
35
|
-
next if field.tag == '880' &&
|
35
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^655/)
|
36
36
|
|
37
37
|
subfields = %w[a b]
|
38
38
|
sub_with_hyphens = field.find_all(&subfield_not_in?(%w[0 2 5 6 8 c e w])).map { |sf|
|
@@ -47,12 +47,10 @@ module PennMARC
|
|
47
47
|
# @todo the Genre facet in Franklin is pretty ugly. It could be cleaned up by limiting the subfields included
|
48
48
|
# here and cleaning up punctuation.
|
49
49
|
# @param [MARC::Record] record
|
50
|
-
# @param [Hash] location_map
|
51
50
|
# @return [Array<String>]
|
52
|
-
def facet(record
|
53
|
-
|
54
|
-
|
55
|
-
manuscript = Format.include_manuscripts?(locations)
|
51
|
+
def facet(record)
|
52
|
+
format_code = record.leader[6] || ' '
|
53
|
+
manuscript = Format.include_manuscripts?(format_code)
|
56
54
|
video = record.fields('007').any? { |field| field.value.starts_with? 'v' }
|
57
55
|
return [] unless manuscript || video
|
58
56
|
|
@@ -112,7 +112,7 @@ module PennMARC
|
|
112
112
|
# @return [Array<string>]
|
113
113
|
def publisher_number_show(record)
|
114
114
|
record.fields(%w[024 028 880]).filter_map { |field|
|
115
|
-
next if field.tag == '880' &&
|
115
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^(024|028)/)
|
116
116
|
|
117
117
|
# do not return doi values from 024 ǂ2
|
118
118
|
if field.tag == '024' && subfield_value_in?(field, '2', %w[doi])
|
@@ -17,7 +17,7 @@ module PennMARC
|
|
17
17
|
def notes_show(record)
|
18
18
|
notes_fields = %w[500 502 504 515 518 525 533 540 550 580 586 588]
|
19
19
|
record.fields(notes_fields + ['880']).filter_map { |field|
|
20
|
-
next if field.tag == '880' &&
|
20
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^(#{notes_fields.join('|')})/)
|
21
21
|
|
22
22
|
join_subfields(field, &subfield_not_in?(%w[5 6 8]))
|
23
23
|
}.uniq
|
@@ -39,7 +39,7 @@ module PennMARC
|
|
39
39
|
additional_fields = %w[562 563 585 590]
|
40
40
|
|
41
41
|
notes = local_notes + record.fields(additional_fields + ['880']).filter_map do |field|
|
42
|
-
next if field.tag == '880' &&
|
42
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^(#{additional_fields.join('|')})/)
|
43
43
|
|
44
44
|
join_subfields(field, &subfield_not_in?(%w[5 6 8]))
|
45
45
|
end
|
@@ -58,7 +58,7 @@ module PennMARC
|
|
58
58
|
|
59
59
|
next unless field.indicator2.in?([' ', ''])
|
60
60
|
|
61
|
-
next if field.tag == '880' &&
|
61
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^561/)
|
62
62
|
|
63
63
|
next if subfield_value?(field, 'a', /^Athenaeum copy: /)
|
64
64
|
|
@@ -74,7 +74,7 @@ module PennMARC
|
|
74
74
|
# @return [Array<String>]
|
75
75
|
def contents_show(record)
|
76
76
|
record.fields(%w[505 880]).filter_map { |field|
|
77
|
-
next if field.tag == '880' &&
|
77
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^505/)
|
78
78
|
|
79
79
|
join_subfields(field, &subfield_not_in?(%w[6 8])).split('--')
|
80
80
|
}.flatten.uniq
|
@@ -144,22 +144,22 @@ module PennMARC
|
|
144
144
|
# @return [Array<String>]
|
145
145
|
def system_details_show(record)
|
146
146
|
system_details_notes = record.fields(%w[538 880]).filter_map do |field|
|
147
|
-
next if field.tag == '880' &&
|
147
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^538/)
|
148
148
|
|
149
149
|
sub3_and_other_subs(field, &subfield_in?(%w[a i u]))
|
150
150
|
end
|
151
151
|
system_details_notes += record.fields(%w[344 880]).filter_map do |field|
|
152
|
-
next if field.tag == '880' &&
|
152
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^344/)
|
153
153
|
|
154
154
|
sub3_and_other_subs(field, &subfield_in?(%w[a b c d e f g h]))
|
155
155
|
end
|
156
156
|
system_details_notes += record.fields(%w[345 346 880]).filter_map do |field|
|
157
|
-
next if field.tag == '880' &&
|
157
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^(345|346)/)
|
158
158
|
|
159
159
|
sub3_and_other_subs(field, &subfield_in?(%w[a b]))
|
160
160
|
end
|
161
161
|
system_details_notes += record.fields(%w[347 880]).filter_map do |field|
|
162
|
-
next if field.tag == '880' &&
|
162
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^347/)
|
163
163
|
|
164
164
|
sub3_and_other_subs(field, &subfield_in?(%w[a b c d e f]))
|
165
165
|
end
|
@@ -96,7 +96,7 @@ module PennMARC
|
|
96
96
|
# @return [Array<String>]
|
97
97
|
def place_of_publication_show(record)
|
98
98
|
record.fields(%w[752 880]).filter_map { |field|
|
99
|
-
next if field.tag == '880' &&
|
99
|
+
next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^752/)
|
100
100
|
|
101
101
|
place = join_subfields(field, &subfield_not_in?(%w[6 8 e w]))
|
102
102
|
place_extra = join_subfields(field, &subfield_in?(%w[e w]))
|
@@ -49,45 +49,46 @@ module PennMARC
|
|
49
49
|
# @param [Hash] relator_map
|
50
50
|
# @return [Array]
|
51
51
|
def related_work_show(record, relator_map: Mappers.relator)
|
52
|
-
|
52
|
+
fields = record.fields(RELATED_WORK_FIELDS)
|
53
|
+
fields += record.fields('880').select { |f| subfield_value?(f, '6', /^(#{RELATED_WORK_FIELDS.join('|')})/) }
|
54
|
+
fields.filter_map { |field|
|
53
55
|
next if field.indicator2.present?
|
54
56
|
|
55
57
|
next unless subfield_defined?(field, 't')
|
56
58
|
|
57
|
-
|
58
|
-
end
|
59
|
-
relation_values = values + record.fields('880').filter_map do |field|
|
60
|
-
next if field.indicator2.present?
|
59
|
+
relator_term_sf = relator_term_subfield(field)
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
next unless subfield_defined?(field, 't')
|
61
|
+
sf_exclude = %w[0 4 6 8 i] << relator_term_sf
|
65
62
|
|
66
|
-
values_with_title_prefix(field,
|
67
|
-
|
68
|
-
|
63
|
+
values_with_title_prefix(field,
|
64
|
+
relator_term_sf: relator_term_sf,
|
65
|
+
relator_map: relator_map,
|
66
|
+
&subfield_not_in?(sf_exclude))
|
67
|
+
}.uniq
|
69
68
|
end
|
70
69
|
|
71
70
|
# Get "Contains" values from {CONTAINS_FIELDS} in the 7XX range. Must have indicator 2 value of 2 indicating an
|
72
71
|
# "Analytical Entry" meaning that the record is contained by the matching field. Map relator codes in sf 4. Ignore
|
73
72
|
# values in sf 0, 5, 6, and 8.
|
73
|
+
# @todo is it okay to include 880 $4 here? Legacy includes untranslated $4, why?
|
74
74
|
# @param [MARC::Record] record
|
75
75
|
# @param [Hash] relator_map
|
76
76
|
# @return [Array<String>]
|
77
77
|
def contains_show(record, relator_map: Mappers.relator)
|
78
|
-
|
78
|
+
fields = record.fields(CONTAINS_FIELDS)
|
79
|
+
fields += record.fields('880').select { |f| subfield_value?(f, '6', /^(#{CONTAINS_FIELDS.join('|')})/) }
|
80
|
+
fields.filter_map { |field|
|
79
81
|
next unless field.indicator2 == '2'
|
80
82
|
|
81
|
-
|
82
|
-
end
|
83
|
-
contains_values = values + record.fields('880').filter_map do |field|
|
84
|
-
next unless field.indicator2 == '2'
|
83
|
+
relator_term_sf = relator_term_subfield(field)
|
85
84
|
|
86
|
-
|
85
|
+
sf_exclude = %w[0 4 5 6 8 i] << relator_term_sf
|
87
86
|
|
88
|
-
values_with_title_prefix(field,
|
89
|
-
|
90
|
-
|
87
|
+
values_with_title_prefix(field,
|
88
|
+
relator_term_sf: relator_term_sf,
|
89
|
+
relator_map: relator_map,
|
90
|
+
&subfield_not_in?(sf_exclude))
|
91
|
+
}.uniq
|
91
92
|
end
|
92
93
|
|
93
94
|
# Get "Constituent Unit" values from {https://www.oclc.org/bibformats/en/7xx/774.html MARC 774}. Include
|
@@ -114,24 +115,21 @@ module PennMARC
|
|
114
115
|
|
115
116
|
# Handle common behavior when a relator field references a title in subfield i
|
116
117
|
# @param [MARC::DataField] field
|
117
|
-
# @param [
|
118
|
-
# @param [Array, nil] sf_exclude subfields to exclude, optional
|
118
|
+
# @param [String, nil] relator_term_sf subfield that holds relator term
|
119
119
|
# @param [Hash, nil] relator_map map relator in sf4 using this map, optional
|
120
|
+
# @param [Proc] join_selector
|
120
121
|
# @return [String] extracted and processed values from field
|
121
|
-
def values_with_title_prefix(field,
|
122
|
-
raise ArgumentError('Define only sf_include or sf_exclude.') if sf_include.present? && sf_exclude.present?
|
123
|
-
|
122
|
+
def values_with_title_prefix(field, relator_term_sf: nil, relator_map: nil, &join_selector)
|
124
123
|
subi = remove_paren_value_from_subfield_i(field) || ''
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
].compact_blank.join(': ')
|
124
|
+
|
125
|
+
title = join_subfields(field, &join_selector)
|
126
|
+
|
127
|
+
title_with_relator = append_relator(field: field,
|
128
|
+
joined_subfields: title,
|
129
|
+
relator_term_sf: relator_term_sf,
|
130
|
+
relator_map: relator_map)
|
131
|
+
|
132
|
+
[subi, title_with_relator].compact_blank.join(': ')
|
135
133
|
end
|
136
134
|
end
|
137
135
|
end
|