pennmarc 1.0.25 → 1.0.26

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +8 -9
  3. data/lib/pennmarc/helpers/creator.rb +139 -65
  4. data/lib/pennmarc/helpers/edition.rb +5 -3
  5. data/lib/pennmarc/helpers/note.rb +24 -19
  6. data/lib/pennmarc/helpers/production.rb +113 -20
  7. data/lib/pennmarc/test/marc_helpers.rb +83 -0
  8. data/lib/pennmarc/util.rb +98 -69
  9. data/lib/pennmarc/version.rb +1 -1
  10. data/lib/pennmarc.rb +7 -0
  11. data/spec/lib/pennmarc/helpers/access_spec.rb +0 -2
  12. data/spec/lib/pennmarc/helpers/citation_spec.rb +0 -2
  13. data/spec/lib/pennmarc/helpers/classification_spec.rb +0 -2
  14. data/spec/lib/pennmarc/helpers/creator_spec.rb +103 -2
  15. data/spec/lib/pennmarc/helpers/database_spec.rb +0 -2
  16. data/spec/lib/pennmarc/helpers/date_spec.rb +0 -2
  17. data/spec/lib/pennmarc/helpers/edition_spec.rb +4 -2
  18. data/spec/lib/pennmarc/helpers/format_spec.rb +0 -2
  19. data/spec/lib/pennmarc/helpers/genre_spec.rb +0 -2
  20. data/spec/lib/pennmarc/helpers/identifer_spec.rb +0 -2
  21. data/spec/lib/pennmarc/helpers/inventory_spec.rb +0 -2
  22. data/spec/lib/pennmarc/helpers/language_spec.rb +0 -2
  23. data/spec/lib/pennmarc/helpers/link_spec.rb +0 -2
  24. data/spec/lib/pennmarc/helpers/location_spec.rb +0 -2
  25. data/spec/lib/pennmarc/helpers/note_spec.rb +22 -29
  26. data/spec/lib/pennmarc/helpers/production_spec.rb +121 -22
  27. data/spec/lib/pennmarc/helpers/relation_spec.rb +0 -2
  28. data/spec/lib/pennmarc/helpers/series_spec.rb +0 -2
  29. data/spec/lib/pennmarc/helpers/subject_spec.rb +0 -2
  30. data/spec/lib/pennmarc/helpers/title_spec.rb +0 -2
  31. data/spec/lib/pennmarc/marc_util_spec.rb +0 -2
  32. data/spec/lib/pennmarc/parser_spec.rb +1 -1
  33. data/spec/spec_helper.rb +7 -0
  34. data/spec/support/fixture_helpers.rb +10 -0
  35. metadata +4 -3
  36. data/spec/support/marc_spec_helpers.rb +0 -85
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b540ecd84333f097b50a3682732229854b188fcde76921eb0ec184622a690dd
4
- data.tar.gz: 9203fadee45b9ad65ec20880a1acbc23356000b748d32d07428ec093590cd55a
3
+ metadata.gz: 8b4d6a53347f4532faa566debcc59bde1fb7043cfbd4530d0a06489a36db8599
4
+ data.tar.gz: 8a92c36c80406541ac454025e6c2adc53af80dab20af5af16b8995dc5bacfe9d
5
5
  SHA512:
6
- metadata.gz: 6770815e8f5f828c15451fc71c04dbef6a131203e8c58d721c063b15f218d5814a71b37fd6c4f088a9c7164d5d989ff6933abc820094068921f218c937a87410
7
- data.tar.gz: 94eee63c29ae06151816a532a5afb7db1f27490de798651c909dc07fd0f33de1b4a1ee26057b6e3a8abc5d15c54d09709df8942e6e21ad828c1296fe3191725e
6
+ metadata.gz: 8b1f0be0caba6a00adc8ccc5516556b2de250d93861157c49a60e17f52810b6eed7942efe8b51843d7428bb329c6dcad58a0887c17e9132004fe3d7d29729682
7
+ data.tar.gz: b06dad73899b13254391b74832d3b99745d82bc9f871801d7a617e2416f9d70039d45a9122a292377628b638c4044e692432688dbce48497cb6394fa48ba0d6e
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 10000`
3
- # on 2024-01-17 17:00:02 UTC using RuboCop version 1.51.0.
3
+ # on 2024-07-02 15:41:46 UTC using RuboCop version 1.51.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -14,7 +14,7 @@ Gemspec/RequireMFA:
14
14
  Exclude:
15
15
  - 'pennmarc.gemspec'
16
16
 
17
- # Offense count: 23
17
+ # Offense count: 25
18
18
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
19
19
  Metrics/AbcSize:
20
20
  Exclude:
@@ -26,18 +26,18 @@ Metrics/AbcSize:
26
26
  - 'lib/pennmarc/helpers/location.rb'
27
27
  - 'lib/pennmarc/helpers/note.rb'
28
28
  - 'lib/pennmarc/helpers/production.rb'
29
- - 'lib/pennmarc/helpers/relation.rb'
30
29
  - 'lib/pennmarc/helpers/series.rb'
31
30
  - 'lib/pennmarc/helpers/subject.rb'
32
31
  - 'lib/pennmarc/helpers/title.rb'
33
32
  - 'lib/pennmarc/util.rb'
34
33
 
35
- # Offense count: 5
34
+ # Offense count: 8
36
35
  # Configuration parameters: CountComments, Max, CountAsOne.
37
36
  Metrics/ClassLength:
38
37
  Exclude:
39
38
  - 'lib/pennmarc/helpers/creator.rb'
40
39
  - 'lib/pennmarc/helpers/format.rb'
40
+ - 'lib/pennmarc/helpers/production.rb'
41
41
  - 'lib/pennmarc/helpers/series.rb'
42
42
  - 'lib/pennmarc/helpers/subject.rb'
43
43
  - 'lib/pennmarc/helpers/title.rb'
@@ -54,13 +54,12 @@ Metrics/CyclomaticComplexity:
54
54
  - 'lib/pennmarc/helpers/language.rb'
55
55
  - 'lib/pennmarc/helpers/note.rb'
56
56
  - 'lib/pennmarc/helpers/production.rb'
57
- - 'lib/pennmarc/helpers/relation.rb'
58
57
  - 'lib/pennmarc/helpers/series.rb'
59
58
  - 'lib/pennmarc/helpers/subject.rb'
60
59
  - 'lib/pennmarc/helpers/title.rb'
61
60
  - 'lib/pennmarc/util.rb'
62
61
 
63
- # Offense count: 26
62
+ # Offense count: 28
64
63
  # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
65
64
  Metrics/MethodLength:
66
65
  Exclude:
@@ -82,7 +81,7 @@ Metrics/ModuleLength:
82
81
  Exclude:
83
82
  - 'lib/pennmarc/util.rb'
84
83
 
85
- # Offense count: 12
84
+ # Offense count: 14
86
85
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
87
86
  Metrics/PerceivedComplexity:
88
87
  Exclude:
@@ -123,7 +122,7 @@ Naming/VariableNumber:
123
122
  Exclude:
124
123
  - 'lib/pennmarc/util.rb'
125
124
 
126
- # Offense count: 7
125
+ # Offense count: 8
127
126
  # Configuration parameters: Max, CountAsOne.
128
127
  RSpec/ExampleLength:
129
128
  Exclude:
@@ -139,7 +138,7 @@ RSpec/FilePath:
139
138
  Exclude:
140
139
  - 'spec/lib/pennmarc/parser_spec.rb'
141
140
 
142
- # Offense count: 12
141
+ # Offense count: 23
143
142
  # Configuration parameters: Max, AllowedGroups.
144
143
  RSpec/NestedGroups:
145
144
  Exclude:
@@ -7,26 +7,27 @@ module PennMARC
7
7
  # @todo can there ever be multiple 100 fields?
8
8
  # can ǂe and ǂ4 both be used at the same time? seems to result in duplicate values
9
9
  class Creator < Helper
10
- class << self
11
- # Main tags for Author/Creator information
12
- TAGS = %w[100 110].freeze
10
+ # Main tags for Author/Creator information
11
+ TAGS = %w[100 110].freeze
13
12
 
14
- # Aux tags for Author/Creator information, for use in search_aux method
15
- AUX_TAGS = %w[100 110 111 400 410 411 700 710 711 800 810 811].freeze
13
+ # Aux tags for Author/Creator information, for use in search_aux method
14
+ AUX_TAGS = %w[100 110 111 400 410 411 700 710 711 800 810 811].freeze
16
15
 
17
- CONFERENCE_SEARCH_TAGS = %w[111 711 811].freeze
16
+ CONFERENCE_SEARCH_TAGS = %w[111 711 811].freeze
17
+ CORPORATE_SEARCH_TAGS = %w[110 710 810].freeze
18
18
 
19
- # subfields NOT to join when combining raw subfield values
20
- NAME_EXCLUDED_SUBFIELDS = %w[a 1 4 5 6 8 t].freeze
19
+ # subfields NOT to join when combining raw subfield values
20
+ NAME_EXCLUDED_SUBFIELDS = %w[a 1 4 5 6 8 t].freeze
21
21
 
22
- CONTRIBUTOR_TAGS = %w[700 710].freeze
22
+ CONTRIBUTOR_TAGS = %w[700 710].freeze
23
23
 
24
- FACET_SOURCE_MAP = {
25
- 100 => 'abcdjq', 110 => 'abcdjq', 111 => 'abcen',
26
- 700 => 'abcdjq', 710 => 'abcdjq', 711 => 'abcen',
27
- 800 => 'abcdjq', 810 => 'abcdjq', 811 => 'abcen'
28
- }.freeze
24
+ FACET_SOURCE_MAP = {
25
+ 100 => 'abcdjq', 110 => 'abcdjq', 111 => 'abcen',
26
+ 700 => 'abcdjq', 710 => 'abcdjq', 711 => 'abcen',
27
+ 800 => 'abcdjq', 810 => 'abcdjq', 811 => 'abcen'
28
+ }.freeze
29
29
 
30
+ class << self
30
31
  # Author/Creator search field. Includes all subfield values (even ǂ0 URIs) from
31
32
  # {https://www.oclc.org/bibformats/en/1xx/100.html 100 Main Entry--Personal Name} and
32
33
  # {https://www.oclc.org/bibformats/en/1xx/110.html 110 Main Entry--Corporate Name}. Maps any relator codes found
@@ -35,8 +36,8 @@ module PennMARC
35
36
  # @todo are we including too many details here and gumming up our index? consider UIRs, relator labels, dates...
36
37
  # @todo shouldn't indicator1 tell us the order of the name? do we not trust the indicator?
37
38
  # @note ported from get_author_creator_1_search_values
38
- # @param [MARC::Record] record
39
- # @param [Hash] relator_map
39
+ # @param record [MARC::Record]
40
+ # @param relator_map [Hash]
40
41
  # @return [Array<String>] array of author/creator values for indexing
41
42
  def search(record, relator_map: Mappers.relator)
42
43
  name_search_values record: record, tags: TAGS, relator_map: relator_map
@@ -50,7 +51,7 @@ module PennMARC
50
51
  # and {https://www.loc.gov/marc/bibliographic/bd711.html MARC 711}. The 800, 810 and 8111 tags are similar in
51
52
  # theme to the 7xx fields but apply to serial records.
52
53
  # @note ported from get_author_creator_2_search_values
53
- # @param [MARC::Record] record
54
+ # @param record [MARC::Record]
54
55
  # @return [Array<String>] array of extended author/creator values for indexing
55
56
  def search_aux(record, relator_map: Mappers.relator)
56
57
  name_search_values record: record, tags: AUX_TAGS, relator_map: relator_map
@@ -60,7 +61,7 @@ module PennMARC
60
61
  # and {https://www.loc.gov/marc/bibliographic/bd110.html 110} and their linked alternates. First, joins subfields
61
62
  # other than $0, $1, $4, $6, $8, $e, and w. Then, appends any encoded relators found in $4.
62
63
  # If there are no valid encoded relators, uses the value found in $e.
63
- # @param [MARC::Record] record
64
+ # @param record [MARC::Record]
64
65
  # @return [Array<String>] array of author/creator values for display
65
66
  def show(record, relator_map: Mappers.relator)
66
67
  fields = record.fields(TAGS)
@@ -72,8 +73,8 @@ module PennMARC
72
73
 
73
74
  # Hash with main creator show values as the fields and the corresponding facet as the values.
74
75
  # Does not include linked 880s.
75
- # @param [MARC::Record] record
76
- # @param [Hash] relator_map
76
+ # @param record [MARC::Record]
77
+ # @param relator_map [Hash]
77
78
  # @return [Hash]
78
79
  def show_facet_map(record, relator_map: Mappers.relator)
79
80
  creators = record.fields(TAGS).filter_map do |field|
@@ -84,11 +85,82 @@ module PennMARC
84
85
  creators.to_h { |h| [h[:show], h[:facet]] }
85
86
  end
86
87
 
88
+ # Returns the list of authors with name (subfield $a) only
89
+ # @param [MARC::Record] record
90
+ # @param [Boolean] main_tags_only, if true, only use TAGS; otherwise use both TAGS and CONTRIBUTOR_TAGS
91
+ # @param [Boolean] first_initial_only: true to only use the first initial instead of first name
92
+ # @return [Array<String>] names of the authors
93
+ def authors_list(record, main_tags_only: false, first_initial_only: false)
94
+ tags = if main_tags_only
95
+ TAGS
96
+ else
97
+ TAGS + CONTRIBUTOR_TAGS
98
+ end
99
+
100
+ fields = record.fields(tags)
101
+ fields.filter_map { |field|
102
+ if first_initial_only
103
+ abbreviate_name(field['a']) if field['a']
104
+ else
105
+ field['a']
106
+ end
107
+ }.uniq
108
+ end
109
+
110
+ # Show the authors and contributors grouped together by relators with only names
111
+ # @param [MARC::Record] record
112
+ # @param [Hash] relator_map
113
+ # @param [Boolean] include_authors: true to include author fields TAGS
114
+ # @param [Boolean] name_only: true to include only the name subfield $a
115
+ # @param [Boolean] vernacular: true to include field 880 with subfield $6
116
+ # @return [Hash]
117
+ def contributors_list(record, relator_map: Mappers.relator, include_authors: true, name_only: true,
118
+ vernacular: false)
119
+ indicator_2_options = ['', ' ', '0']
120
+ tags = CONTRIBUTOR_TAGS
121
+
122
+ fields = record.fields(tags)
123
+ fields += record.fields('880').select { |field| subfield_value_in?(field, '6', CONTRIBUTOR_TAGS) } if vernacular
124
+
125
+ contributors = {}
126
+ fields.each do |field|
127
+ next if indicator_2_options.exclude?(field.indicator2) && field.tag.in?(CONTRIBUTOR_TAGS)
128
+ next if subfield_defined? field, 'i'
129
+
130
+ relator = relator(field: field, relator_term_sf: 'e', relator_map: relator_map)
131
+ relator = 'Contributor' if relator.blank?
132
+ relator = trim_punctuation(relator).capitalize
133
+
134
+ name = if name_only
135
+ field['a']
136
+ else
137
+ join_subfields(field, &subfield_in?(%w[a b c d j q u 3])) + ", #{relator}"
138
+ end
139
+
140
+ if contributors.key?(relator)
141
+ contributors[relator].push(name)
142
+ else
143
+ contributors[relator] = [name]
144
+ end
145
+ end
146
+
147
+ # add the authors
148
+ if include_authors
149
+ authors = authors_list(record, main_tags_only: true)
150
+ if contributors.key?('Author')
151
+ contributors['Author'] += authors
152
+ else
153
+ contributors['Author'] = authors
154
+ end
155
+ end
156
+ contributors
157
+ end
158
+
87
159
  # All author/creator values for display (like #show, but multivalued?) - no 880 linkage
88
160
  # Performs additional normalization of author names
89
161
  # @note ported from get_author_creator_values (indexed as author_creator_a) - shown on results page
90
- # @param [MARC::Record] record
91
- # @param [Hash] relator_map
162
+ # @param record [MARC::Record]
163
+ # @param relator_map [Hash]
92
164
  # @return [Array<String>] array of author/creator values for display
93
165
  def show_aux(record, relator_map: Mappers.relator)
94
166
  record.fields(TAGS).map { |field|
@@ -99,7 +171,7 @@ module PennMARC
99
171
  # Author/Creator sort. Does not map and include any relator codes.
100
172
  # @todo This includes any URI from ǂ0 which could help to disambiguate in sorts, but ǂ1 is excluded...
101
173
  # @note ported from get_author_creator_sort_values
102
- # @param [MARC::Record] record
174
+ # @param record [MARC::Record]
103
175
  # @return [String] string with author/creator value for sorting
104
176
  def sort(record)
105
177
  field = record.fields(TAGS).first
@@ -107,11 +179,11 @@ module PennMARC
107
179
  end
108
180
 
109
181
  # Author/Creator for faceting. Grabs values from a plethora of fields, joins defined subfields, then trims some
110
- # punctuation (@see trim_punctuation)
182
+ # punctuation (@see Util.trim_punctuation)
111
183
  # @todo should trim_punctuation apply to each subfield value, or the joined values? i think the joined values
112
184
  # @note ported from author_creator_xfacet2_input - is this the best choice? check the copyField declarations -
113
185
  # franklin uses author_creator_f
114
- # @param [MARC::Record] record
186
+ # @param record [MARC::Record]
115
187
  # @return [Array<String>] array of author/creator values for faceting
116
188
  def facet(record)
117
189
  FACET_SOURCE_MAP.flat_map { |field_num, subfields|
@@ -123,8 +195,8 @@ module PennMARC
123
195
 
124
196
  # Conference for display, intended for results display
125
197
  # @note ported from get_conference_values
126
- # @param [MARC::Record] record
127
- # @param [Hash] relator_map
198
+ # @param record [MARC::Record]
199
+ # @param relator_map [Hash]
128
200
  # @return [Array<String>] array of conference values
129
201
  def conference_show(record, relator_map: Mappers.relator)
130
202
  record.fields('111').filter_map { |field|
@@ -139,7 +211,7 @@ module PennMARC
139
211
  # using subfields $e and $w. We append any relators, preferring those defined in $4 and using $j as a fallback.
140
212
  # @note ported from get_conference_values
141
213
  # @todo what is ǂi for?
142
- # @param [MARC::Record] record
214
+ # @param record [MARC::Record]
143
215
  # @return [Array<String>] array of conference values
144
216
  def conference_detail_show(record, relator_map: Mappers.relator)
145
217
  conferences = record.fields(%w[111 711]).filter_map do |field|
@@ -164,8 +236,8 @@ module PennMARC
164
236
  # Return hash of detailed conference values mapped to their corresponding facets from fields
165
237
  # {https://www.loc.gov/marc/bibliographic/bd111.html 111} and
166
238
  # {https://www.loc.gov/marc/bibliographic/bd711.html 711}. Does not include linked 880s.
167
- # @param [MARC::Record] record
168
- # @param [Hash] relator_map
239
+ # @param record [MARC::Record]
240
+ # @param relator_map [Hash]
169
241
  # @return [Hash]
170
242
  def conference_detail_show_facet_map(record, relator_map: Mappers.relator)
171
243
  conferences = record.fields(%w[111 711]).filter_map do |field|
@@ -180,7 +252,7 @@ module PennMARC
180
252
  end
181
253
 
182
254
  # Conference name values for searching
183
- # @param [MARC::Record] record
255
+ # @param record [MARC::Record]
184
256
  # @return [Array<String>]
185
257
  def conference_search(record)
186
258
  record.fields(CONFERENCE_SEARCH_TAGS).filter_map { |field|
@@ -188,14 +260,23 @@ module PennMARC
188
260
  }.uniq
189
261
  end
190
262
 
263
+ # Corporate author search values for searching
264
+ # @param record [MARC::Record]
265
+ # @return [Array<String>]
266
+ def corporate_search(record)
267
+ record.fields(CORPORATE_SEARCH_TAGS).filter_map do |field|
268
+ join_subfields(field, &subfield_in?(%w[a b c d]))
269
+ end
270
+ end
271
+
191
272
  # Retrieve contributor values for display from fields {https://www.oclc.org/bibformats/en/7xx/700.html 700}
192
273
  # and {https://www.oclc.org/bibformats/en/7xx/710.html 710} and their linked alternates. Joins subfields
193
274
  # 'a', 'b', 'c', 'd', 'j', and 'q', 'u', and '3'. Then appends resulting string with any encoded relationships
194
275
  # found in $4. If there are no valid encoded relationships, uses the value found in $e.
195
276
  # @note legacy version returns array of hash objects including data for display link
196
277
  # @todo is it okay to include 880 $4 here? Legacy includes $4 in main author display 880 but not here.
197
- # @param [MARC::Record] record
198
- # @ param [Hash] relator_map
278
+ # @param record [MARC::Record]
279
+ # @param relator_map [Hash]
199
280
  # @return [Array<String>]
200
281
  def contributor_show(record, relator_map: Mappers.relator)
201
282
  indicator_2_options = ['', ' ', '0']
@@ -212,9 +293,9 @@ module PennMARC
212
293
 
213
294
  private
214
295
 
215
- # @param [MARC::Record] record
216
- # @param [Array] tags to consider
217
- # @param [Hash] relator_map
296
+ # @param record [MARC::Record]
297
+ # @param tags [Array] to consider
298
+ # @param relator_map [Hash]
218
299
  # @return [Array<String>] name values from given tags
219
300
  def name_search_values(record:, tags:, relator_map:)
220
301
  acc = record.fields(tags).filter_map do |field|
@@ -238,30 +319,10 @@ module PennMARC
238
319
  acc.uniq
239
320
  end
240
321
 
241
- # Trim punctuation method extracted from Traject macro, to ensure consistent output
242
- # @todo move to Util?
243
- # @param [String] string
244
- # @return [String] string with relevant punctuation removed
245
- def trim_punctuation(string)
246
- return string unless string
247
-
248
- string = string.sub(%r{ *[ ,/;:] *\Z}, '')
249
-
250
- # trailing period if it is preceded by at least three letters (possibly preceded and followed by whitespace)
251
- string = string.sub(/( *[[:word:]]{3,})\. *\Z/, '\1')
252
-
253
- # single square bracket characters if they are the start and/or end chars and there are no internal square
254
- # brackets.
255
- string = string.sub(/\A\[?([^\[\]]+)\]?\Z/, '\1')
256
-
257
- # trim any leading or trailing whitespace
258
- string.strip
259
- end
260
-
261
322
  # Extract the information we care about from 1xx fields, map relator codes, and use appropriate punctuation
262
- # @param [MARC::Field] field
263
- # @param [Hash] mapping
264
- # @param [Boolean] should_convert_name_order
323
+ # @param field [MARC::Field]
324
+ # @param mapping [Hash]
325
+ # @param should_convert_name_order [Boolean]
265
326
  # @return [String] joined subfield values for value from field
266
327
  def name_from_main_entry(field, mapping, should_convert_name_order: false)
267
328
  relator_term_sf = relator_term_subfield(field)
@@ -284,7 +345,7 @@ module PennMARC
284
345
  end
285
346
 
286
347
  # Convert "Lastname, First" to "First Lastname"
287
- # @param [String] name value for processing
348
+ # @param name [String] value for processing
288
349
  # @return [String]
289
350
  def convert_name_order(name)
290
351
  return name unless name.include? ','
@@ -294,17 +355,30 @@ module PennMARC
294
355
  "#{after_comma} #{before_comma}".squish
295
356
  end
296
357
 
358
+ # Convert "Lastname, First" to "Lastname, F"
359
+ # @param [String] name
360
+ def abbreviate_name(name)
361
+ name_parts = name.split(', ')
362
+ return '' if name_parts.empty?
363
+
364
+ first_name_parts = name_parts.last.split
365
+ temp_name = "#{name_parts.first}, #{first_name_parts.first[0, 1]}."
366
+ first_name_parts.shift
367
+ temp_name += " #{first_name_parts.join(' ')}" unless first_name_parts.empty?
368
+ temp_name
369
+ end
370
+
297
371
  # Parse creator facet value from given creator field and desired subfields
298
- # @param [MARC::Field] field
299
- # @param [Array<String>] subfields
372
+ # @param field [MARC::Field]
373
+ # @param subfields [Array<String>]
300
374
  # @return [String]
301
375
  def parse_facet_value(field, subfields)
302
376
  trim_punctuation(join_subfields(field, &subfield_in?(subfields)))
303
377
  end
304
378
 
305
379
  # Parse creator show value from given main creator fields (100/110).
306
- # @param [MARC::Field] field
307
- # @param [Hash] relator_map
380
+ # @param field [MARC::Field]
381
+ # @param relator_map [Hash]
308
382
  # @return [String]
309
383
  def parse_show_value(field, relator_map: Mappers.relator)
310
384
  creator = join_subfields(field, &subfield_not_in?(%w[0 1 4 6 8 e w]))
@@ -314,7 +388,7 @@ module PennMARC
314
388
  # Parse detailed conference show value from given conference field (111/711). If there is no $i, we join subfield
315
389
  # values other than $0, $4, $5, $6, $8, $e, $j, and $w to create conference value. We join subfields $e and $w to
316
390
  # determine the subunit value. We append any relators, preferring those defined in $4 and using $j as a fallback.
317
- # @param [MARC::Field] field
391
+ # @param field [MARC::Field]
318
392
  # @return [String]
319
393
  def parse_conference_detail_show_value(field, relator_map: Mappers.relator)
320
394
  conf = if subfield_undefined? field, 'i'
@@ -13,10 +13,12 @@ module PennMARC
13
13
  # https://www.loc.gov/marc/bibliographic/bd250.html
14
14
  # @param [MARC::Record] record
15
15
  # @return [Array<String>] array of editions and their alternates
16
- def show(record)
17
- editions = record.fields('250').map { |field|
16
+ def show(record, with_alternate: true)
17
+ editions = record.fields('250').map do |field|
18
18
  join_subfields(field, &subfield_not_in?(%w[6 8]))
19
- } + linked_alternate_not_6_or_8(record, '250')
19
+ end
20
+ editions += linked_alternate_not_6_or_8(record, '250') if with_alternate
21
+
20
22
  editions.uniq
21
23
  end
22
24
 
@@ -12,7 +12,7 @@ module PennMARC
12
12
  # {https://www.oclc.org/bibformats/en/5xx/580.html 580}, {https://www.oclc.org/bibformats/en/5xx/586.html 586},
13
13
  # {https://www.oclc.org/bibformats/en/5xx/588.html 588}
14
14
  # and their linked alternates.
15
- # @param [MARC::Record] record
15
+ # @param record [MARC::Record]
16
16
  # @return [Array<String>]
17
17
  def notes_show(record)
18
18
  notes_fields = %w[500 502 504 515 518 525 533 540 550 580 586 588]
@@ -27,7 +27,7 @@ module PennMARC
27
27
  # {https://www.oclc.org/bibformats/en/5xx/562.html 562}, {https://www.oclc.org/bibformats/en/5xx/563.html 563},
28
28
  # {https://www.oclc.org/bibformats/en/5xx/585.html 585}, {https://www.oclc.org/bibformats/en/5xx/590.html 590}.
29
29
  # Includes linked alternates except for 561.
30
- # @param [MARC::Record] record
30
+ # @param record [MARC::Record]
31
31
  # @return [Array<String>]
32
32
  def local_notes_show(record)
33
33
  local_notes = record.fields('561').filter_map do |field|
@@ -50,7 +50,7 @@ module PennMARC
50
50
  # prefixed subject field {https://www.oclc.org/bibformats/en/6xx/650.html 650} and its linked alternate.
51
51
  # Ignores 561 fields with subfield 'a' values that begin with 'Athenaeum copy: ' and 650 fields where subfield 'a'
52
52
  # does not have the prefix 'PRO'.
53
- # @param [MARC::Record] record
53
+ # @param record [MARC::Record]
54
54
  # @return [Array<String>]
55
55
  def provenance_show(record)
56
56
  provenance_notes = record.fields(%w[561 880]).filter_map do |field|
@@ -68,20 +68,25 @@ module PennMARC
68
68
  notes.uniq
69
69
  end
70
70
 
71
- # Retrieve contents notes for display from fields {https://www.oclc.org/bibformats/en/5xx/505.html 505} and
72
- # its linked alternate.
73
- # @param [MARC::Record] record
71
+ # Retrieve contents notes for display from fields {https://www.oclc.org/bibformats/en/5xx/505.html 505} and, if
72
+ # include_vernacular param is true, its linked alternate. Used for display and searching.
73
+ # @param record [MARC::Record]
74
+ # @param with_alternate [Boolean]
74
75
  # @return [Array<String>]
75
- def contents_show(record)
76
+ def contents_values(record, with_alternate: true)
76
77
  record.fields(%w[505 880]).filter_map { |field|
77
- next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^505/)
78
+ if field.tag == '880'
79
+ next unless with_alternate
80
+
81
+ next if no_subfield_value_matches?(field, '6', /^505/)
82
+ end
78
83
 
79
84
  join_subfields(field, &subfield_not_in?(%w[6 8])).split('--')
80
85
  }.flatten.uniq
81
86
  end
82
87
 
83
88
  # Retrieve access restricted notes for display from field {https://www.oclc.org/bibformats/en/5xx/506.html 506}.
84
- # @param [MARC::Record] record
89
+ # @param record [MARC::Record]
85
90
  # @return [Array<String>]
86
91
  def access_restriction_show(record)
87
92
  record.fields('506').filter_map { |field|
@@ -91,7 +96,7 @@ module PennMARC
91
96
 
92
97
  # Retrieve finding aid notes for display from field {https://www.oclc.org/bibformats/en/5xx/555.html 555} and its
93
98
  # linked alternate.
94
- # @param [MARC::Record] record
99
+ # @param record [MARC::Record]
95
100
  # @return [Array<String>]
96
101
  def finding_aid_show(record)
97
102
  datafield_and_linked_alternate(record, '555')
@@ -99,7 +104,7 @@ module PennMARC
99
104
 
100
105
  # Retrieve participant notes for display from field {https://www.oclc.org/bibformats/en/5xx/511.html 511} and its
101
106
  # linked alternate.
102
- # @param [MARC::Record] record
107
+ # @param record [MARC::Record]
103
108
  # @return [Array<String>]
104
109
  def participant_show(record)
105
110
  datafield_and_linked_alternate(record, '511')
@@ -107,7 +112,7 @@ module PennMARC
107
112
 
108
113
  # Retrieve credits notes for display from field {https://www.oclc.org/bibformats/en/5xx/508.html 508} and its
109
114
  # linked alternate.
110
- # @param [MARC::Record] record
115
+ # @param record [MARC::Record]
111
116
  # @return [Array<String>]
112
117
  def credits_show(record)
113
118
  datafield_and_linked_alternate(record, '508')
@@ -115,7 +120,7 @@ module PennMARC
115
120
 
116
121
  # Retrieve biography notes for display from field {https://www.oclc.org/bibformats/en/5xx/545.html 545} and its
117
122
  # linked alternate.
118
- # @param [MARC::Record] record
123
+ # @param record [MARC::Record]
119
124
  # @return [Array<String>]
120
125
  def biography_show(record)
121
126
  datafield_and_linked_alternate(record, '545')
@@ -123,14 +128,14 @@ module PennMARC
123
128
 
124
129
  # Retrieve summary notes for display from field {https://www.oclc.org/bibformats/en/5xx/520.html 520} and its
125
130
  # linked alternate.
126
- # @param [MARC::Record] record
131
+ # @param record [MARC::Record]
127
132
  # @return [Array<String>]
128
133
  def summary_show(record)
129
134
  datafield_and_linked_alternate(record, '520')
130
135
  end
131
136
 
132
137
  # Retrieve arrangement values for display from field field {https://www.oclc.org/bibformats/en/3xx/351.html 351}.
133
- # @param [MARC::Record] record
138
+ # @param record [MARC::Record]
134
139
  # @return [Array<String>]
135
140
  def arrangement_show(record)
136
141
  datafield_and_linked_alternate(record, '351')
@@ -140,7 +145,7 @@ module PennMARC
140
145
  # {https://www.oclc.org/bibformats/en/3xx/344.html 344}, {https://www.oclc.org/bibformats/en/3xx/345.html 345},
141
146
  # {https://www.oclc.org/bibformats/en/3xx/346.html 346}, {https://www.oclc.org/bibformats/en/3xx/347.html 347},
142
147
  # and their linked alternates.
143
- # @param [MARC::Record] record
148
+ # @param record [MARC::Record]
144
149
  # @return [Array<String>]
145
150
  def system_details_show(record)
146
151
  system_details_notes = record.fields(%w[538 880]).filter_map do |field|
@@ -167,7 +172,7 @@ module PennMARC
167
172
  end
168
173
 
169
174
  # Retrieve "With" notes for display from field {https://www.loc.gov/marc/bibliographic/bd501.html 501}
170
- # @param [Marc::Record] record
175
+ # @param record [Marc::Record]
171
176
  # @return [Array<String>]
172
177
  def bound_with_show(record)
173
178
  record.fields('501').filter_map { |field| join_subfields(field, &subfield_in?(['a'])).presence }.uniq
@@ -177,8 +182,8 @@ module PennMARC
177
182
 
178
183
  # For system details: extract subfield ǂ3 plus other subfields as specified by passed-in block. Pays special
179
184
  # attention to punctuation, joining subfield ǂ3 values with a colon-space (': ').
180
- # @param [MARC::DataField] field
181
- # @param [Proc] &
185
+ # @param field [MARC::DataField]
186
+ # @param & [Proc]
182
187
  # @return [String]
183
188
  def sub3_and_other_subs(field, &)
184
189
  sub3 = field.filter_map { |sf| trim_trailing('period', sf.value) if sf.code == '3' }.join(': ')