pennmarc 1.4.8 → 1.4.11

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: a51f4a4e365a774002e2dbddfa2d1ba72b37e7ed5b98c2b6ca7910e45c571568
4
- data.tar.gz: 795408a49a463709d3d0805ec5a66b58c822ee99630f9ed281583c2c954e23b4
3
+ metadata.gz: 8afdbe2c48c9cf22c9d3242757f070996e6181f3d1ac570ece3fdbf04e8c2f5d
4
+ data.tar.gz: 3ddc3f81b9a8152e53aa19430cc45180e30fc89a11f3cda5ebae41cb9c0a275c
5
5
  SHA512:
6
- metadata.gz: 64213422101fa26f03d675af34ffb5f0169b266c6173689516fb9a33120d3fca8c709392ccea842baf96ae08887c9aea238d542e932cf289428437fce7685df9
7
- data.tar.gz: b29c0fb8dd64d223b0749b1179286bd99d430e658d38e236cfed0747b96fc88dd9494c213ecd0c007c03a0bca03ea49a6ba61fce2eb59578e6c42cc337ee46e1
6
+ metadata.gz: 7fd53869a4b48a1d8446a969283c8e60f467952dfc17a7c251ca9ffae767bc4f9a9e04f7dba24a3c6a97aa18856a23b79bb181dadf8766832c6d85fbfa4a3928
7
+ data.tar.gz: 35a12593cd5352b3ffa9de11afa86ef22b7b00d2ae0f48f1e78f961f71a68d50bd694e13baaa41bf85ca25e9877097360405e57619a976fa0e688ef6845856e9
data/.rubocop.yml CHANGED
@@ -3,5 +3,16 @@ inherit_from: .rubocop_todo.yml
3
3
  inherit_gem:
4
4
  upennlib-rubocop: upennlib_rubocop_defaults.yml
5
5
 
6
+ plugins:
7
+ - rubocop-yard
8
+
9
+ YARD/MismatchName:
10
+ Description: 'Check @param and @option name and method parameters'
11
+ Enabled: true
12
+ VersionAdded: '0.3.0'
13
+ EnforcedStylePrototypeName: before
14
+ SupportedStylesPrototypeName:
15
+ - before
16
+
6
17
  Rails:
7
18
  Enabled: false
data/Gemfile CHANGED
@@ -8,6 +8,7 @@ gem 'library_stdnums', '~> 1.6'
8
8
  gem 'marc', '~> 1.2'
9
9
  gem 'nokogiri', '~> 1.15'
10
10
  gem 'rake', '~> 13.0'
11
+ gem 'rubocop-yard', require: false
11
12
  gem 'upennlib-rubocop', require: false
12
13
 
13
14
  group :test, :development do
data/Gemfile.lock CHANGED
@@ -127,6 +127,10 @@ GEM
127
127
  rubocop-rspec (3.9.0)
128
128
  lint_roller (~> 1.1)
129
129
  rubocop (~> 1.81)
130
+ rubocop-yard (1.1.0)
131
+ lint_roller
132
+ rubocop (~> 1.72)
133
+ yard
130
134
  ruby-progressbar (1.13.0)
131
135
  securerandom (0.4.1)
132
136
  simplecov (0.22.0)
@@ -171,6 +175,7 @@ DEPENDENCIES
171
175
  rackup
172
176
  rake (~> 13.0)
173
177
  rspec (~> 3.12)
178
+ rubocop-yard
174
179
  simplecov (~> 0.22)
175
180
  upennlib-rubocop
176
181
  yard
@@ -23,6 +23,8 @@ module PennMARC
23
23
  CONTRIBUTOR_TAGS = %w[700 710].freeze
24
24
  CONTRIBUTOR_DISPLAY_SUBFIELDS = %w[a b c d j q u 3].freeze
25
25
 
26
+ UNIVERSITY_IDENTIFIER = 'PU'
27
+
26
28
  FACET_SOURCE_MAP = {
27
29
  100 => 'abcdjq', 110 => 'abcdjq', 111 => 'abcen',
28
30
  700 => 'abcdjq', 710 => 'abcdjq', 711 => 'abcen',
@@ -52,6 +54,7 @@ module PennMARC
52
54
  # theme to the 7xx fields but apply to serial records. Includes all subfield values except those in the
53
55
  # {SEARCH_EXCLUDED_SUBFIELDS} constant.
54
56
  # @param record [MARC::Record]
57
+ # @param relator_map [Hash]
55
58
  # @return [Array<String>] array of extended author/creator values for indexing
56
59
  def search_aux(record, relator_map: Mappers.relator)
57
60
  name_search_values record: record, tags: AUX_TAGS, relator_map: relator_map
@@ -62,6 +65,7 @@ module PennMARC
62
65
  # value except for those defined in the {DISPLAY_EXCLUDED_SUBFIELDS} constant. Then, appends any encoded relators
63
66
  # found in $4. If there are no valid encoded relators, uses the value found in $e.
64
67
  # @param record [MARC::Record]
68
+ # @param relator_map [Hash]
65
69
  # @return [Array<String>] array of author/creator values for display
66
70
  def show(record, relator_map: Mappers.relator)
67
71
  fields = record.fields(TAGS)
@@ -87,6 +91,7 @@ module PennMARC
87
91
 
88
92
  # Show more credited authors - both 100 field and 700 entries where the relator (codes e or 4) is author/aut
89
93
  # @param record [MARC::Record]
94
+ # @param relator_map [Hash]
90
95
  # @return [Array<String>] array of author/creator values for display
91
96
  def extended_show(record, relator_map: Mappers.relator)
92
97
  fields = record.fields(TAGS + %w[700 710])
@@ -124,6 +129,8 @@ module PennMARC
124
129
  def authors_list(record, main_tags_only: false, first_initial_only: false)
125
130
  fields = record.fields(main_tags_only ? TAGS : TAGS + CONTRIBUTOR_TAGS)
126
131
  fields.filter_map { |field|
132
+ next if university_provenance? field
133
+
127
134
  if field['a'].present?
128
135
  name = trim_trailing(:comma, field['a'])
129
136
  first_initial_only ? abbreviate_name(name) : name
@@ -150,6 +157,7 @@ module PennMARC
150
157
  fields.each do |field|
151
158
  next if indicator_2_options.exclude?(field.indicator2) && field.tag.in?(CONTRIBUTOR_TAGS)
152
159
  next if subfield_defined? field, 'i'
160
+ next if university_provenance? field
153
161
 
154
162
  relator = relator(field: field, relator_term_sf: 'e', relator_map: relator_map)
155
163
  relator = 'Contributor' if relator.blank?
@@ -231,6 +239,7 @@ module PennMARC
231
239
  # @note ported from get_conference_values
232
240
  # @todo what is ǂi for?
233
241
  # @param record [MARC::Record]
242
+ # @param relator_map [Hash]
234
243
  # @return [Array<String>] array of conference values
235
244
  def conference_detail_show(record, relator_map: Mappers.relator)
236
245
  conferences = record.fields(%w[111 711]).filter_map do |field|
@@ -462,6 +471,7 @@ module PennMARC
462
471
  # values other than $0, $4, $5, $6, $8, $e, $j, and $w to create conference value. We join subfields $e and $w to
463
472
  # determine the subunit value. We append any relators, preferring those defined in $4 and using $j as a fallback.
464
473
  # @param field [MARC::Field]
474
+ # @param relator_map [Hash]
465
475
  # @return [String]
466
476
  def parse_conference_detail_show_value(field, relator_map: Mappers.relator)
467
477
  conf = if subfield_undefined? field, 'i'
@@ -481,6 +491,14 @@ module PennMARC
481
491
  def describes_author?(field)
482
492
  field['4']&.downcase == 'aut' || field['e']&.downcase&.start_with?('author')
483
493
  end
494
+
495
+ # Does the given field describe a contributor representing university provenance. A contributor tag with a '$5'
496
+ # value starting with the university identifier represents university provenance.
497
+ # @param field [MARC::Field]
498
+ # @return [Boolean]
499
+ def university_provenance?(field)
500
+ field.tag.in?(CONTRIBUTOR_TAGS) && subfield_value?(field, '5', /^#{UNIVERSITY_IDENTIFIER}/)
501
+ end
484
502
  end
485
503
  end
486
504
  end
@@ -12,6 +12,7 @@ module PennMARC
12
12
  # Publication and/or Volume Designation).
13
13
  # https://www.loc.gov/marc/bibliographic/bd250.html
14
14
  # @param record [MARC::Record]
15
+ # @param with_alternate [Boolean]
15
16
  # @return [Array<String>] array of editions and their alternates
16
17
  def show(record, with_alternate: true)
17
18
  editions = record.fields('250').map do |field|
@@ -7,7 +7,7 @@ module PennMARC
7
7
  # Represent a Electronic inventory entry - simple because the subfield specification is identical across
8
8
  # entries returned by the API and Alma Publishing enrichment
9
9
  class Electronic < Base
10
- # @return [Hash{Symbol->Unknown}]
10
+ # @return [Hash{Symbol=>Unknown}]
11
11
  def to_h
12
12
  { portfolio_id: field[mapper::ELEC_PORTFOLIO_ID],
13
13
  url: field[mapper::ELEC_SERVICE_URL],
@@ -25,7 +25,7 @@ module PennMARC
25
25
  field[mapper::PHYS_PRIORITY]
26
26
  end
27
27
 
28
- # @return [Hash{Symbol->Unknown}]
28
+ # @return [Hash{Symbol=>Unknown}]
29
29
  def to_h
30
30
  { holding_id: field[mapper::PHYS_HOLDING_ID],
31
31
  location_name: field[mapper::PHYS_LOCATION_NAME],
@@ -68,7 +68,7 @@ module PennMARC
68
68
  # Determine enriched marc location tag, location code subfield, and call number subfield,
69
69
  # giving priority to using 'itm', 'AVA', or 'hld' fields.
70
70
  # @param record [MARC::Record]
71
- # @return [Hash<String, String>] containing location tag and subfield code
71
+ # @return [Hash{String => String}] containing location tag and subfield code
72
72
  # - `:tag` (String): The enriched marc location tag
73
73
  # - `:location_code_sf` (String): The subfield code where location code is stored
74
74
  # - `:call_num_sf` (String): The subfield code where call number is stored
@@ -1602,6 +1602,10 @@ vetewellrm:
1602
1602
  - Veterinary
1603
1603
  - 'Veterinary: Atwood Library (Campus)'
1604
1604
  display: 'Veterinary: Atwood Library (Campus)- Wellness Room'
1605
+ vpcgcdisp:
1606
+ specific_location: Van Pelt - Global Collections Book Display
1607
+ library: Van Pelt-Dietrich Library Center
1608
+ display: Van Pelt - Global Collections Book Display -- First Floor
1605
1609
  vpexhibits:
1606
1610
  specific location: Van Pelt - Exhibits and Events
1607
1611
  library: Van Pelt-Dietrich Library Center
@@ -13,6 +13,7 @@ module PennMARC
13
13
  class Parser
14
14
  # Allow calls to `respond_to?` on parser instances to respond accurately by checking helper classes
15
15
  # @param name [String, Symbol]
16
+ # @param include_private [Boolean]
16
17
  # @return [Boolean]
17
18
  def respond_to_missing?(name, include_private = false)
18
19
  helper, method_name = parse_call(name)
@@ -41,7 +41,7 @@ module PennMARC
41
41
  end
42
42
  end
43
43
 
44
- # @return [Array[Array]]
44
+ # @return [Array<Array>]
45
45
  def factors
46
46
  FACTORS
47
47
  end
data/lib/pennmarc/util.rb CHANGED
@@ -38,7 +38,7 @@ module PennMARC
38
38
  # returns true if field has a value that matches
39
39
  # passed-in regex and passed in subfield
40
40
  # @param field [MARC::DataField]
41
- # @param subfield [String|Integer|Symbol]
41
+ # @param subfield [String, Integer, Symbol]
42
42
  # @param regex [Regexp]
43
43
  # @return [Boolean, nil]
44
44
  def subfield_value?(field, subfield, regex)
@@ -48,7 +48,7 @@ module PennMARC
48
48
  # returns true if field has no value that matches
49
49
  # passed-in regex and passed in subfield
50
50
  # @param field [MARC::DataField]
51
- # @param subfield [String|Integer|Symbol]
51
+ # @param subfield [String, Integer, Symbol]
52
52
  # @param regex [Regexp]
53
53
  # @return [Boolean, nil]
54
54
  def no_subfield_value_matches?(field, subfield, regex)
@@ -57,7 +57,7 @@ module PennMARC
57
57
 
58
58
  # returns true if a given field has a given subfield value in a given array
59
59
  # @param field [MARC::DataField]
60
- # @param subfield [String|Integer|Symbol]
60
+ # @param subfield [String, Integer, Symbol]
61
61
  # @param array [Array]
62
62
  # @return [Boolean]
63
63
  def subfield_value_in?(field, subfield, array)
@@ -65,8 +65,8 @@ module PennMARC
65
65
  end
66
66
 
67
67
  # returns true if a given field does not have a given subfield value in a given array
68
- # @param field [MARC:DataField]
69
- # @param subfield [String|Integer|Symbol]
68
+ # @param field [MARC::DataField]
69
+ # @param subfield [String, Integer, Symbol]
70
70
  # @param array [Array]
71
71
  # @return [Boolean]
72
72
  def subfield_value_not_in?(field, subfield, array)
@@ -89,7 +89,7 @@ module PennMARC
89
89
 
90
90
  # Check if a field has a given subfield defined
91
91
  # @param field [MARC::DataField]
92
- # @param subfield [String|Symbol|Integer]
92
+ # @param subfield [String, Symbol, Integer]
93
93
  # @return [Boolean]
94
94
  def subfield_defined?(field, subfield)
95
95
  field.any? { |sf| sf.code == subfield.to_s }
@@ -97,7 +97,7 @@ module PennMARC
97
97
 
98
98
  # Check if a field does not have a given subfield defined
99
99
  # @param field [MARC::DataField]
100
- # @param subfield [String|Symbol|Integer]
100
+ # @param subfield [String, Symbol, Integer]
101
101
  # @return [Boolean]
102
102
  def subfield_undefined?(field, subfield)
103
103
  field.none? { |sf| sf.code == subfield.to_s }
@@ -105,7 +105,7 @@ module PennMARC
105
105
 
106
106
  # Gets all subfield values for a subfield in a given field
107
107
  # @param field [MARC::DataField]
108
- # @param subfield [String|Symbol] as a string or symbol
108
+ # @param subfield [String, Symbol] as a string or symbol
109
109
  # @return [Array] subfield values for given subfield code
110
110
  def subfield_values(field, subfield)
111
111
  field.filter_map do |sf|
@@ -183,7 +183,7 @@ module PennMARC
183
183
  # passed-in block from 880 datafield that has a particular subfield 6 value.
184
184
  # See: https://www.loc.gov/marc/bibliographic/bd880.html
185
185
  # @param record [MARC::Record]
186
- # @param subfield6_value [String|Array] either a string to look for in sub6 or an array of them
186
+ # @param subfield6_value [String, Array] either a string to look for in sub6 or an array of them
187
187
  # @param selector [Proc] takes a subfield as argument, returns a boolean
188
188
  # @return [Array] array of linked alternates
189
189
  def linked_alternate(record, subfield6_value, &selector)
@@ -198,7 +198,7 @@ module PennMARC
198
198
  # from 880 datafield that has a particular subfield 6 value. We exclude 6 because
199
199
  # that value is the linkage ID itself and 8 because... IDK
200
200
  # @param record [MARC::Record]
201
- # @param subfield6_value [String|Array] either a string to look for in sub6 or an array of them
201
+ # @param subfield6_value [String, Array] either a string to look for in sub6 or an array of them
202
202
  # @return [Array] array of linked alternates without 8 or 6 values
203
203
  def linked_alternate_not_6_or_8(record, subfield6_value)
204
204
  excluded_subfields = %w[6 8]
@@ -319,7 +319,7 @@ module PennMARC
319
319
  # {https://www.loc.gov/marc/bibliographic/bd111.html 111}, {https://www.loc.gov/marc/bibliographic/bd411.html 411},
320
320
  # {https://www.loc.gov/marc/bibliographic/bd611.html 611}, {https://www.loc.gov/marc/bibliographic/bd711.html 711},
321
321
  # {https://www.loc.gov/marc/bibliographic/bd811.html 811}
322
- # @param field [MARC:Field]
322
+ # @param field [MARC::Field]
323
323
  # @return [String (frozen)]
324
324
  def relator_term_subfield(field)
325
325
  field_or_its_linked_alternate?(field, %w[111 411 611 711 811]) ? 'j' : 'e'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- VERSION = '1.4.8'
4
+ VERSION = '1.4.11'
5
5
  end
@@ -192,6 +192,23 @@ describe 'PennMARC::Creator' do
192
192
  'Name ends with comma', 'Name with no comma'
193
193
  end
194
194
  end
195
+
196
+ context 'with university donor/fund provenance' do
197
+ let(:fields) do
198
+ [marc_field(tag: '100', subfields: { a: 'Surname, Name', '0': 'http://cool.uri/12345', d: '1900-2000',
199
+ e: 'author.', '4': 'http://cool.uri/vocabulary/relators/aut' }),
200
+ marc_field(tag: '700', subfields: { a: 'A contributor', e: 'contributor',
201
+ '5': "Does-not-start-with-#{helper::UNIVERSITY_IDENTIFIER}" }),
202
+ marc_field(tag: '700', subfields: { a: 'Important Person Collection', '6': '100', d: '1970-',
203
+ '5': helper::UNIVERSITY_IDENTIFIER }),
204
+ marc_field(tag: '710', subfields: { a: 'Important Person Collection Library', '6': '100', d: '1970-',
205
+ '5': helper::UNIVERSITY_IDENTIFIER })]
206
+ end
207
+
208
+ it 'omits any university donor/fund provenance' do
209
+ expect(helper.authors_list(record)).to contain_exactly 'Surname, Name', 'A contributor'
210
+ end
211
+ end
195
212
  end
196
213
 
197
214
  describe '.contributors_list' do
@@ -245,6 +262,21 @@ describe 'PennMARC::Creator' do
245
262
  ['Translator', ['Einstein, Albert 1970-, Translator']]
246
263
  end
247
264
  end
265
+
266
+ context 'with university donor/fund provenance' do
267
+ let(:fields) do
268
+ [marc_field(tag: '700', subfields: { a: 'Surname, Name', '0': 'http://cool.uri/12345', d: '1900-2000',
269
+ e: 'author.', '4': 'http://cool.uri/vocabulary/relators/aut' }),
270
+ marc_field(tag: '700', subfields: { a: 'Important Person Collection', '6': '100', d: '1970-',
271
+ '5': helper::UNIVERSITY_IDENTIFIER }),
272
+ marc_field(tag: '710', subfields: { a: 'Important Person Collection Library', '6': '100', d: '1970-',
273
+ '5': helper::UNIVERSITY_IDENTIFIER })]
274
+ end
275
+
276
+ it 'omits any university donor/fund provenance' do
277
+ expect(helper.contributors_list(record)).to contain_exactly ['Author', ['Surname, Name']]
278
+ end
279
+ end
248
280
  end
249
281
 
250
282
  describe '.show_facet_map' do
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.4.8
4
+ version: 1.4.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Kanning
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2026-07-24 00:00:00.000000000 Z
15
+ date: 2026-10-08 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport