pennmarc 1.0.14 → 1.0.15.pre

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 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: