pennmarc 1.0.30 → 1.0.32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/Gemfile.lock +0 -2
  4. data/lib/pennmarc/heading_control.rb +9 -5
  5. data/lib/pennmarc/helpers/access.rb +4 -4
  6. data/lib/pennmarc/helpers/citation.rb +2 -2
  7. data/lib/pennmarc/helpers/classification.rb +10 -7
  8. data/lib/pennmarc/helpers/creator.rb +27 -25
  9. data/lib/pennmarc/helpers/database.rb +8 -8
  10. data/lib/pennmarc/helpers/date.rb +5 -5
  11. data/lib/pennmarc/helpers/edition.rb +7 -7
  12. data/lib/pennmarc/helpers/format.rb +36 -40
  13. data/lib/pennmarc/helpers/genre.rb +5 -5
  14. data/lib/pennmarc/helpers/identifier.rb +18 -18
  15. data/lib/pennmarc/helpers/inventory.rb +7 -7
  16. data/lib/pennmarc/helpers/inventory_entry/base.rb +2 -2
  17. data/lib/pennmarc/helpers/language.rb +4 -4
  18. data/lib/pennmarc/helpers/link.rb +6 -6
  19. data/lib/pennmarc/helpers/location.rb +14 -14
  20. data/lib/pennmarc/helpers/note.rb +2 -2
  21. data/lib/pennmarc/helpers/production.rb +7 -6
  22. data/lib/pennmarc/helpers/relation.rb +14 -14
  23. data/lib/pennmarc/helpers/series.rb +19 -19
  24. data/lib/pennmarc/helpers/subject.rb +28 -28
  25. data/lib/pennmarc/helpers/title.rb +18 -18
  26. data/lib/pennmarc/mappings/headings_override.yml +12 -8
  27. data/lib/pennmarc/parser.rb +5 -5
  28. data/lib/pennmarc/test/marc_helpers.rb +11 -11
  29. data/lib/pennmarc/util.rb +18 -18
  30. data/lib/pennmarc/version.rb +1 -1
  31. data/pennmarc.gemspec +0 -1
  32. data/spec/lib/pennmarc/heading_control_spec.rb +17 -10
  33. data/spec/lib/pennmarc/helpers/creator_spec.rb +15 -12
  34. data/spec/lib/pennmarc/marc_util_spec.rb +12 -0
  35. data/spec/support/fixture_helpers.rb +1 -1
  36. metadata +2 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '07810ba2a6de07713ce40a1cfbe7fc33d5497eec834011a0098ce2cbd74bc5ff'
4
- data.tar.gz: 45c3f0002e46be338a63be2109153f7603d9ebf8b1814d825b4c889c7f7237b4
3
+ metadata.gz: 529930d44585a1ba459c533cd6906bbc910a3b73c2a09bc57c0eb1f2739772b7
4
+ data.tar.gz: 1570743e970c564ece0d3eefa40fd51a720cf920f44cf97fca866770e21785bd
5
5
  SHA512:
6
- metadata.gz: 9a214837d1f061611a13ea7d09b13ae41d7f6f7df8f08d03da3d98d8969849aacb0edfd45a3fea231acb1e53f8c06c4e4793db49cf5274063d6c59d7b7043212
7
- data.tar.gz: 1a6dd99e562ef38b301e49ac17b6ec211eb0af1e7bdccc6a0d98c15683163f9c4168e51b8560296282a42d6dacdbfbb5d8856628af7000614e48961cbcb6b19c
6
+ metadata.gz: 97e6db5b2bccfde42421db0276b890b9ec0ea81bd9862679b1b948ba692d44f0dd23bd54dde788f042908c4dfb6c22f1016109f3ae449711a9c09fba98729aa8
7
+ data.tar.gz: 8dc0c53f5f491f2c403b392fb0edf69ed61fd193e131a118c0ea2f4b3f2d33b24eca1412207d2791320f69475f57fd08e74928d888b5fafba6907f9a6e5251b1
data/Gemfile CHANGED
@@ -5,7 +5,6 @@ source 'https://rubygems.org'
5
5
  gem 'activesupport', '~> 7'
6
6
  gem 'library_stdnums', '~> 1.6'
7
7
  gem 'marc', '~> 1.2'
8
- gem 'multi_string_replace', '~> 2.0'
9
8
  gem 'nokogiri', '~> 1.15'
10
9
  gem 'rake', '~> 13.0'
11
10
  gem 'upennlib-rubocop', require: false
data/Gemfile.lock CHANGED
@@ -19,7 +19,6 @@ GEM
19
19
  scrub_rb (>= 1.0.1, < 2)
20
20
  unf
21
21
  minitest (5.18.0)
22
- multi_string_replace (2.0.2)
23
22
  nokogiri (1.15.2-arm64-darwin)
24
23
  racc (~> 1.4)
25
24
  nokogiri (1.15.2-x64-mingw-ucrt)
@@ -114,7 +113,6 @@ DEPENDENCIES
114
113
  activesupport (~> 7)
115
114
  library_stdnums (~> 1.6)
116
115
  marc (~> 1.2)
117
- multi_string_replace (~> 2.0)
118
116
  nokogiri (~> 1.15)
119
117
  rake (~> 13.0)
120
118
  rspec (~> 3.12)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'multi_string_replace'
4
-
5
3
  module PennMARC
6
4
  # Shared tools and values for controlling handling of subject or genre headings
7
5
  class HeadingControl
@@ -10,6 +8,9 @@ module PennMARC
10
8
  ALLOWED_SOURCE_CODES = %w[aat cct fast ftamc gmgpc gsafd homoit jlabsh lcgft lcsh lcstt lctgm
11
9
  local/osu mesh ndlsh nli nlksh rbbin rbgenr rbmscv rbpap rbpri rbprov rbpub rbtyp].freeze
12
10
 
11
+ REMOVE_TERM_REGEX = /#{Mappers.headings_to_remove&.join('|')}/i
12
+ REPLACE_TERM_REGEX = /(#{Mappers.heading_overrides.keys.join('|')})/i
13
+
13
14
  class << self
14
15
  # Replace or remove any terms in provided values pursuant to the configuration in remove and override mappers.
15
16
  # Used to remove or replace offensive or otherwise undesirable subject headings.
@@ -18,10 +19,13 @@ module PennMARC
18
19
  def term_override(values)
19
20
  values.filter_map do |value|
20
21
  # Remove values if they contain a remove term
21
- next nil if value.match?(/#{Mappers.headings_to_remove&.join('|')}/i)
22
+ next nil if value.match?(REMOVE_TERM_REGEX)
23
+
24
+ # return early if theres no terms to replace
25
+ next value if value.match(REPLACE_TERM_REGEX).nil?
22
26
 
23
- # Replace values using multi_string_replace gem
24
- MultiStringReplace.replace value, Mappers.heading_overrides
27
+ # lookup and perform replacement
28
+ value.sub(::Regexp.last_match.to_s, Mappers.heading_overrides[::Regexp.last_match.to_s.downcase])
25
29
  end
26
30
  end
27
31
  end
@@ -12,7 +12,7 @@ module PennMARC
12
12
  # electronic access or has physical holdings, and is therefore "Online" or "At the library". If a record is "At
13
13
  # the library", but has a link to a finding aid in the 856 field (matching certain criteria), also add 'Online' as
14
14
  # an access method.
15
- # @param [MARC::Record] record
15
+ # @param record [MARC::Record]
16
16
  # @return [Array]
17
17
  def facet(record)
18
18
  values = record.filter_map do |field|
@@ -30,14 +30,14 @@ module PennMARC
30
30
  private
31
31
 
32
32
  # Does the record have added electronic holding info?
33
- # @param [MARC::Field] field
33
+ # @param field [MARC::Field]
34
34
  # @return [Boolean]
35
35
  def electronic_holding_tag?(field)
36
36
  field.tag.in? [Enriched::Pub::ELEC_INVENTORY_TAG, Enriched::Api::ELEC_INVENTORY_TAG]
37
37
  end
38
38
 
39
39
  # Does the record have added physical holding info?
40
- # @param [MARC::Field] field
40
+ # @param field [MARC::Field]
41
41
  # @return [Boolean]
42
42
  def physical_holding_tag?(field)
43
43
  field.tag.in? [Enriched::Pub::PHYS_INVENTORY_TAG, Enriched::Api::PHYS_INVENTORY_TAG]
@@ -51,7 +51,7 @@ module PennMARC
51
51
  # See: https://www.loc.gov/marc/bibliographic/bd856.html
52
52
  # @note Some electronic records do not have Portfolios in Alma, so we rely upon the Resource Link in the 856 to
53
53
  # get these records included in the Online category.
54
- # @param [MARC::Record] record
54
+ # @param record [MARC::Record]
55
55
  # @return [Boolean]
56
56
  def resource_link?(record)
57
57
  record.fields('856').filter_map do |field|
@@ -10,7 +10,7 @@ module PennMARC
10
10
  # abbreviations, etc.). The actual text of a published description is not recorded in field 510 but rather in
11
11
  # field 520 (Summary, Etc. Note).
12
12
  # https://www.loc.gov/marc/bibliographic/bd510.html
13
- # @param [MARC::Record] record
13
+ # @param record [MARC::Record]
14
14
  # @return [Array<String>] array of citations and any linked alternates
15
15
  def cited_in_show(record)
16
16
  datafield_and_linked_alternate(record, '510').uniq
@@ -21,7 +21,7 @@ module PennMARC
21
21
  # each is recorded in a separate occurrence of field 524. The note is sometimes displayed and/or printed with an
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
- # @param [MARC::Record] record
24
+ # @param record [MARC::Record]
25
25
  # @return [Array<String>] array of citation of described materials note and any linked alternates
26
26
  def cite_as_show(record)
27
27
  datafield_and_linked_alternate(record, '524').uniq
@@ -25,7 +25,7 @@ module PennMARC
25
25
  # its title in a single string. See {PennMARC::Enriched} and {PennMARC::Enriched::Api} for more
26
26
  # information on the enriched MARC fields.
27
27
  # @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/ AVA docs
28
- # @param [MARC::Record] record
28
+ # @param record [MARC::Record]
29
29
  # @return [Array<String>] array of classifications
30
30
  def facet(record)
31
31
  record.fields(TAGS).flat_map { |field|
@@ -45,7 +45,7 @@ module PennMARC
45
45
  private
46
46
 
47
47
  # Retrieve subfield code that stores the call number on enriched marc field
48
- # @param [MARC::DataField] field
48
+ # @param field [MARC::DataField]
49
49
  # @return [String]
50
50
  def call_number_sf(field)
51
51
  return Enriched::Pub::ITEM_CALL_NUMBER if field.tag == Enriched::Pub::ITEM_TAG
@@ -54,7 +54,7 @@ module PennMARC
54
54
  end
55
55
 
56
56
  # Retrieve subfield code that stores call number type on enriched marc field
57
- # @param [MARC::DataField] field
57
+ # @param field [MARC::DataField]
58
58
  # @return [String]
59
59
  def call_number_type_sf(field)
60
60
  return Enriched::Pub::ITEM_CALL_NUMBER_TYPE if field.tag == Enriched::Pub::ITEM_TAG
@@ -63,9 +63,9 @@ module PennMARC
63
63
  end
64
64
 
65
65
  # retrieve title of classification based on single char classification code and call number type
66
- # @param[String] class_code classification code
67
- # @param[String] call_number_type value from call number type subfield
68
- # @return [String, NilClass]
66
+ # @param class_code [String] classification code
67
+ # @param call_number_type [String] value from call number type subfield
68
+ # @return [String, nil]
69
69
  def translate_classification(class_code, call_number_type)
70
70
  map = CLASSIFICATION_MAPS[call_number_type]
71
71
 
@@ -77,6 +77,9 @@ module PennMARC
77
77
  # format classification facet by joining single character classification code with its corresponding title.
78
78
  # Our Dewey mapping codes are single digit, so we must concatenate '00' to the class code to accurately reflect
79
79
  # Dewey class codes.
80
+ # @param class_code [String]
81
+ # @param call_number_type [String]
82
+ # @param title [String]
80
83
  # @return [String]
81
84
  def format_facet(class_code, call_number_type, title)
82
85
  return [class_code, title].join(' - ') if loc_call_number_type?(call_number_type)
@@ -85,7 +88,7 @@ module PennMARC
85
88
  end
86
89
 
87
90
  # Determine whether call number type is library of congress
88
- # @param [String] call_number_type value from call number type subfield
91
+ # @param call_number_type [String] value from call number type subfield
89
92
  # @return [Boolean]
90
93
  def loc_call_number_type?(call_number_type)
91
94
  call_number_type == '0'
@@ -86,9 +86,9 @@ module PennMARC
86
86
  end
87
87
 
88
88
  # Returns the list of authors with name (subfield $a) only
89
- # @param [MARC::Record] record
90
- # @param [Boolean] main_tags_only, if true, only use TAGS; otherwise use both TAGS and CONTRIBUTOR_TAGS
91
- # @param [Boolean] first_initial_only: true to only use the first initial instead of first name
89
+ # @param record [MARC::Record]
90
+ # @param main_tags_only [Boolean] only use TAGS; otherwise use both TAGS and CONTRIBUTOR_TAGS
91
+ # @param first_initial_only [Boolean] only use the first initial instead of first name
92
92
  # @return [Array<String>] names of the authors
93
93
  def authors_list(record, main_tags_only: false, first_initial_only: false)
94
94
  tags = if main_tags_only
@@ -99,20 +99,19 @@ module PennMARC
99
99
 
100
100
  fields = record.fields(tags)
101
101
  fields.filter_map { |field|
102
- if first_initial_only
103
- abbreviate_name(field['a']) if field['a']
104
- else
105
- field['a']
102
+ if field['a'].present?
103
+ name = trim_trailing(:comma, field['a'])
104
+ first_initial_only ? abbreviate_name(name) : name
106
105
  end
107
106
  }.uniq
108
107
  end
109
108
 
110
109
  # Show the authors and contributors grouped together by relators with only names
111
- # @param [MARC::Record] record
112
- # @param [Hash] relator_map
113
- # @param [Boolean] include_authors: true to include author fields TAGS
114
- # @param [Boolean] name_only: true to include only the name subfield $a
115
- # @param [Boolean] vernacular: true to include field 880 with subfield $6
110
+ # @param record [MARC::Record]
111
+ # @param relator_map [Hash]
112
+ # @param include_authors [Boolean] include author fields TAGS
113
+ # @param name_only [Boolean] include only the name subfield $a
114
+ # @param vernacular [Boolean] include field 880 with subfield $6
116
115
  # @return [Hash]
117
116
  def contributors_list(record, relator_map: Mappers.relator, include_authors: true, name_only: true,
118
117
  vernacular: false)
@@ -131,10 +130,11 @@ module PennMARC
131
130
  relator = 'Contributor' if relator.blank?
132
131
  relator = trim_punctuation(relator).capitalize
133
132
 
133
+ name = trim_trailing(:comma, field['a'])
134
134
  name = if name_only
135
- field['a']
135
+ name
136
136
  else
137
- join_subfields(field, &subfield_in?(%w[a b c d j q u 3])) + ", #{relator}"
137
+ "#{name} #{join_subfields(field, &subfield_in?(%w[b c d j q u 3]))}, #{relator}"
138
138
  end
139
139
 
140
140
  if contributors.key?(relator)
@@ -294,7 +294,7 @@ module PennMARC
294
294
  private
295
295
 
296
296
  # @param record [MARC::Record]
297
- # @param tags [Array] to consider
297
+ # @param tags [Array] tags to consider
298
298
  # @param relator_map [Hash]
299
299
  # @return [Array<String>] name values from given tags
300
300
  def name_search_values(record:, tags:, relator_map:)
@@ -328,7 +328,7 @@ module PennMARC
328
328
  relator_term_sf = relator_term_subfield(field)
329
329
  name = field.filter_map { |sf|
330
330
  if sf.code == 'a'
331
- should_convert_name_order ? convert_name_order(sf.value) : sf.value
331
+ should_convert_name_order ? convert_name_order(sf.value) : trim_trailing(:comma, sf.value)
332
332
  elsif sf.code == relator_term_sf
333
333
  next
334
334
  elsif NAME_EXCLUDED_SUBFIELDS.exclude?(sf.code)
@@ -348,6 +348,7 @@ module PennMARC
348
348
  # @param name [String] value for processing
349
349
  # @return [String]
350
350
  def convert_name_order(name)
351
+ name = trim_trailing(:comma, name)
351
352
  return name unless name.include? ','
352
353
 
353
354
  after_comma = join_and_squish([trim_trailing(:comma, substring_after(name, ', '))])
@@ -356,16 +357,17 @@ module PennMARC
356
357
  end
357
358
 
358
359
  # Convert "Lastname, First" to "Lastname, F"
359
- # @param [String] name
360
+ # @param name [String]
361
+ # @return [String]
360
362
  def abbreviate_name(name)
361
- name_parts = name.split(', ')
362
- return '' if name_parts.empty?
363
-
364
- first_name_parts = name_parts.last.split
365
- temp_name = "#{name_parts.first}, #{first_name_parts.first[0, 1]}."
366
- first_name_parts.shift
367
- temp_name += " #{first_name_parts.join(' ')}" unless first_name_parts.empty?
368
- temp_name
363
+ name = trim_trailing(:comma, name)
364
+ return name unless name.include? ','
365
+
366
+ after_comma = join_and_squish([trim_trailing(:comma, substring_after(name, ','))])
367
+ before_comma = substring_before(name, ',')
368
+ abbrv = "#{before_comma},"
369
+ abbrv += " #{after_comma.first.upcase}." if after_comma.present?
370
+ abbrv
369
371
  end
370
372
 
371
373
  # Parse creator facet value from given creator field and desired subfields
@@ -16,8 +16,8 @@ module PennMARC
16
16
  # Retrieves database subtype (subfield 'b') from
17
17
  # {https://upennlibrary.atlassian.net/wiki/spaces/ALMA/pages/323912493/Local+9XX+Field+Use+in+Almalocal
18
18
  # local field 944}. Only returns database subtype if Penn's Database facet value is present in subfield 'a'.
19
- # @param [Marc::Record]
20
- # @return [Array<string>] Array of types
19
+ # @param record [MARC::Record]
20
+ # @return [Array<String>] Array of types
21
21
  def type_facet(record)
22
22
  record.fields('944').filter_map { |field|
23
23
  # skip unless specified database format type present
@@ -32,8 +32,8 @@ module PennMARC
32
32
  # {https://upennlibrary.atlassian.net/wiki/spaces/ALMA/pages/323912493/Local+9XX+Field+Use+in+Almalocal
33
33
  # local field 943}. Only returns database subject category if Penn's Community of Interest code is present in
34
34
  # subfield '2'.
35
- # @param [Marc::Record]
36
- # @return [Array<string>] Array of categories
35
+ # @param record [MARC::Record]
36
+ # @return [Array<String>] Array of categories
37
37
  def category_facet(record)
38
38
  return [] unless curated_db?(record)
39
39
 
@@ -53,8 +53,8 @@ module PennMARC
53
53
  # local field 943}. Only returns subcategory if Penn's Community of Interest code is present in subfield '2'.
54
54
  # @note return value differs from legacy implementation. This version only returns ["category--subcategory"] or
55
55
  # an empty array.
56
- # @param [Marc::Record]
57
- # @return [Array<string>] Array of "category--subcategory"
56
+ # @param record [MARC::Record]
57
+ # @return [Array<String>] Array of "category--subcategory"
58
58
  def subcategory_facet(record)
59
59
  return [] unless curated_db?(record)
60
60
 
@@ -79,8 +79,8 @@ module PennMARC
79
79
  private
80
80
 
81
81
  # Determines if Database format type is format type used to facet databases
82
- # @param [Marc::Record]
83
- # @return [TrueClass, FalseClass]
82
+ # @param record [MARC::Record]
83
+ # @return [Boolean]
84
84
  def curated_db?(record)
85
85
  record.fields('944').any? { |field| subfield_value?(field, 'a', /#{DATABASES_FACET_VALUE}/o) }
86
86
  end
@@ -7,7 +7,7 @@ module PennMARC
7
7
  # Retrieve publication date (Date 1) from {https://www.loc.gov/marc/bibliographic/bd008a.html 008 field}.
8
8
  # Publication date is a four-digit year found in position 7-10 and may contain 'u' characters to represent
9
9
  # partially known dates. We replace any occurrences of 'u' with '0' before converting to DateTime object.
10
- # @param [MARC::Record] record
10
+ # @param record [MARC::Record]
11
11
  # @return [Time, nil] The publication date, or nil if date found in record is invalid
12
12
  def publication(record)
13
13
  record.fields('008').filter_map { |field|
@@ -22,7 +22,7 @@ module PennMARC
22
22
  # Retrieve date added (subfield 'q') from enriched marc 'itm' field.
23
23
  # {PennMARC::Enriched} maps enriched marc fields and subfields created during Alma publishing. The enriched
24
24
  # metadata provided by the Alma API does not include the date created value, so we can't work with that here.
25
- # @param [MARC::Record] record
25
+ # @param record [MARC::Record]
26
26
  # @return [Time, nil] The date added, or nil if date found in record is invalid
27
27
  def added(record)
28
28
  record.fields(Enriched::Pub::ITEM_TAG).flat_map { |field|
@@ -46,7 +46,7 @@ module PennMARC
46
46
  # Retrieve date last updated from {https://www.loc.gov/marc/bibliographic/bd005.html 005 field}.
47
47
  # Date last updated is a sixteen character String recorded in
48
48
  # {https://www.iso.org/iso-8601-date-and-time-format.html ISO 8601} format.
49
- # @param [MARC::Record] record
49
+ # @param record [MARC::Record]
50
50
  # @return [Time, nil] The date last updated, or nil if date found in record is invalid
51
51
  def last_updated(record)
52
52
  record.fields('005').filter_map { |field|
@@ -69,8 +69,8 @@ module PennMARC
69
69
  private
70
70
 
71
71
  # Sanitizes a partially known date string by replacing any 'u' occurrences with a specified replacement value.
72
- # @param [String] date The date string in '%Y' format, potentially containing 'u' characters.
73
- # @param [String] replacement The value with which to replace 'u' occurrences in the date string.
72
+ # @param date [String] The date string in '%Y' format, potentially containing 'u' characters.
73
+ # @param replacement [String] The value with which to replace 'u' occurrences in the date string.
74
74
  # @return [String, nil] The sanitized date string with 'u' characters replaced by the replacement value,
75
75
  # or nil if the date string does not match the expected format.
76
76
  def sanitize_partially_known_date(date, replacement)
@@ -11,7 +11,7 @@ module PennMARC
11
11
  # sequential edition statements such as 1st- ed. This type of information is contained in field 362 (Dates of
12
12
  # Publication and/or Volume Designation).
13
13
  # https://www.loc.gov/marc/bibliographic/bd250.html
14
- # @param [MARC::Record] record
14
+ # @param record [MARC::Record]
15
15
  # @return [Array<String>] array of editions and their alternates
16
16
  def show(record, with_alternate: true)
17
17
  editions = record.fields('250').map do |field|
@@ -23,8 +23,8 @@ module PennMARC
23
23
  end
24
24
 
25
25
  # Edition values for display in search results. Just grab the first 250 field.
26
- # @param [MARC::Record] record
27
- # @return [String, NilClass] string of all first 250 subfields, excluding 6 and 8
26
+ # @param record [MARC::Record]
27
+ # @return [String, nil] string of all first 250 subfields, excluding 6 and 8
28
28
  def values(record)
29
29
  edition = record.fields('250').first
30
30
  return if edition.blank?
@@ -36,8 +36,8 @@ module PennMARC
36
36
  # from this field, the introductory phrase Other editions available: may be generated based on the field tag for
37
37
  # display.
38
38
  # https://www.loc.gov/marc/bibliographic/bd775.html
39
- # @param [MARC::Record] record
40
- # @param [Hash] relator_map
39
+ # @param record [MARC::Record]
40
+ # @param relator_map [Hash]
41
41
  # @return [Array<String>] array of other edition strings
42
42
  def other_show(record, relator_map: Mappers.relator)
43
43
  values = record.fields('775').filter_map do |field|
@@ -57,8 +57,8 @@ module PennMARC
57
57
  private
58
58
 
59
59
  # Assemble a string of relevant edition information.
60
- # @param [MARC::DataField] field
61
- # @param [Hash] relator_map
60
+ # @param field [MARC::DataField]
61
+ # @param relator_map [Hash]
62
62
  # @return [String (frozen)] assembled other version string
63
63
  def other_edition_value(field, relator_map)
64
64
  subi = remove_paren_value_from_subfield_i(field) || ''
@@ -33,7 +33,7 @@ module PennMARC
33
33
  # 254, 255, 310, 342, 352, 362 or {https://www.oclc.org/bibformats/en/3xx/340.html 340} field. based on the source
34
34
  # field, different subfields are used.
35
35
  # @note ported from get_format_display
36
- # @param [MARC::Record] record
36
+ # @param record [MARC::Record]
37
37
  # @return [Array<String>] format values for display
38
38
  def show(record)
39
39
  results = record.fields('300').map { |f| join_subfields(f, &subfield_not_in?(%w[3 6 8])) }
@@ -70,13 +70,9 @@ module PennMARC
70
70
  # 5. Media Type values from {https://www.oclc.org/bibformats/en/3xx/337.html#subfielda 337 ǂa}
71
71
  # Additional fields are considered for many of the formats. Much of this logic has been moved to private methods
72
72
  # to keep this method from becoming too unwieldy.
73
- # @todo is the conditional structure here still best practice? see the "Thesis on Microfilm" case in the specs
74
- # for this helper method
75
73
  # @note ported from get_format
76
- # @param [MARC::Record] record
77
- # @param [Hash] location_map
74
+ # @param record [MARC::Record]
78
75
  # @return [Array<String>] format values for faceting
79
-
80
76
  def facet(record)
81
77
  formats = []
82
78
  format_code = leader_format(record.leader)
@@ -113,7 +109,7 @@ module PennMARC
113
109
 
114
110
  # Show "Other Format" values from {https://www.oclc.org/bibformats/en/7xx/776.html 776} and any 880 linkage.
115
111
  # @todo is 774 an error in the linked field in legacy? i changed to 776 here
116
- # @param [MARC::Record] record
112
+ # @param record [MARC::Record]
117
113
  # @return [Array<String>] other format values for display
118
114
  def other_show(record)
119
115
  values = record.fields('776').filter_map do |field|
@@ -130,7 +126,7 @@ module PennMARC
130
126
 
131
127
  # Retrieve cartographic reference data for map/atlas formats for display from
132
128
  # {https://www.oclc.org/bibformats/en/2xx/255.html 255} and {https://www.oclc.org/bibformats/en/3xx/342.html 342}
133
- # @param [MARC::Record] record
129
+ # @param record [MARC::Record]
134
130
  # @return [Array<String>]
135
131
  def cartographic_show(record)
136
132
  record.fields(%w[255 342]).map { |field|
@@ -139,7 +135,7 @@ module PennMARC
139
135
  end
140
136
 
141
137
  # Check if leader format code is either 't', 'f', or 'd'
142
- # @param [String] format_code
138
+ # @param format_code [String]
143
139
  # @return [Boolean]
144
140
  def include_manuscripts?(format_code)
145
141
  format_code.first.in? %w[t f d]
@@ -149,7 +145,7 @@ module PennMARC
149
145
 
150
146
  # Get Call Numbers for holdings using the 'Classification part' which can contain strings like
151
147
  # 'Microfilm'. Look in enriched tags used by both Alma Publishing and API.
152
- # @param [MARC::Record] record
148
+ # @param record [MARC::Record]
153
149
  # @return [Array]
154
150
  def call_nums(record)
155
151
  if field_defined?(record, Enriched::Pub::PHYS_INVENTORY_TAG)
@@ -169,7 +165,7 @@ module PennMARC
169
165
  # Get 'Curated' format from.
170
166
  # {https://upennlibrary.atlassian.net/wiki/spaces/ALMA/pages/323912493/Local+9XX+Field+Use+in+Alma local field
171
167
  # 944} ǂa, as long as it is not a numerical value.
172
- # @param [MARC::Record] record
168
+ # @param record [MARC::Record]
173
169
  # @return [Array]
174
170
  def curated_format(record)
175
171
  record.fields('944').filter_map { |field|
@@ -180,57 +176,57 @@ module PennMARC
180
176
  }.uniq
181
177
  end
182
178
 
183
- # @param [String] format_code
179
+ # @param format_code [String]
184
180
  # @return [Boolean]
185
181
  def image?(format_code)
186
182
  format_code.in?(%w[km kd])
187
183
  end
188
184
 
189
- # @param [String] format_code
185
+ # @param format_code [String]
190
186
  # @return [Boolean]
191
187
  def datafile?(format_code)
192
188
  format_code == 'mm'
193
189
  end
194
190
 
195
- # @param [String] format_code
191
+ # @param format_code [String]
196
192
  # @return [Boolean]
197
193
  def journal_periodical?(format_code)
198
194
  format_code.in?(%w[as gs])
199
195
  end
200
196
 
201
- # @param [String] format_code
197
+ # @param format_code [String]
202
198
  # @return [Boolean]
203
199
  def three_d_object?(format_code)
204
200
  format_code.start_with?('r')
205
201
  end
206
202
 
207
- # @param [String] format_code
203
+ # @param format_code [String]
208
204
  # @return [Boolean]
209
205
  def sound_recording?(format_code)
210
206
  format_code.in?(%w[im jm jc jd js])
211
207
  end
212
208
 
213
- # @param [String] format_code
209
+ # @param format_code [String]
214
210
  # @return [Boolean]
215
211
  def graphical_media?(format_code)
216
212
  format_code == 'gm'
217
213
  end
218
214
 
219
- # @param [String] format_code
215
+ # @param format_code [String]
220
216
  # @return [Boolean]
221
217
  def map_atlas?(format_code)
222
218
  format_code&.start_with?('e') || format_code == 'fm'
223
219
  end
224
220
 
225
- # @param [String] format_code
221
+ # @param format_code [String]
226
222
  # @return [Boolean]
227
223
  def musical_score?(format_code)
228
224
  format_code.in?(%w[ca cb cc cd cm cs dc dm])
229
225
  end
230
226
 
231
- # @param [String] format_code
232
- # @param [Array<String>] media_type
233
- # @param [MARC::Record] record
227
+ # @param format_code [String]
228
+ # @param media_type [Array<String>]
229
+ # @param record [MARC::Record]
234
230
  # @return [Boolean]
235
231
  def book?(format_code, media_type, record)
236
232
  title_forms = subfield_values_for tag: '245', subfield: :k, record: record
@@ -239,17 +235,17 @@ module PennMARC
239
235
  media_type.none? { |val| val =~ /micro/i }
240
236
  end
241
237
 
242
- # @param [Array<String>] f006_forms
243
- # @param [String] format_code
238
+ # @param f006_forms [Array<String>]
239
+ # @param format_code [String]
244
240
  # @return [Boolean]
245
241
  def website_database?(f006_forms, format_code)
246
242
  format_code&.end_with?('i') ||
247
243
  (format_code == 'am' && f006_forms.include?('m') && f006_forms.include?('s'))
248
244
  end
249
245
 
250
- # @param [String] f008
251
- # @param [MARC::Record] record
252
- # @param [String] format_code
246
+ # @param f008 [String]
247
+ # @param record [MARC::Record]
248
+ # @param format_code [String]
253
249
  # @return [Boolean]
254
250
  def government_document?(f008, record, format_code)
255
251
  # is a 260 entry present, and does it have a b that matches 'press'
@@ -259,31 +255,31 @@ module PennMARC
259
255
  %w[c d i j].exclude?(format_code[0]) && f008[28].in?(%w[f i o]) && !f260press
260
256
  end
261
257
 
262
- # @param [String] f008
263
- # @param [String] format_code
258
+ # @param f008 [String]
259
+ # @param format_code [String]
264
260
  # @return [Boolean]
265
261
  def newspaper?(f008, format_code)
266
262
  format_code == 'as' && (f008[21] == 'n' || f008[22] == 'e')
267
263
  end
268
264
 
269
- # @param [MARC::Record] record
265
+ # @param record [MARC::Record]
270
266
  # @return [Boolean]
271
267
  def conference_event?(record)
272
268
  record.fields('111').any? || record.fields('711').any? # TODO: use field_present helper here and below?
273
269
  end
274
270
 
275
- # @param [MARC::Record] record
276
- # @param [String] format_code
271
+ # @param record [MARC::Record]
272
+ # @param format_code [String]
277
273
  # @return [Boolean]
278
274
  def thesis_or_dissertation?(format_code, record)
279
275
  record.fields('502').any? && format_code.in?(%w[am tm dm])
280
276
  end
281
277
 
282
- # @param [Array<String>] call_nums
283
- # @param [Array<String>] f007
284
- # @param [String] f008
285
- # @param [Array<String>] title_medium
286
- # @param [Array<String>] media_type
278
+ # @param call_nums [Array<String>]
279
+ # @param f007 [Array<String>]
280
+ # @param f008 [String]
281
+ # @param title_medium [Array<String>]
282
+ # @param media_type [Array<String>]
287
283
  # @return [Boolean]
288
284
  def micro_or_microform?(call_nums, f007, f008, media_type, title_medium)
289
285
  [f008[23], f008[29]].any? { |v| v.in?(%w[a b c]) } ||
@@ -296,7 +292,7 @@ module PennMARC
296
292
  # Determine archive format by checking if {https://www.loc.gov/marc/bibliographic/hd852.html 852} and
297
293
  # {PennMARC::Enriched} Publishing Tag 'ITM' have values that match any of the following archive locations:
298
294
  # archarch, musearch, scfreed, univarch, archivcoll
299
- # @param [MARC::Record] record
295
+ # @param record [MARC::Record]
300
296
  # @return [Boolean]
301
297
  def archive?(record)
302
298
  enriched_tag = Enriched::Pub::ITEM_TAG
@@ -311,7 +307,7 @@ module PennMARC
311
307
  end
312
308
 
313
309
  # Consider {https://www.loc.gov/marc/bibliographic/bd007g.html 007} to determine graphical media format
314
- # @param [Array<String>] f007
310
+ # @param f007 [Array<String>]
315
311
  # @return [String (frozen)]
316
312
  def graphical_media_type(f007)
317
313
  if f007.any? { |v| v.start_with?('g') }
@@ -321,7 +317,7 @@ module PennMARC
321
317
  end
322
318
  end
323
319
 
324
- # @param [String] leader
320
+ # @param leader [String]
325
321
  # @return [String]
326
322
  def leader_format(leader)
327
323
  leader[6..7] || ' '