pennmarc 1.0.25 → 1.0.26
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/.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(': ')
|