pennmarc 1.0.25 → 1.0.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +8 -9
- data/lib/pennmarc/helpers/creator.rb +139 -65
- data/lib/pennmarc/helpers/edition.rb +5 -3
- data/lib/pennmarc/helpers/note.rb +24 -19
- data/lib/pennmarc/helpers/production.rb +113 -20
- data/lib/pennmarc/test/marc_helpers.rb +83 -0
- data/lib/pennmarc/util.rb +98 -69
- data/lib/pennmarc/version.rb +1 -1
- data/lib/pennmarc.rb +7 -0
- data/spec/lib/pennmarc/helpers/access_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/citation_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/classification_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/creator_spec.rb +103 -2
- data/spec/lib/pennmarc/helpers/database_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/date_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/edition_spec.rb +4 -2
- data/spec/lib/pennmarc/helpers/format_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/genre_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/identifer_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/inventory_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/language_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/link_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/location_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/note_spec.rb +22 -29
- data/spec/lib/pennmarc/helpers/production_spec.rb +121 -22
- data/spec/lib/pennmarc/helpers/relation_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/series_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/subject_spec.rb +0 -2
- data/spec/lib/pennmarc/helpers/title_spec.rb +0 -2
- data/spec/lib/pennmarc/marc_util_spec.rb +0 -2
- data/spec/lib/pennmarc/parser_spec.rb +1 -1
- data/spec/spec_helper.rb +7 -0
- data/spec/support/fixture_helpers.rb +10 -0
- metadata +4 -3
- data/spec/support/marc_spec_helpers.rb +0 -85
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b4d6a53347f4532faa566debcc59bde1fb7043cfbd4530d0a06489a36db8599
|
4
|
+
data.tar.gz: 8a92c36c80406541ac454025e6c2adc53af80dab20af5af16b8995dc5bacfe9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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-
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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
|
-
|
11
|
-
|
12
|
-
TAGS = %w[100 110].freeze
|
10
|
+
# Main tags for Author/Creator information
|
11
|
+
TAGS = %w[100 110].freeze
|
13
12
|
|
14
|
-
|
15
|
-
|
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
|
-
|
16
|
+
CONFERENCE_SEARCH_TAGS = %w[111 711 811].freeze
|
17
|
+
CORPORATE_SEARCH_TAGS = %w[110 710 810].freeze
|
18
18
|
|
19
|
-
|
20
|
-
|
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
|
-
|
22
|
+
CONTRIBUTOR_TAGS = %w[700 710].freeze
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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]
|
39
|
-
# @param [Hash]
|
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]
|
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]
|
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]
|
76
|
-
# @param [Hash]
|
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]
|
91
|
-
# @param [Hash]
|
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]
|
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]
|
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]
|
127
|
-
# @param [Hash]
|
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]
|
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]
|
168
|
-
# @param [Hash]
|
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]
|
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]
|
198
|
-
# @
|
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]
|
216
|
-
# @param [Array]
|
217
|
-
# @param [Hash]
|
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]
|
263
|
-
# @param [Hash]
|
264
|
-
# @param [Boolean]
|
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]
|
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]
|
299
|
-
# @param [Array<String>]
|
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]
|
307
|
-
# @param [Hash]
|
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]
|
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
|
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
|
-
|
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]
|
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]
|
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]
|
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]
|
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
|
76
|
+
def contents_values(record, with_alternate: true)
|
76
77
|
record.fields(%w[505 880]).filter_map { |field|
|
77
|
-
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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(': ')
|