pennmarc 1.0.14 → 1.0.15.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76a91ac26d34008866dd6b66d66b9bbebf5d952d4bda7514d34a40b87f436244
4
- data.tar.gz: 6d6813b9dcbadcf45905a48bb30dbc48fbe47ab081d8457d4936cb2263ba1c91
3
+ metadata.gz: cd846248b3c6fcde1cfd8a74312d84f46ce28f534effaff22ec112a5456afd2f
4
+ data.tar.gz: 7e5789d9ef2594767e438a5b1fd2978b1508afad975785059b3520d795fda15b
5
5
  SHA512:
6
- metadata.gz: a704d7a8957d042ad629446626fa8734e1d9b5c0ee65ba844343765d7c196ac0e8da3ae328213b1832556786b63a426c8ad2b4dc1e9b806795a723530d9367eb
7
- data.tar.gz: 01f2d33cd2e7ec4a0aecb5f032bacd438a553d6d8667c5a0191e282f4722358fd23755b788a9ce21f32677d076e7224a04a73c24345f1146fd76198c42e9ebf3
6
+ metadata.gz: 82a79402e68c4b48f3d38fa165042472aab3a8d811797145811af8a873d177ceb9020a2e71c9853f5c792a37d0533d7a87c7ec94506507c817e3dc09db345dcf
7
+ data.tar.gz: 87196088380e9b7f6750511434edcc49467ca9ee47e9577cb3f42ce75e595a2f7cb62605ede37d1a4b17b59876dec437a0beee131ee97eb19f1c411751c849cc
data/.gitlab-ci.yml CHANGED
@@ -1,4 +1,8 @@
1
1
  include:
2
+ - project: "devops/gitlab/ci-templates/general"
3
+ file:
4
+ - ".install_hashicorp_vault.yml"
5
+ - ".vault_jwt_auth.yml"
2
6
  - project: "devops/gitlab/ci-templates/ruby"
3
7
  ref: "sans-dind"
4
8
  file:
@@ -37,19 +41,10 @@ gem_publication:
37
41
  image: ruby:3.2.2
38
42
  variables:
39
43
  GEMSPEC_FILE: "${CI_PROJECT_NAME}.gemspec"
40
- VAULT_VERSION: "1.10.1"
44
+ VAULT_VERSION: "1.15.5"
41
45
  before_script:
42
- - |
43
- apt-get update && apt-get -y install \
44
- wget \
45
- unzip && \
46
- wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip -O /tmp/vault_${VAULT_VERSION}.zip && \
47
- unzip /tmp/vault_${VAULT_VERSION}.zip -d /usr/bin && \
48
- rm -fr /tmp/vault_${VAULT_VERSION}.zip && \
49
- apt-get remove -y wget unzip && \
50
- apt-get clean
51
- - export VAULT_ADDR=${VAULT_URL}
52
- - export VAULT_TOKEN="$(vault write -field=token auth/jwt/${CI_SERVER_HOST}/login role=${JWT_ROLE} jwt=${CI_JOB_JWT})"
46
+ - !reference [.install_hashicorp_vault, before_script]
47
+ - !reference [.vault_jwt_auth, before_script]
53
48
  - export GEM_HOST_API_KEY="$(vault kv get -field=rubygems_api_key ${VAULT_KV_ENDPOINT}${ENVIRONMENT})"
54
49
  - |
55
50
  gem -v
@@ -11,9 +11,9 @@ module PennMARC
11
11
  # field 520 (Summary, Etc. Note).
12
12
  # https://www.loc.gov/marc/bibliographic/bd510.html
13
13
  # @param [MARC::Record] record
14
- # @return [Array] array of citations and any linked alternates
14
+ # @return [Array<String>] array of citations and any linked alternates
15
15
  def cited_in_show(record)
16
- datafield_and_linked_alternate(record, '510')
16
+ datafield_and_linked_alternate(record, '510').uniq
17
17
  end
18
18
 
19
19
  # Field 524 is the Preferred Citation of Described Materials Note. It is the Format for the citation of the
@@ -22,9 +22,9 @@ module PennMARC
22
22
  # introductory phrase that is generated as a display constant based on the first indicator value.
23
23
  # https://www.loc.gov/marc/bibliographic/bd524.html
24
24
  # @param [MARC::Record] record
25
- # @return [Array] array of citation of described materials note and any linked alternates
25
+ # @return [Array<String>] array of citation of described materials note and any linked alternates
26
26
  def cite_as_show(record)
27
- datafield_and_linked_alternate(record, '524')
27
+ datafield_and_linked_alternate(record, '524').uniq
28
28
  end
29
29
  end
30
30
  end
@@ -28,7 +28,7 @@ module PennMARC
28
28
  # @param [MARC::Record] record
29
29
  # @return [Array<String>] array of classifications
30
30
  def facet(record)
31
- record.fields(TAGS).flat_map do |field|
31
+ record.fields(TAGS).flat_map { |field|
32
32
  call_number_type = subfield_values(field, call_number_type_sf(field))&.first
33
33
  call_numbers = subfield_values(field, call_number_sf(field))
34
34
 
@@ -39,7 +39,7 @@ module PennMARC
39
39
 
40
40
  format_facet(class_code, call_number_type, title)
41
41
  end
42
- end
42
+ }.uniq
43
43
  end
44
44
 
45
45
  private
@@ -67,9 +67,9 @@ module PennMARC
67
67
  def show(record)
68
68
  fields = record.fields(TAGS)
69
69
  fields += record.fields('880').select { |field| subfield_value_in?(field, '6', TAGS) }
70
- fields.filter_map do |field|
70
+ fields.filter_map { |field|
71
71
  join_subfields(field, &subfield_not_in?(%w[0 1 4 6 8 e w]))
72
- end
72
+ }.uniq
73
73
  end
74
74
 
75
75
  # Author/Creator sort. Does not map and include any relator codes.
@@ -95,11 +95,11 @@ module PennMARC
95
95
  700 => 'abcdjq', 710 => 'abcdjq', 711 => 'abcen',
96
96
  800 => 'abcdjq', 810 => 'abcdjq', 811 => 'abcen'
97
97
  }
98
- source_map.flat_map do |field_num, subfields|
98
+ source_map.flat_map { |field_num, subfields|
99
99
  record.fields(field_num.to_s).map do |field|
100
100
  trim_punctuation(join_subfields(field, &subfield_in?(subfields.chars)))
101
101
  end
102
- end
102
+ }.uniq
103
103
  end
104
104
 
105
105
  # Conference for display, intended for results display
@@ -108,9 +108,9 @@ module PennMARC
108
108
  # @param [Hash] relator_map
109
109
  # @return [Array<String>] array of conference values
110
110
  def conference_show(record, relator_map: Mappers.relator)
111
- record.fields('111').filter_map do |field|
111
+ record.fields('111').filter_map { |field|
112
112
  name_from_main_entry field, relator_map
113
- end
113
+ }.uniq
114
114
  end
115
115
 
116
116
  # Conference detailed display, intended for record show page.
@@ -130,7 +130,7 @@ module PennMARC
130
130
  conf_extra = join_subfields field, &subfield_in?(%w[e j w])
131
131
  join_and_squish [conf, conf_extra].compact_blank
132
132
  end
133
- values + record.fields('880').filter_map do |field|
133
+ conferences = values + record.fields('880').filter_map do |field|
134
134
  next unless subfield_value_in? field, '6', %w[111 711]
135
135
 
136
136
  next if subfield_defined? field, 'i'
@@ -139,15 +139,16 @@ module PennMARC
139
139
  conf_extra = join_subfields(field, &subfield_in?(%w[4 e j w]))
140
140
  join_and_squish [conf, conf_extra]
141
141
  end
142
+ conferences.uniq
142
143
  end
143
144
 
144
145
  # Conference name values for searching
145
146
  # @param [MARC::Record] record
146
147
  # @return [Array<String>]
147
148
  def conference_search(record)
148
- record.fields(CONFERENCE_SEARCH_TAGS).filter_map do |field|
149
+ record.fields(CONFERENCE_SEARCH_TAGS).filter_map { |field|
149
150
  join_subfields(field, &subfield_in?(%w[a c d e]))
150
- end
151
+ }.uniq
151
152
  end
152
153
 
153
154
  # Retrieve contributor values for display from fields {https://www.oclc.org/bibformats/en/7xx/700.html 700}
@@ -159,7 +160,7 @@ module PennMARC
159
160
  # @return [Array<String>]
160
161
  def contributor_show(record, relator_map: Mappers.relator)
161
162
  indicator_2_options = ['', ' ', '0']
162
- contributors = record.fields(%w[700 710]).filter_map do |field|
163
+ values = record.fields(%w[700 710]).filter_map do |field|
163
164
  next unless indicator_2_options.member?(field.indicator2)
164
165
  next if subfield_defined? field, 'i'
165
166
 
@@ -176,7 +177,7 @@ module PennMARC
176
177
  }.join
177
178
  "#{contributor} #{contributor_append}".squish
178
179
  end
179
- contributors + record.fields('880').filter_map do |field|
180
+ contributors = values + record.fields('880').filter_map do |field|
180
181
  next unless subfield_value_in?(field, '6', %w[700 710])
181
182
  next if subfield_defined?(field, 'i')
182
183
 
@@ -184,6 +185,7 @@ module PennMARC
184
185
  contributor_append = join_subfields(field, &subfield_in?(%w[e u 3]))
185
186
  "#{contributor} #{contributor_append}".squish
186
187
  end
188
+ contributors.uniq
187
189
  end
188
190
 
189
191
  private
@@ -19,13 +19,13 @@ module PennMARC
19
19
  # @param [Marc::Record]
20
20
  # @return [Array<string>] Array of types
21
21
  def type_facet(record)
22
- record.fields('944').filter_map do |field|
22
+ record.fields('944').filter_map { |field|
23
23
  # skip unless specified database format type present
24
24
  next unless subfield_value?(field, 'a', /#{DATABASES_FACET_VALUE}/o)
25
25
 
26
26
  type = field.find { |subfield| subfield.code == 'b' }
27
27
  type&.value
28
- end
28
+ }.uniq
29
29
  end
30
30
 
31
31
  # Retrieves database subject category/communities of interest (subfield 'a') from
@@ -37,13 +37,13 @@ module PennMARC
37
37
  def category_facet(record)
38
38
  return [] unless curated_db?(record)
39
39
 
40
- record.fields('943').filter_map do |field|
40
+ record.fields('943').filter_map { |field|
41
41
  # skip unless Community of Interest code is in subfield '2'
42
42
  next unless subfield_value?(field, '2', /#{COI_CODE}/o)
43
43
 
44
44
  category = field.find { |subfield| subfield.code == 'a' }
45
45
  category&.value
46
- end
46
+ }.uniq
47
47
  end
48
48
 
49
49
  # Concatenates database subject category with database sub subject category in the format "category--subcategory"
@@ -58,7 +58,7 @@ module PennMARC
58
58
  def subcategory_facet(record)
59
59
  return [] unless curated_db?(record)
60
60
 
61
- record.fields('943').filter_map do |field|
61
+ record.fields('943').filter_map { |field|
62
62
  # skip unless Community of Interest code is in subfield '2'
63
63
  next unless subfield_value?(field, '2', /#{COI_CODE}/o)
64
64
 
@@ -73,7 +73,7 @@ module PennMARC
73
73
  next if subcategory.blank?
74
74
 
75
75
  "#{category.value}--#{subcategory.value}"
76
- end
76
+ }.uniq
77
77
  end
78
78
 
79
79
  private
@@ -14,9 +14,10 @@ module PennMARC
14
14
  # @param [MARC::Record] record
15
15
  # @return [Array<String>] array of editions and their alternates
16
16
  def show(record)
17
- record.fields('250').map { |field|
17
+ editions = record.fields('250').map { |field|
18
18
  join_subfields(field, &subfield_not_in?(%w[6 8]))
19
19
  } + linked_alternate_not_6_or_8(record, '250')
20
+ editions.uniq
20
21
  end
21
22
 
22
23
  # Edition values for display in search results. Just grab the first 250 field.
@@ -42,12 +43,13 @@ module PennMARC
42
43
 
43
44
  other_edition_value(field, relator_map)
44
45
  end
45
- values + record.fields('880').filter_map do |field|
46
+ editions = values + record.fields('880').filter_map do |field|
46
47
  next unless field.indicator2.blank? && subfield_value_in?(field, '6', %w[775]) &&
47
48
  subfield_defined?(field, 'i')
48
49
 
49
50
  other_edition_value(field, relator_map)
50
51
  end
52
+ editions.uniq
51
53
  end
52
54
 
53
55
  private
@@ -48,7 +48,7 @@ module PennMARC
48
48
  end
49
49
  join_subfields(f, &subfield_not_in?(subfield_to_ignore))
50
50
  end
51
- results.compact_blank
51
+ results.compact_blank.uniq
52
52
  end
53
53
 
54
54
  # Get Format values for faceting. Format values are determined using complex logic for each possible format value.
@@ -122,23 +122,24 @@ module PennMARC
122
122
  OTHER
123
123
  end
124
124
  end
125
- formats.concat(curated_format(record))
125
+ formats.concat(curated_format(record)).uniq
126
126
  end
127
127
 
128
128
  # Show "Other Format" values from {https://www.oclc.org/bibformats/en/7xx/776.html 776} and any 880 linkage.
129
129
  # @todo is 774 an error in the linked field in legacy? i changed to 776 here
130
130
  # @param [MARC::Record] record
131
- # @return [Array] other format values for display
131
+ # @return [Array<String>] other format values for display
132
132
  def other_show(record)
133
- other_formats = record.fields('776').filter_map do |field|
133
+ values = record.fields('776').filter_map do |field|
134
134
  value = join_subfields(field, &subfield_in?(%w[i a s t o]))
135
135
  next if value.blank?
136
136
 
137
137
  value
138
138
  end
139
- other_formats + linked_alternate(record, '776') do |sf|
139
+ other_formats = values + linked_alternate(record, '776') do |sf|
140
140
  sf.code.in? %w[i a s t o]
141
141
  end
142
+ other_formats.uniq
142
143
  end
143
144
 
144
145
  # Retrieve cartographic reference data for map/atlas formats for display from
@@ -146,9 +147,9 @@ module PennMARC
146
147
  # @param [MARC::Record] record
147
148
  # @return [Array<String>]
148
149
  def cartographic_show(record)
149
- record.fields(%w[255 342]).map do |field|
150
+ record.fields(%w[255 342]).map { |field|
150
151
  join_subfields(field, &subfield_not_in?(%w[6 8]))
151
- end
152
+ }.uniq
152
153
  end
153
154
 
154
155
  # Check if a set of locations has any locations that include the term 'manuscripts'
@@ -34,11 +34,12 @@ module PennMARC
34
34
  # @param [MARC::Record] record
35
35
  # @return [Array<String>]
36
36
  def isbn_show(record)
37
- isbn_values = record.fields('020').filter_map do |field|
37
+ values = record.fields('020').filter_map do |field|
38
38
  joined_isbn = join_subfields(field, &subfield_in?(%w[a]))
39
39
  joined_isbn.presence
40
40
  end
41
- isbn_values + linked_alternate(record, '020', &subfield_in?(%w[a]))
41
+ isbn_values = values + linked_alternate(record, '020', &subfield_in?(%w[a]))
42
+ isbn_values.uniq
42
43
  end
43
44
 
44
45
  # Get ISSN values for display from the {https://www.oclc.org/bibformats/en/0xx/022.html 022 field} and related
@@ -47,11 +48,12 @@ module PennMARC
47
48
  # @param [MARC::Record] record
48
49
  # @return [Array<String>]
49
50
  def issn_show(record)
50
- issn_values = record.fields('022').filter_map do |field|
51
+ values = record.fields('022').filter_map do |field|
51
52
  joined_issn = join_subfields(field, &subfield_in?(%w[a]))
52
53
  joined_issn.presence
53
54
  end
54
- issn_values + linked_alternate(record, '022', &subfield_in?(%w[a]))
55
+ issn_values = values + linked_alternate(record, '022', &subfield_in?(%w[a]))
56
+ issn_values.uniq
55
57
  end
56
58
 
57
59
  # Get numeric OCLC ID of first {https://www.oclc.org/bibformats/en/0xx/035.html 035 field}
@@ -82,7 +84,7 @@ module PennMARC
82
84
  # @param [MARC::Record] record
83
85
  # @return [Array<String>]
84
86
  def oclc_id_search(record)
85
- record.fields('035').flat_map do |field|
87
+ record.fields('035').flat_map { |field|
86
88
  field.filter_map do |subfield|
87
89
  # skip unless subfield 'a' or 'z'
88
90
  next unless subfield.code.in?(%w[a z])
@@ -98,7 +100,7 @@ module PennMARC
98
100
 
99
101
  match[1]
100
102
  end
101
- end
103
+ }.uniq
102
104
  end
103
105
 
104
106
  # Get publisher issued identifiers from fields {https://www.oclc.org/bibformats/en/0xx/024.html 024},
@@ -109,7 +111,7 @@ module PennMARC
109
111
  # @param [MARC::Record] record
110
112
  # @return [Array<string>]
111
113
  def publisher_number_show(record)
112
- record.fields(%w[024 028 880]).filter_map do |field|
114
+ record.fields(%w[024 028 880]).filter_map { |field|
113
115
  next if field.tag == '880' && subfield_value_not_in?(field, '6', %w[024 028])
114
116
 
115
117
  # do not return doi values from 024 ǂ2
@@ -118,7 +120,7 @@ module PennMARC
118
120
  else
119
121
  join_subfields(field, &subfield_not_in?(%w[5 6])).presence
120
122
  end
121
- end
123
+ }.uniq
122
124
  end
123
125
 
124
126
  # Get publisher issued identifiers for searching of a record. Values extracted from fields
@@ -127,19 +129,19 @@ module PennMARC
127
129
  # @param [MARC::Record] record
128
130
  # @return [Array<String>]
129
131
  def publisher_number_search(record)
130
- record.fields(%w[024 028]).filter_map do |field|
132
+ record.fields(%w[024 028]).filter_map { |field|
131
133
  joined_identifiers = join_subfields(field, &subfield_in?(%w[a]))
132
134
  joined_identifiers.presence
133
- end
135
+ }.uniq
134
136
  end
135
137
 
136
138
  # Retrieve fingerprint for display from the {https://www.oclc.org/bibformats/en/0xx/026.html 026} field
137
139
  # @param [MARC::Record] record
138
140
  # @return [Array<String>]
139
141
  def fingerprint_show(record)
140
- record.fields('026').map do |field|
142
+ record.fields('026').map { |field|
141
143
  join_subfields(field, &subfield_not_in?(%w[2 5 6 8]))
142
- end
144
+ }.uniq
143
145
  end
144
146
 
145
147
  # Retrieve DOI values stored in {https://www.oclc.org/bibformats/en/0xx/024.html 024}.
@@ -147,14 +149,14 @@ module PennMARC
147
149
  # @param [MARC::Record] record
148
150
  # @return [Array<String>]
149
151
  def doi_show(record)
150
- record.fields('024').filter_map do |field|
152
+ record.fields('024').filter_map { |field|
151
153
  # skip unless indicator1 is '7'
152
154
  next unless field.indicator1.in?(%w[7])
153
155
  # skip unless ǂ2 is the string literal 'doi'
154
156
  next unless subfield_value_in?(field, '2', %w[doi])
155
157
 
156
158
  join_subfields(field, &subfield_in?(%w[a]))
157
- end
159
+ }.uniq
158
160
  end
159
161
 
160
162
  private
@@ -18,7 +18,8 @@ module PennMARC
18
18
  values = record.fields('546').map do |field|
19
19
  join_subfields field, &subfield_not_in?(%w[6 8])
20
20
  end
21
- values + linked_alternate(record, '546', &subfield_not_in?(%w[6 8]))
21
+ language_values = values + linked_alternate(record, '546', &subfield_not_in?(%w[6 8]))
22
+ language_values.uniq
22
23
  end
23
24
 
24
25
  # Get language values for searching and faceting of a record. The values are extracted from subfields
@@ -33,7 +34,7 @@ module PennMARC
33
34
  # @param [MARC::Record] record
34
35
  # @param [Hash] iso_639_2_mapping iso-639-2 spec hash for language code translation
35
36
  # @param [Hash] iso_639_3_mapping iso-639-3 spec hash for language code translation
36
- # @return [Array] array of language values
37
+ # @return [Array<String>] array of language values
37
38
  def values(record, iso_639_2_mapping: Mappers.iso_639_2_language, iso_639_3_mapping: Mappers.iso_639_3_language)
38
39
  values = record.fields('041').filter_map { |field|
39
40
  mapper = subfield_value?(field, '2', /iso639-3/) ? iso_639_3_mapping : iso_639_2_mapping
@@ -16,11 +16,11 @@ module PennMARC
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]
19
- record.fields(notes_fields + ['880']).filter_map do |field|
19
+ record.fields(notes_fields + ['880']).filter_map { |field|
20
20
  next if field.tag == '880' && subfield_value_not_in?(field, '6', notes_fields)
21
21
 
22
22
  join_subfields(field, &subfield_not_in?(%w[5 6 8]))
23
- end
23
+ }.uniq
24
24
  end
25
25
 
26
26
  # Retrieve local notes for display from fields {https://www.oclc.org/bibformats/en/5xx/561.html 561},
@@ -38,11 +38,12 @@ module PennMARC
38
38
 
39
39
  additional_fields = %w[562 563 585 590]
40
40
 
41
- local_notes + record.fields(additional_fields + ['880']).filter_map do |field|
41
+ notes = local_notes + record.fields(additional_fields + ['880']).filter_map do |field|
42
42
  next if field.tag == '880' && subfield_value_not_in?(field, '6', additional_fields)
43
43
 
44
44
  join_subfields(field, &subfield_not_in?(%w[5 6 8]))
45
45
  end
46
+ notes.uniq
46
47
  end
47
48
 
48
49
  # Retrieve provenance notes for display from fields {https://www.oclc.org/bibformats/en/5xx/561.html 561} and
@@ -63,7 +64,8 @@ module PennMARC
63
64
 
64
65
  join_subfields(field, &subfield_in?(%w[a]))
65
66
  end
66
- provenance_notes + prefixed_subject_and_alternate(record, 'PRO')
67
+ notes = provenance_notes + prefixed_subject_and_alternate(record, 'PRO')
68
+ notes.uniq
67
69
  end
68
70
 
69
71
  # Retrieve contents notes for display from fields {https://www.oclc.org/bibformats/en/5xx/505.html 505} and
@@ -75,16 +77,16 @@ module PennMARC
75
77
  next if field.tag == '880' && subfield_value_not_in?(field, '6', %w[505])
76
78
 
77
79
  join_subfields(field, &subfield_not_in?(%w[6 8])).split('--')
78
- }.flatten
80
+ }.flatten.uniq
79
81
  end
80
82
 
81
83
  # Retrieve access restricted notes for display from field {https://www.oclc.org/bibformats/en/5xx/506.html 506}.
82
84
  # @param [MARC::Record] record
83
85
  # @return [Array<String>]
84
86
  def access_restriction_show(record)
85
- record.fields('506').filter_map do |field|
87
+ record.fields('506').filter_map { |field|
86
88
  join_subfields(field, &subfield_not_in?(%w[5 6]))
87
- end
89
+ }.uniq
88
90
  end
89
91
 
90
92
  # Retrieve finding aid notes for display from field {https://www.oclc.org/bibformats/en/5xx/555.html 555} and its
@@ -161,7 +163,7 @@ module PennMARC
161
163
 
162
164
  sub3_and_other_subs(field, &subfield_in?(%w[a b c d e f]))
163
165
  end
164
- system_details_notes
166
+ system_details_notes.uniq
165
167
  end
166
168
 
167
169
  private
@@ -8,21 +8,21 @@ module PennMARC
8
8
  # @param [MARC::Record] record
9
9
  # @return [Array<String>]
10
10
  def show(record)
11
- get_264_or_880_fields(record, '0')
11
+ get_264_or_880_fields(record, '0').uniq
12
12
  end
13
13
 
14
14
  # Retrieve distribution values for display from {https://www.oclc.org/bibformats/en/2xx/264.html 264 field}.
15
15
  # @param [MARC::Record] record
16
16
  # @return [Array<String>]
17
17
  def distribution_show(record)
18
- get_264_or_880_fields(record, '2')
18
+ get_264_or_880_fields(record, '2').uniq
19
19
  end
20
20
 
21
21
  # Retrieve manufacture values for display from {https://www.oclc.org/bibformats/en/2xx/264.html 264 field}.
22
22
  # @param [MARC::Record] record
23
23
  # @return [Array<String>]
24
24
  def manufacture_show(record)
25
- get_264_or_880_fields(record, '3')
25
+ get_264_or_880_fields(record, '3').uniq
26
26
  end
27
27
 
28
28
  # Retrieve publication values. Return publication values from
@@ -60,7 +60,7 @@ module PennMARC
60
60
 
61
61
  values += joined264
62
62
  end
63
- values.filter_map { |value| value&.strip }
63
+ values.filter_map { |value| value&.strip }.uniq
64
64
  end
65
65
 
66
66
  # Retrieve publication values for display from fields
@@ -68,7 +68,7 @@ module PennMARC
68
68
  # {https://www.oclc.org/bibformats/en/2xx/260.html 260}-262 and their linked alternates,
69
69
  # and {https://www.oclc.org/bibformats/en/2xx/264.html 264} and its linked alternate.
70
70
  # @param [MARC::Record] record
71
- # @return [Object]
71
+ # @return [Array<String>]
72
72
  def publication_show(record)
73
73
  values = record.fields('245').first(1).flat_map { |field| subfield_values(field, 'f') }
74
74
 
@@ -86,22 +86,22 @@ module PennMARC
86
86
  end
87
87
 
88
88
  values += get_264_or_880_fields(record, '1')
89
- values.compact_blank
89
+ values.compact_blank.uniq
90
90
  end
91
91
 
92
92
  # Retrieve place of publication for display from {https://www.oclc.org/bibformats/en/7xx/752.html 752 field} and
93
93
  # its linked alternate.
94
94
  # @note legacy version returns array of hash objects including data for display link
95
95
  # @param [MARC::Record] record
96
- # @return [Object]
96
+ # @return [Array<String>]
97
97
  def place_of_publication_show(record)
98
- record.fields(%w[752 880]).filter_map do |field|
98
+ record.fields(%w[752 880]).filter_map { |field|
99
99
  next if field.tag == '880' && subfield_values(field, '6').exclude?('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]))
103
103
  "#{place} #{place_extra}"
104
- end
104
+ }.uniq
105
105
  end
106
106
 
107
107
  private
@@ -14,11 +14,11 @@ module PennMARC
14
14
  # in this field should be sufficient to locate host item record.
15
15
  #
16
16
  # @param [MARC::Record] record
17
- # @return [Array] contained in values for display
17
+ # @return [Array<String>] contained in values for display
18
18
  def contained_in_show(record)
19
- record.fields('773').map do |field|
19
+ record.fields('773').map { |field|
20
20
  join_subfields(field, &subfield_not_in?(%w[6 7 8 w]))
21
- end
21
+ }.uniq
22
22
  end
23
23
 
24
24
  # Get "chronology" information from specially-prefixed 650 (subject) fields
@@ -56,7 +56,7 @@ module PennMARC
56
56
 
57
57
  values_with_title_prefix(field, sf_exclude: %w[0 4 6 8 i], relator_map: relator_map)
58
58
  end
59
- values + record.fields('880').filter_map do |field|
59
+ relation_values = values + record.fields('880').filter_map do |field|
60
60
  next if field.indicator2.present?
61
61
 
62
62
  next unless subfield_value?(field, '6', /^(#{RELATED_WORK_FIELDS.join('|')})/)
@@ -65,6 +65,7 @@ module PennMARC
65
65
 
66
66
  values_with_title_prefix(field, sf_exclude: %w[0 4 6 8 i], relator_map: relator_map)
67
67
  end
68
+ relation_values.uniq
68
69
  end
69
70
 
70
71
  # Get "Contains" values from {CONTAINS_FIELDS} in the 7XX range. Must have indicator 2 value of 2 indicating an
@@ -72,20 +73,21 @@ module PennMARC
72
73
  # values in sf 0, 5, 6, and 8.
73
74
  # @param [MARC::Record] record
74
75
  # @param [Hash] relator_map
75
- # @return [Array]
76
+ # @return [Array<String>]
76
77
  def contains_show(record, relator_map: Mappers.relator)
77
- acc = record.fields(CONTAINS_FIELDS).filter_map do |field|
78
+ values = record.fields(CONTAINS_FIELDS).filter_map do |field|
78
79
  next unless field.indicator2 == '2'
79
80
 
80
81
  values_with_title_prefix(field, sf_exclude: %w[0 4 5 6 8 i], relator_map: relator_map)
81
82
  end
82
- acc + record.fields('880').filter_map do |field|
83
+ contains_values = values + record.fields('880').filter_map do |field|
83
84
  next unless field.indicator2 == '2'
84
85
 
85
86
  next unless subfield_value?(field, '6', /^(#{CONTAINS_FIELDS.join('|')})/)
86
87
 
87
88
  values_with_title_prefix(field, sf_include: %w[0 5 6 8 i])
88
89
  end
90
+ contains_values.uniq
89
91
  end
90
92
 
91
93
  # Get "Constituent Unit" values from {https://www.oclc.org/bibformats/en/7xx/774.html MARC 774}. Include
@@ -93,10 +95,11 @@ module PennMARC
93
95
  # @param [MARC::Record] record
94
96
  # @return [Array]
95
97
  def constituent_unit_show(record)
96
- acc = record.fields('774').filter_map do |field|
98
+ values = record.fields('774').filter_map do |field|
97
99
  join_subfields(field, &subfield_in?(%w[i a s t]))
98
100
  end
99
- acc + linked_alternate(record, '774', &subfield_in?(%w[i a s t]))
101
+ constituent_values = values + linked_alternate(record, '774', &subfield_in?(%w[i a s t]))
102
+ constituent_values.uniq
100
103
  end
101
104
 
102
105
  # Get "Has Supplement" values from {https://www.oclc.org/bibformats/en/7xx/770.html MARC 770}. Ignore
@@ -31,7 +31,8 @@ module PennMARC
31
31
  end || []
32
32
 
33
33
  values += remaining_show_entries(record, tags_present)
34
- values + series_880_fields(record)
34
+ series_values = values + series_880_fields(record)
35
+ series_values.uniq
35
36
  end
36
37
 
37
38
  # Values from series fields for display.
@@ -75,7 +76,7 @@ module PennMARC
75
76
 
76
77
  filtered_values.map { |v| v.gsub(/\(|\)/, '') }.join(' ')
77
78
  end
78
- values
79
+ values.uniq
79
80
  end
80
81
 
81
82
  # Information concerning the immediate predecessor of the target item (chronological relationship). When a note
@@ -83,9 +84,9 @@ module PennMARC
83
84
  # indicator position for display.
84
85
  # https://www.loc.gov/marc/bibliographic/bd780.html
85
86
  # @param [MARC::Record] record
86
- # @return [String] continues fields string
87
+ # @return [Array<String>] continues fields string
87
88
  def get_continues_show(record)
88
- continues(record, '780')
89
+ continues(record, '780').uniq
89
90
  end
90
91
 
91
92
  # Information concerning the immediate successor to the target item (chronological relationship). When a note is
@@ -93,9 +94,9 @@ module PennMARC
93
94
  # position for display.
94
95
  # https://www.loc.gov/marc/bibliographic/bd785.html
95
96
  # @param [MARC::Record] record
96
- # @return [String] continued by fields string
97
+ # @return [Array<String>] continued by fields string
97
98
  def get_continued_by_show(record)
98
- continues(record, '785')
99
+ continues(record, '785').uniq
99
100
  end
100
101
 
101
102
  private
@@ -127,7 +128,7 @@ module PennMARC
127
128
  # @note added 2017/04/10: filter out 0 (authority record numbers) added by Alma
128
129
  # @param [MARC::Record] record
129
130
  # @param [String] first_tag
130
- # @return [Array<Hash>] array of author show entry hashes
131
+ # @return [Array<String>] array of author show entry strings
131
132
  def title_show_entries(record, first_tag)
132
133
  record.fields(first_tag).map do |field|
133
134
  series = join_subfields(field, &subfield_not_in?(%w[0 5 6 8 c e w v n]))
@@ -156,6 +157,7 @@ module PennMARC
156
157
  # links that field to the 880 field. The data in field 880 may be in more than one script. This function exists
157
158
  # because it differs than the tradition use of linked_alternate.
158
159
  # @param [MARC::Record] record
160
+ # @return [Array<String>]
159
161
  def series_880_fields(record)
160
162
  record.fields('880').filter_map do |field|
161
163
  next unless subfield_value?(field, '6', /^(800|810|811|830|400|410|411|440|490)/)
@@ -189,7 +191,7 @@ module PennMARC
189
191
  # Get subfields from a given field (continues or continued_by).
190
192
  # @param [MARC::Record] record
191
193
  # @param [String] tag
192
- # @return [String] joined subfields
194
+ # @return [Array<String>] joined subfields
193
195
  def continues(record, tag)
194
196
  record.fields.filter_map do |field|
195
197
  next unless field.tag == tag || (field.tag == '880' && subfield_value?(field, '6', /^#{tag}/))
@@ -32,9 +32,9 @@ module PennMARC
32
32
  # a search (non-display) field?
33
33
  # @param [Hash] relator_map
34
34
  # @param [MARC::Record] record
35
- # @return [Array] array of all subject values for search
35
+ # @return [Array<String>] array of all subject values for search
36
36
  def search(record, relator_map: Mappers.relator)
37
- subject_fields(record, type: :search).filter_map do |field|
37
+ subject_fields(record, type: :search).filter_map { |field|
38
38
  subj_parts = field.filter_map do |subfield|
39
39
  # TODO: use term hash here? pro/chr would be rejected...
40
40
  # TODO: should we care about punctuation in a search field? relator mapping?
@@ -55,21 +55,21 @@ module PennMARC
55
55
  next if subj_parts.empty?
56
56
 
57
57
  join_and_squish subj_parts
58
- end
58
+ }.uniq
59
59
  end
60
60
 
61
61
  # All Subjects for faceting
62
62
  #
63
63
  # @note this is ported mostly form MG's new-style Subject parsing
64
64
  # @param [MARC::Record] record
65
- # @return [Array] array of all subject values for faceting
65
+ # @return [Array<String>] array of all subject values for faceting
66
66
  def facet(record)
67
- subject_fields(record, type: :facet).filter_map do |field|
67
+ subject_fields(record, type: :facet).filter_map { |field|
68
68
  term_hash = build_subject_hash(field)
69
69
  next if term_hash.blank? || term_hash[:count]&.zero?
70
70
 
71
71
  format_term type: :facet, term: term_hash
72
- end
72
+ }.uniq
73
73
  end
74
74
 
75
75
  # All Subjects for display. This includes all {DISPLAY_TAGS} and {LOCAL_TAGS}. For tags that specify a source,
@@ -35,11 +35,11 @@ module PennMARC
35
35
  # @param [MARC::Record] record
36
36
  # @return [Array<String>] array of title values for search
37
37
  def search(record)
38
- record.fields(%w[245 880]).filter_map do |field|
38
+ record.fields(%w[245 880]).filter_map { |field|
39
39
  next if field.tag == '880' && subfield_value_not_in?(field, '6', %w[245])
40
40
 
41
41
  join_subfields(field, &subfield_not_in?(%w[c 6 8 h]))
42
- end
42
+ }.uniq
43
43
  end
44
44
 
45
45
  # Auxiliary Title Search field. Takes from many fields defined in {AUX_TITLE_TAGS} that contain title-like
@@ -47,10 +47,11 @@ module PennMARC
47
47
  # @param [MARC::Record] record
48
48
  # @return [Array<String>] array of auxiliary title values for search
49
49
  def search_aux(record)
50
- search_aux_values(record: record, title_type: :main, &subfield_not_in?(%w[c 6 8])) +
51
- search_aux_values(record: record, title_type: :related, &subfield_not_in?(%w[s t])) +
52
- search_aux_values(record: record, title_type: :entity, &subfield_in?(%w[t])) +
53
- search_aux_values(record: record, title_type: :note, &subfield_in?(%w[t]))
50
+ values = search_aux_values(record: record, title_type: :main, &subfield_not_in?(%w[c 6 8])) +
51
+ search_aux_values(record: record, title_type: :related, &subfield_not_in?(%w[s t])) +
52
+ search_aux_values(record: record, title_type: :entity, &subfield_in?(%w[t])) +
53
+ search_aux_values(record: record, title_type: :note, &subfield_in?(%w[t]))
54
+ values.uniq
54
55
  end
55
56
 
56
57
  # Journal Title Search field. Takes from {https://www.loc.gov/marc/bibliographic/bd245.html 245} and linked 880.
@@ -61,11 +62,11 @@ module PennMARC
61
62
  def journal_search(record)
62
63
  return [] if not_a_serial?(record)
63
64
 
64
- record.fields(%w[245 880]).filter_map do |field|
65
+ record.fields(%w[245 880]).filter_map { |field|
65
66
  next if field.tag == '880' && subfield_value_not_in?(field, '6', %w[245])
66
67
 
67
68
  join_subfields(field, &subfield_not_in?(%w[c 6 8 h]))
68
- end
69
+ }.uniq
69
70
  end
70
71
 
71
72
  # Auxiliary Journal Title Search field. Takes from many fields defined in {AUX_TITLE_TAGS} that contain title-like
@@ -74,10 +75,11 @@ module PennMARC
74
75
  # @param [MARC::Record] record
75
76
  # @return [Array<String>] auxiliary journal title information for search
76
77
  def journal_search_aux(record)
77
- search_aux_values(record: record, title_type: :main, journal: true, &subfield_not_in?(%w[c 6 8])) +
78
- search_aux_values(record: record, title_type: :related, journal: true, &subfield_not_in?(%w[s t])) +
79
- search_aux_values(record: record, title_type: :entity, journal: true, &subfield_in?(%w[t])) +
80
- search_aux_values(record: record, title_type: :note, journal: true, &subfield_in?(%w[t]))
78
+ values = search_aux_values(record: record, title_type: :main, journal: true, &subfield_not_in?(%w[c 6 8])) +
79
+ search_aux_values(record: record, title_type: :related, journal: true, &subfield_not_in?(%w[s t])) +
80
+ search_aux_values(record: record, title_type: :entity, journal: true, &subfield_in?(%w[t])) +
81
+ search_aux_values(record: record, title_type: :note, journal: true, &subfield_in?(%w[t]))
82
+ values.uniq
81
83
  end
82
84
 
83
85
  # Single-valued Title, for use in headings. Takes the first {https://www.oclc.org/bibformats/en/2xx/245.html 245}
@@ -162,12 +164,13 @@ module PennMARC
162
164
 
163
165
  join_subfields(field, &subfield_not_in?(%w[5 6 8 e w]))
164
166
  end
165
- standardized_titles + record.fields('880').filter_map do |field|
167
+ titles = standardized_titles + record.fields('880').filter_map do |field|
166
168
  next unless subfield_undefined?(field, 'i') ||
167
169
  subfield_value_in?(field, '6', %w[130 240 730])
168
170
 
169
171
  join_subfields field, &subfield_not_in?(%w[5 6 8 e w])
170
172
  end
173
+ titles.uniq
171
174
  end
172
175
 
173
176
  # Other Title for display
@@ -187,11 +190,12 @@ module PennMARC
187
190
 
188
191
  join_subfields(field, &subfield_not_in?(%w[5 6 8]))
189
192
  end
190
- other_titles + record.fields('880').filter_map do |field|
193
+ titles = other_titles + record.fields('880').filter_map do |field|
191
194
  next unless subfield_value_in? field, '6', %w[246 740]
192
195
 
193
196
  join_subfields(field, &subfield_not_in?(%w[5 6 8]))
194
197
  end
198
+ titles.uniq
195
199
  end
196
200
 
197
201
  # Former Title for display.
@@ -204,13 +208,13 @@ module PennMARC
204
208
  # @return [Array<String>] array of former titles
205
209
  def former_show(record)
206
210
  record.fields
207
- .filter_map do |field|
211
+ .filter_map { |field|
208
212
  next unless field.tag == '247' || (field.tag == '880' && subfield_value?(field, '6', /^247/))
209
213
 
210
214
  former_title = join_subfields field, &subfield_not_in?(%w[6 8 e w]) # 6 and 8 are not meaningful for display
211
215
  former_title_append = join_subfields field, &subfield_in?(%w[e w])
212
216
  "#{former_title} #{former_title_append}".strip
213
- end
217
+ }.uniq
214
218
  end
215
219
 
216
220
  private
data/lib/pennmarc/util.rb CHANGED
@@ -173,7 +173,7 @@ module PennMARC
173
173
  # Returns the non-6,8 subfields from a datafield and its 880 link.
174
174
  # @param [MARC::Record] record
175
175
  # @param [String] tag
176
- # @return [Array] acc
176
+ # @return [Array<String>] values
177
177
  def datafield_and_linked_alternate(record, tag)
178
178
  record.fields(tag).filter_map { |field|
179
179
  join_subfields(field, &subfield_not_in?(%w[6 8]))
@@ -238,7 +238,7 @@ module PennMARC
238
238
  # @param [String] prefix to select from subject field
239
239
  # @return [Array] array of values
240
240
  def prefixed_subject_and_alternate(record, prefix)
241
- record.fields(%w[650 880]).filter_map do |field|
241
+ record.fields(%w[650 880]).filter_map { |field|
242
242
  next unless field.indicator2 == '4'
243
243
 
244
244
  next if field.tag == '880' && subfield_values(field, '6').exclude?('650')
@@ -248,7 +248,7 @@ module PennMARC
248
248
  elements = field.select(&subfield_in?(%w[a])).map { |sf| sf.value.gsub(/^%?#{prefix}/, '') }
249
249
  elements << join_subfields(field, &subfield_not_in?(%w[a 6 8 e w 5]))
250
250
  join_and_squish elements
251
- end
251
+ }.uniq
252
252
  end
253
253
 
254
254
  # Does the given field specify an allowed source code?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- VERSION = '1.0.14'
4
+ VERSION = '1.0.15.pre'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pennmarc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.14
4
+ version: 1.0.15.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Kanning
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-01-30 00:00:00.000000000 Z
13
+ date: 2024-02-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -166,9 +166,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
166
  version: '3.2'
167
167
  required_rubygems_version: !ruby/object:Gem::Requirement
168
168
  requirements:
169
- - - ">="
169
+ - - ">"
170
170
  - !ruby/object:Gem::Version
171
- version: '0'
171
+ version: 1.3.1
172
172
  requirements: []
173
173
  rubygems_version: 3.4.10
174
174
  signing_key: