pennmarc 0.0.2 → 1.0.1

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/.rubocop_todo.yml +143 -0
  4. data/Gemfile +1 -1
  5. data/README.md +12 -2
  6. data/lib/pennmarc/helpers/creator.rb +59 -21
  7. data/lib/pennmarc/helpers/database.rb +8 -8
  8. data/lib/pennmarc/helpers/date.rb +16 -15
  9. data/lib/pennmarc/helpers/edition.rb +25 -20
  10. data/lib/pennmarc/helpers/format.rb +15 -4
  11. data/lib/pennmarc/helpers/genre.rb +13 -11
  12. data/lib/pennmarc/helpers/helper.rb +1 -0
  13. data/lib/pennmarc/helpers/identifier.rb +16 -7
  14. data/lib/pennmarc/helpers/language.rb +3 -3
  15. data/lib/pennmarc/helpers/link.rb +6 -0
  16. data/lib/pennmarc/helpers/location.rb +8 -8
  17. data/lib/pennmarc/helpers/note.rb +52 -2
  18. data/lib/pennmarc/helpers/relation.rb +4 -4
  19. data/lib/pennmarc/helpers/series.rb +171 -85
  20. data/lib/pennmarc/helpers/subject.rb +16 -17
  21. data/lib/pennmarc/helpers/title.rb +1 -1
  22. data/lib/pennmarc/mappers.rb +31 -0
  23. data/lib/pennmarc/parser.rb +34 -157
  24. data/lib/pennmarc/util.rb +15 -16
  25. data/pennmarc.gemspec +2 -2
  26. data/spec/lib/pennmarc/helpers/citation_spec.rb +1 -2
  27. data/spec/lib/pennmarc/helpers/creator_spec.rb +54 -19
  28. data/spec/lib/pennmarc/helpers/date_spec.rb +5 -5
  29. data/spec/lib/pennmarc/helpers/edition_spec.rb +4 -6
  30. data/spec/lib/pennmarc/helpers/format_spec.rb +30 -10
  31. data/spec/lib/pennmarc/helpers/genre_spec.rb +4 -4
  32. data/spec/lib/pennmarc/helpers/identifer_spec.rb +15 -0
  33. data/spec/lib/pennmarc/helpers/language_spec.rb +1 -1
  34. data/spec/lib/pennmarc/helpers/location_spec.rb +2 -1
  35. data/spec/lib/pennmarc/helpers/note_spec.rb +67 -2
  36. data/spec/lib/pennmarc/helpers/relation_spec.rb +2 -2
  37. data/spec/lib/pennmarc/helpers/series_spec.rb +54 -0
  38. data/spec/lib/pennmarc/helpers/subject_spec.rb +9 -9
  39. data/spec/lib/pennmarc/helpers/title_spec.rb +3 -1
  40. data/spec/lib/pennmarc/marc_util_spec.rb +9 -8
  41. data/spec/lib/pennmarc/parser_spec.rb +24 -3
  42. data/spec/spec_helper.rb +1 -1
  43. metadata +8 -20
  44. data/legacy/indexer.rb +0 -568
  45. data/legacy/marc.rb +0 -2964
  46. data/legacy/test_file_output.json +0 -49
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b68bae786cc1cd9bcd1bb53e401be81bc3a97d4bb4319c6b37f9089898721424
4
- data.tar.gz: ca840e625b1fbfe4e8e9cd9ef042eb2f8afbc8323e620b8fcb7f190d2e65c71c
3
+ metadata.gz: e574f1fae4f59435df3bf467da310ae7e426d82c2fe54ae2321ad326c05e5e99
4
+ data.tar.gz: de545e5a150b26c73e814e36b167bb688d267a97205cf4cdbab15dfd5c3225a8
5
5
  SHA512:
6
- metadata.gz: 5d7c2a945285aec3959c3594414f937005ed981c4ed0d7c6ffb567456f7c25ec7a08dfb06fb0cb8316b482743637724b756d348596946e909087a7ad51d4e658
7
- data.tar.gz: e542bb11f7174cbfe3bb1f55aac1ac769a7fd004dc828354e09ac52911ffee680f3782189181d0d28617e2db9557c1cf654ae40f3c3f9e467b2e11657d9a33a2
6
+ metadata.gz: 3c3fc981f5999eaca710a54fa3d247f2d01cc8183e13212151afab0cbb5b37f93531cbd264b22d1d4f30ef730b800efe38039b4bfc42a44cd28778c06f0cde3f
7
+ data.tar.gz: 729f0f80fd9d9ade7d1ae1085610cd85b8ab31beb1245efcaee246a18c01238abd5adc18dcf995f624448d518f4e36222a71c972d00c537c6367229f7d8d35c6
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ inherit_gem:
4
+ upennlib-rubocop: upennlib_rubocop_defaults.yml
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,143 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 10000`
3
+ # on 2023-08-14 17:52:48 UTC using RuboCop version 1.51.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 22
10
+ # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
11
+ Metrics/AbcSize:
12
+ Exclude:
13
+ - 'lib/pennmarc/helpers/creator.rb'
14
+ - 'lib/pennmarc/helpers/edition.rb'
15
+ - 'lib/pennmarc/helpers/format.rb'
16
+ - 'lib/pennmarc/helpers/genre.rb'
17
+ - 'lib/pennmarc/helpers/location.rb'
18
+ - 'lib/pennmarc/helpers/note.rb'
19
+ - 'lib/pennmarc/helpers/production.rb'
20
+ - 'lib/pennmarc/helpers/relation.rb'
21
+ - 'lib/pennmarc/helpers/series.rb'
22
+ - 'lib/pennmarc/helpers/subject.rb'
23
+ - 'lib/pennmarc/helpers/title.rb'
24
+ - 'lib/pennmarc/util.rb'
25
+
26
+ # Offense count: 5
27
+ # Configuration parameters: CountComments, Max, CountAsOne.
28
+ Metrics/ClassLength:
29
+ Exclude:
30
+ - 'lib/pennmarc/helpers/creator.rb'
31
+ - 'lib/pennmarc/helpers/format.rb'
32
+ - 'lib/pennmarc/helpers/series.rb'
33
+ - 'lib/pennmarc/helpers/subject.rb'
34
+ - 'lib/pennmarc/helpers/title.rb'
35
+
36
+ # Offense count: 18
37
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
38
+ Metrics/CyclomaticComplexity:
39
+ Exclude:
40
+ - 'lib/pennmarc/helpers/creator.rb'
41
+ - 'lib/pennmarc/helpers/database.rb'
42
+ - 'lib/pennmarc/helpers/edition.rb'
43
+ - 'lib/pennmarc/helpers/format.rb'
44
+ - 'lib/pennmarc/helpers/genre.rb'
45
+ - 'lib/pennmarc/helpers/note.rb'
46
+ - 'lib/pennmarc/helpers/production.rb'
47
+ - 'lib/pennmarc/helpers/relation.rb'
48
+ - 'lib/pennmarc/helpers/series.rb'
49
+ - 'lib/pennmarc/helpers/subject.rb'
50
+ - 'lib/pennmarc/helpers/title.rb'
51
+ - 'lib/pennmarc/util.rb'
52
+
53
+ # Offense count: 24
54
+ # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
55
+ Metrics/MethodLength:
56
+ Exclude:
57
+ - 'lib/pennmarc/helpers/creator.rb'
58
+ - 'lib/pennmarc/helpers/date.rb'
59
+ - 'lib/pennmarc/helpers/edition.rb'
60
+ - 'lib/pennmarc/helpers/format.rb'
61
+ - 'lib/pennmarc/helpers/location.rb'
62
+ - 'lib/pennmarc/helpers/note.rb'
63
+ - 'lib/pennmarc/helpers/production.rb'
64
+ - 'lib/pennmarc/helpers/relation.rb'
65
+ - 'lib/pennmarc/helpers/series.rb'
66
+ - 'lib/pennmarc/helpers/subject.rb'
67
+ - 'lib/pennmarc/helpers/title.rb'
68
+
69
+ # Offense count: 1
70
+ # Configuration parameters: CountComments, Max, CountAsOne.
71
+ Metrics/ModuleLength:
72
+ Exclude:
73
+ - 'lib/pennmarc/util.rb'
74
+
75
+ # Offense count: 12
76
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
77
+ Metrics/PerceivedComplexity:
78
+ Exclude:
79
+ - 'lib/pennmarc/helpers/creator.rb'
80
+ - 'lib/pennmarc/helpers/edition.rb'
81
+ - 'lib/pennmarc/helpers/format.rb'
82
+ - 'lib/pennmarc/helpers/genre.rb'
83
+ - 'lib/pennmarc/helpers/note.rb'
84
+ - 'lib/pennmarc/helpers/production.rb'
85
+ - 'lib/pennmarc/helpers/series.rb'
86
+ - 'lib/pennmarc/helpers/title.rb'
87
+ - 'lib/pennmarc/util.rb'
88
+
89
+ # Offense count: 2
90
+ # This cop supports safe autocorrection (--autocorrect).
91
+ # Configuration parameters: EnforcedStyle, BlockForwardingName.
92
+ # SupportedStyles: anonymous, explicit
93
+ Naming/BlockForwarding:
94
+ Exclude:
95
+ - 'lib/pennmarc/util.rb'
96
+
97
+ # Offense count: 1
98
+ # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros.
99
+ # NamePrefix: is_, has_, have_
100
+ # ForbiddenPrefixes: is_, has_, have_
101
+ # AllowedMethods: is_a?
102
+ # MethodDefinitionMacros: define_method, define_singleton_method
103
+ Naming/PredicateName:
104
+ Exclude:
105
+ - 'lib/pennmarc/helpers/relation.rb'
106
+
107
+ # Offense count: 2
108
+ # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
109
+ # SupportedStyles: snake_case, normalcase, non_integer
110
+ # AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
111
+ Naming/VariableNumber:
112
+ Exclude:
113
+ - 'lib/pennmarc/util.rb'
114
+
115
+ # Offense count: 6
116
+ # Configuration parameters: Max, CountAsOne.
117
+ RSpec/ExampleLength:
118
+ Exclude:
119
+ - 'spec/lib/pennmarc/helpers/creator_spec.rb'
120
+ - 'spec/lib/pennmarc/helpers/note_spec.rb'
121
+ - 'spec/lib/pennmarc/helpers/production_spec.rb'
122
+ - 'spec/lib/pennmarc/marc_util_spec.rb'
123
+
124
+ # Offense count: 1
125
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
126
+ # Include: **/*_spec*rb*, **/spec/**/*
127
+ RSpec/FilePath:
128
+ Exclude:
129
+ - 'spec/lib/pennmarc/parser_spec.rb'
130
+
131
+ # Offense count: 4
132
+ # Configuration parameters: Max, AllowedGroups.
133
+ RSpec/NestedGroups:
134
+ Exclude:
135
+ - 'spec/lib/pennmarc/helpers/format_spec.rb'
136
+
137
+ # Offense count: 2
138
+ # This cop supports unsafe autocorrection (--autocorrect-all).
139
+ # Configuration parameters: Include.
140
+ # Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb
141
+ Rails/Output:
142
+ Exclude:
143
+ - 'lib/pennmarc/helpers/date.rb'
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ gem 'library_stdnums', '~> 1.6'
7
7
  gem 'marc', '~> 1.2'
8
8
  gem 'nokogiri', '~> 1.15'
9
9
  gem 'rake', '~> 13.0'
10
+ gem 'upennlib-rubocop', require: false
10
11
 
11
12
  group :test, :development do
12
13
  gem 'rspec', '~> 3.12'
@@ -17,7 +18,6 @@ group :test do
17
18
  end
18
19
 
19
20
  group :development do
20
- gem 'upennlib-rubocop', require: false
21
21
  gem 'webrick', '~> 1.8'
22
22
  gem 'yard', '~> 0.9'
23
23
  end
data/README.md CHANGED
@@ -53,6 +53,12 @@ To run rubocop with the configuration:
53
53
  rubocop
54
54
  ```
55
55
 
56
+ #### To regenerate `.rubocop_todo.yml`:
57
+ ```shell
58
+ bundle exec rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 10000
59
+ ```
60
+
61
+
56
62
  ### Testing
57
63
 
58
64
  Testing is done with `rspec`. Test coverage should approach 100% given the relative simplicity of this gem.
@@ -63,6 +69,12 @@ To run the test suite:
63
69
  rspec
64
70
  ```
65
71
 
72
+ ## Publishing the Gem
73
+
74
+ 1. Update the version in `pennmarc.gemspec`
75
+ 2. Run `gem build pennmarc.gemspec` with the latest code
76
+ 3. Run `gem push pennmarc-{version number here}`(e.g. `gem push pennmarc-1.0.0`) to push to RubyGems. You will need access and MFA setup with RubyGems.
77
+
66
78
  ## QA
67
79
 
68
80
  ### Checking output of an arbitrary MARC XML file
@@ -75,8 +87,6 @@ MARC_FILE=path/to/marc.xml bundle exec rake pennmarc:parse
75
87
 
76
88
  ## TODO
77
89
  - rake task or some similar command to return a full set of values extracted from a specified marcxml file
78
- - hosting of yard output files?
79
- - mappings (locations, call number, languages)
80
90
  - Pipeline to run tests and publish to Rubygems
81
91
  - rubocop check
82
92
  - rdoc/yard coverage checks?
@@ -24,43 +24,45 @@ module PennMARC
24
24
  # indicator1 tell us the order of the name?
25
25
  # @note ported from get_author_creator_1_search_values
26
26
  # @param [MARC::Record] record
27
- # @param [Hash] relator_mapping
27
+ # @param [Hash] relator_map
28
28
  # @return [Array<String>] array of author/creator values for indexing
29
- def search(record, relator_mapping)
29
+ def search(record, relator_map: Mappers.relator)
30
+ creator_subfields = %w[a 1 4 6 8]
30
31
  acc = record.fields(TAGS).map do |field|
31
32
  pieces = field.filter_map do |sf|
32
33
  if sf.code == 'a'
33
34
  convert_name_order(sf.value)
34
- elsif %w[a 1 4 6 8].exclude?(sf.code)
35
+ elsif creator_subfields.exclude?(sf.code)
35
36
  sf.value
36
37
  elsif sf.code == '4'
37
- relator = translate_relator(sf.value, relator_mapping)
38
+ relator = translate_relator(sf.value, relator_map)
38
39
  next if relator.blank?
39
40
 
40
41
  relator
41
42
  end
42
43
  end
43
44
  value = join_and_squish(pieces)
44
- if value.end_with?('.') || value.end_with?('-')
45
+ if value.end_with?('.', '-')
45
46
  value
46
47
  else
47
48
  "#{value}."
48
49
  end
49
50
  end
50
51
  # a second iteration over the same fields produces name entries with the names not reordered
52
+ secondary_subfields = %w[4 6 8]
51
53
  acc += record.fields(TAGS).map do |field|
52
54
  pieces = field.filter_map do |sf|
53
- if !%w[4 6 8].member?(sf.code)
55
+ if secondary_subfields.exclude?(sf.code)
54
56
  sf.value
55
57
  elsif sf.code == '4'
56
- relator = translate_relator(sf.value, relator_mapping)
58
+ relator = translate_relator(sf.value, relator_map)
57
59
  next if relator.blank?
58
60
 
59
61
  relator
60
62
  end
61
63
  end
62
64
  value = join_and_squish(pieces)
63
- if value.end_with?('.') || value.end_with?('-')
65
+ if value.end_with?('.', '-')
64
66
  value
65
67
  else
66
68
  "#{value}."
@@ -69,9 +71,9 @@ module PennMARC
69
71
  acc += record.fields(%w[880]).filter_map do |field|
70
72
  next unless field.any? { |sf| sf.code == '6' && sf.value.in?(%w[100 110]) }
71
73
 
72
- suba = field.find_all(&subfield_in?(%w[a])).map do |sf|
74
+ suba = field.find_all(&subfield_in?(%w[a])).map { |sf|
73
75
  convert_name_order(sf.value)
74
- end.first
76
+ }.first
75
77
  oth = join_and_squish(field.find_all(&subfield_not_in?(%w[6 8 a t])).map(&:value))
76
78
  join_and_squish [suba, oth]
77
79
  end
@@ -88,11 +90,11 @@ module PennMARC
88
90
  # All author/creator values for display (like #show, but multivalued?) - no 880 linkage
89
91
  # @note ported from get_author_creator_values (indexed as author_creator_a) - shown on results page
90
92
  # @param [MARC::Record] record
91
- # @param [Hash] relator_mapping
93
+ # @param [Hash] relator_map
92
94
  # @return [Array<String>] array of author/creator values for display
93
- def values(record, relator_mapping)
95
+ def values(record, relator_map: Mappers.relator)
94
96
  record.fields(TAGS).map do |field|
95
- name_from_main_entry(field, relator_mapping)
97
+ name_from_main_entry(field, relator_map)
96
98
  end
97
99
  end
98
100
 
@@ -109,8 +111,7 @@ module PennMARC
109
111
  end
110
112
  end
111
113
 
112
- # Author/Creator sort. Does not map and include any relator
113
- # codes.
114
+ # Author/Creator sort. Does not map and include any relator codes.
114
115
  # @todo This includes any URI from ǂ0 which could help to disambiguate in sorts, but ǂ1 is excluded...
115
116
  # @note ported from get_author_creator_sort_values
116
117
  # @param [MARC::Record] record
@@ -135,7 +136,7 @@ module PennMARC
135
136
  }
136
137
  source_map.flat_map do |field_num, subfields|
137
138
  record.fields(field_num.to_s).map do |field|
138
- trim_punctuation(join_subfields(field, &subfield_in?(subfields.split(''))))
139
+ trim_punctuation(join_subfields(field, &subfield_in?(subfields.chars)))
139
140
  end
140
141
  end
141
142
  end
@@ -145,7 +146,7 @@ module PennMARC
145
146
  # @param [MARC::Record] record
146
147
  # @param [Hash] relator_map
147
148
  # @return [Array<String>] array of conference values
148
- def conference_show(record, relator_map)
149
+ def conference_show(record, relator_map: Mappers.relator)
149
150
  record.fields('111').filter_map do |field|
150
151
  name_from_main_entry field, relator_map
151
152
  end
@@ -183,6 +184,42 @@ module PennMARC
183
184
  # @note see get_conference_search_values
184
185
  def conference_search(record); end
185
186
 
187
+ # Retrieve contributor values for display from fields {https://www.oclc.org/bibformats/en/7xx/700.html 700}
188
+ # and {https://www.oclc.org/bibformats/en/7xx/710.html 710} and their linked alternates. Joins subfields
189
+ # 'a', 'b', 'c', 'd', 'j', and 'q'. Then appends resulting string with joined subfields 'e', 'u', '3', and '4'.
190
+ # @note legacy version returns array of hash objects including data for display link
191
+ # @param [MARC::Record] record
192
+ # @ param [Hash] relator_map
193
+ # @return [Array<String>]
194
+ def contributor_show(record, relator_map: Mappers.relator)
195
+ indicator_2_options = ['', ' ', '0']
196
+ contributors = record.fields(%w[700 710]).filter_map do |field|
197
+ next unless indicator_2_options.member?(field.indicator2)
198
+ next if subfield_defined? field, 'i'
199
+
200
+ contributor = join_subfields(field, &subfield_in?(%w[a b c d j q]))
201
+ contributor_append_subfields = %w[e u 3 4]
202
+ contributor_append = field.filter_map { |subfield|
203
+ next unless contributor_append_subfields.member?(subfield.code)
204
+
205
+ if subfield.code == '4'
206
+ ", #{translate_relator(subfield.value, relator_map)}"
207
+ else
208
+ " #{subfield.value}"
209
+ end
210
+ }.join
211
+ "#{contributor} #{contributor_append}".squish
212
+ end
213
+ contributors + record.fields('880').filter_map do |field|
214
+ next unless subfield_value_in?(field, '6', %w[700 710])
215
+ next if subfield_defined?(field, 'i')
216
+
217
+ contributor = join_subfields(field, &subfield_in?(%w[a b c d j q]))
218
+ contributor_append = join_subfields(field, &subfield_in?(%w[e u 3]))
219
+ "#{contributor} #{contributor_append}".squish
220
+ end
221
+ end
222
+
186
223
  private
187
224
 
188
225
  # Trim punctuation method extracted from Traject macro, to ensure consistent output
@@ -209,8 +246,9 @@ module PennMARC
209
246
  # @param [MARC::Field] field
210
247
  # @return [String] joined subfield values for value from field
211
248
  def name_from_main_entry(field, mapping)
212
- s = field.filter_map do |sf|
213
- if %w[0 1 4 6 8].exclude?(sf.code)
249
+ name_subfields = %w[0 1 4 6 8]
250
+ s = field.filter_map { |sf|
251
+ if name_subfields.exclude?(sf.code)
214
252
  " #{sf.value}"
215
253
  elsif sf.code == '4'
216
254
  relator = translate_relator(sf.value, mapping)
@@ -218,8 +256,8 @@ module PennMARC
218
256
 
219
257
  ", #{relator}"
220
258
  end
221
- end.join
222
- (s + (!%w[. -].member?(s.last) ? '.' : '')).squish
259
+ }.join
260
+ (s + (%w[. -].member?(s.last) ? '' : '.')).squish
223
261
  end
224
262
 
225
263
  # Convert "Lastname, First" to "First Lastname"
@@ -21,7 +21,7 @@ module PennMARC
21
21
  def type(record)
22
22
  record.fields('944').filter_map do |field|
23
23
  # skip unless specified database format type present
24
- next unless subfield_value?(field, 'a', /#{DATABASES_FACET_VALUE}/)
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
@@ -39,7 +39,7 @@ module PennMARC
39
39
 
40
40
  record.fields('943').filter_map do |field|
41
41
  # skip unless Community of Interest code is in subfield '2'
42
- next unless subfield_value?(field, '2', /#{COI_CODE}/)
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
@@ -60,17 +60,17 @@ module PennMARC
60
60
 
61
61
  record.fields('943').filter_map do |field|
62
62
  # skip unless Community of Interest code is in subfield '2'
63
- next unless subfield_value?(field, '2', /#{COI_CODE}/)
63
+ next unless subfield_value?(field, '2', /#{COI_CODE}/o)
64
64
 
65
65
  category = field.find { |subfield| subfield.code == 'a' }
66
66
 
67
- # skip unless category is present
68
- next unless category.present?
67
+ # skip if category is blank
68
+ next if category.blank?
69
69
 
70
70
  subcategory = field.find { |subfield| subfield.code == 'b' }
71
71
 
72
- # skip unless subcategory is present
73
- next unless subcategory.present?
72
+ # skip if subcategory is blank
73
+ next if subcategory.blank?
74
74
 
75
75
  "#{category.value}--#{subcategory.value}"
76
76
  end
@@ -82,7 +82,7 @@ module PennMARC
82
82
  # @param [Marc::Record]
83
83
  # @return [TrueClass, FalseClass]
84
84
  def curated_db?(record)
85
- record.fields('944').any? { |field| subfield_value?(field, 'a', /#{DATABASES_FACET_VALUE}/) }
85
+ record.fields('944').any? { |field| subfield_value?(field, 'a', /#{DATABASES_FACET_VALUE}/o) }
86
86
  end
87
87
  end
88
88
  end
@@ -10,13 +10,13 @@ module PennMARC
10
10
  # @param [MARC::Record] record
11
11
  # @return [DateTime, nil] The publication date, or nil if date found in record is invalid
12
12
  def publication(record)
13
- record.fields('008').filter_map do |field|
13
+ record.fields('008').filter_map { |field|
14
14
  four_digit_year = sanitize_partially_known_date(field.value[7, 4], '0')
15
15
 
16
- next unless four_digit_year.present?
16
+ next if four_digit_year.blank?
17
17
 
18
18
  DateTime.new(four_digit_year.to_i)
19
- end.first
19
+ }.first
20
20
  end
21
21
 
22
22
  # Retrieve date added (subfield 'q') from enriched marc 'itm' field.
@@ -24,7 +24,7 @@ module PennMARC
24
24
  # @param [MARC::Record] record
25
25
  # @return [DateTime, nil] The date added, or nil if date found in record is invalid
26
26
  def added(record)
27
- record.fields(EnrichedMarc::TAG_ITEM).flat_map do |field|
27
+ record.fields(EnrichedMarc::TAG_ITEM).flat_map { |field|
28
28
  field.filter_map do |subfield|
29
29
  # skip unless field has date created subfield
30
30
  next unless subfield_defined?(field, EnrichedMarc::SUB_ITEM_DATE_CREATED)
@@ -42,7 +42,7 @@ module PennMARC
42
42
  puts "Error parsing date in date added subfield: #{subfield.value} - #{e}"
43
43
  nil
44
44
  end
45
- end.max
45
+ }.max
46
46
  end
47
47
 
48
48
  # Retrieve date last updated from {https://www.loc.gov/marc/bibliographic/bd005.html 005 field}.
@@ -51,19 +51,20 @@ module PennMARC
51
51
  # @param [MARC::Record] record
52
52
  # @return [DateTime, nil] The date last updated, or nil if date found in record is invalid
53
53
  def last_updated(record)
54
- record.fields('005').filter_map do |field|
55
- date_time_string = field.value
54
+ record.fields('005').filter_map { |field|
55
+ begin
56
+ date_time_string = field.value
56
57
 
57
- next if date_time_string.blank?
58
+ next if date_time_string.blank?
58
59
 
59
- next if date_time_string.start_with?('0000')
60
+ next if date_time_string.start_with?('0000')
60
61
 
61
- DateTime.iso8601(date_time_string).to_datetime
62
-
63
- rescue ArgumentError => e
64
- puts "Error parsing last updated date: #{date_time_string} - #{e}"
65
- nil
66
- end.first
62
+ DateTime.iso8601(date_time_string).to_datetime
63
+ rescue ArgumentError => e
64
+ puts "Error parsing last updated date: #{date_time_string} - #{e}"
65
+ nil
66
+ end
67
+ }.first
67
68
  end
68
69
 
69
70
  private
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- # Do Edition-y stuff
4
+ # Do Edition and edition-related field processing.
5
5
  class Edition < Helper
6
6
  class << self
7
7
  # Edition values for display on a record page. Field 250 is information relating to the edition of a work as
@@ -14,9 +14,9 @@ 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 do |field|
17
+ record.fields('250').map { |field|
18
18
  join_subfields(field, &subfield_not_in?(%w[6 8]))
19
- end + linked_alternate_not_6_or_8(record, '250')
19
+ } + linked_alternate_not_6_or_8(record, '250')
20
20
  end
21
21
 
22
22
  # Edition values for display in search results. Just grab the first 250 field.
@@ -24,7 +24,7 @@ module PennMARC
24
24
  # @return [String, NilClass] string of all first 250 subfields, excluding 6 and 8
25
25
  def values(record)
26
26
  edition = record.fields('250').first
27
- return unless edition.present?
27
+ return if edition.blank?
28
28
 
29
29
  join_subfields(edition, &subfield_not_in?(%w[6 8]))
30
30
  end
@@ -34,17 +34,19 @@ module PennMARC
34
34
  # display.
35
35
  # https://www.loc.gov/marc/bibliographic/bd775.html
36
36
  # @param [MARC::Record] record
37
+ # @param [Hash] relator_map
37
38
  # @return [Array<String>] array of other edition strings
38
- def other_show(record, relator_mapping)
39
- record.fields('775').filter_map do |field|
39
+ def other_show(record, relator_map: Mappers.relator)
40
+ values = record.fields('775').filter_map do |field|
40
41
  next unless subfield_defined?(field, :i)
41
42
 
42
- other_edition_value(field, relator_mapping)
43
- end + record.fields('880').filter_map do |field|
43
+ other_edition_value(field, relator_map)
44
+ end
45
+ values + record.fields('880').filter_map do |field|
44
46
  next unless field.indicator2.blank? && subfield_value_in?(field, '6', %w[775]) &&
45
47
  subfield_defined?(field, 'i')
46
48
 
47
- other_edition_value(field, relator_mapping)
49
+ other_edition_value(field, relator_map)
48
50
  end
49
51
  end
50
52
 
@@ -52,31 +54,34 @@ module PennMARC
52
54
 
53
55
  # Assemble a string of relevant edition information.
54
56
  # @param [MARC::DataField] field
55
- # @param [Hash] relator_mapping
57
+ # @param [Hash] relator_map
56
58
  # @return [String (frozen)] assembled other version string
57
- def other_edition_value(field, relator_mapping)
59
+ def other_edition_value(field, relator_map)
58
60
  subi = remove_paren_value_from_subfield_i(field) || ''
59
- other_editions = field.filter_map do |sf|
60
- next if %w[6 8].member?(sf.code)
61
+ excluded_subfields = %w[6 8]
62
+ other_edition_subfields = %w[s x z]
63
+ other_editions = field.filter_map { |sf|
64
+ next if excluded_subfields.member?(sf.code)
61
65
 
62
- if %w[s x z].member?(sf.code)
66
+ if other_edition_subfields.member?(sf.code)
63
67
  " #{sf.value}"
64
68
  elsif sf.code == 't'
65
- relator = translate_relator(sf.value, relator_mapping)
69
+ relator = translate_relator(sf.value, relator_map)
66
70
  next if relator.blank?
67
71
 
68
72
  " #{relator}. "
69
73
  end
70
- end.join
71
- other_editions_append = field.filter_map do |sf|
72
- next if %w[6 8].member?(sf.code)
74
+ }.join
75
+ other_editions_append_subfields = %w[i h s t x z e f o r w y 7]
76
+ other_editions_append = field.filter_map { |sf|
77
+ next if excluded_subfields.member?(sf.code)
73
78
 
74
- if %w[i h s t x z e f o r w y 7].exclude?(sf.code)
79
+ if other_editions_append_subfields.exclude?(sf.code)
75
80
  " #{sf.value}"
76
81
  elsif sf.code == 'h'
77
82
  " (#{sf.value}) "
78
83
  end
79
- end.join
84
+ }.join
80
85
  prepend = trim_trailing(:period, subi).squish
81
86
 
82
87
  if other_editions.present? || other_editions_append.present?
@@ -71,7 +71,7 @@ module PennMARC
71
71
  # @param [Hash] location_map
72
72
  # @return [Array<String>] format values for faceting
73
73
 
74
- def facet(record, location_map)
74
+ def facet(record, location_map: Mappers.location)
75
75
  formats = []
76
76
  format_code = leader_format(record.leader)
77
77
  f007 = record.fields('007').map(&:value)
@@ -88,7 +88,8 @@ module PennMARC
88
88
  end
89
89
 
90
90
  # get all specific_location values from inventory info
91
- locations = Location.location record: record, location_map: location_map, display_value: :specific_location
91
+ locations = Location.location record: record, location_map: location_map,
92
+ display_value: :specific_location
92
93
 
93
94
  if include_manuscripts?(locations)
94
95
  formats << MANUSCRIPT
@@ -147,6 +148,16 @@ module PennMARC
147
148
  end
148
149
  end
149
150
 
151
+ # Retrieve cartographic reference data for map/atlas formats for display from
152
+ # {https://www.oclc.org/bibformats/en/2xx/255.html 255} and {https://www.oclc.org/bibformats/en/3xx/342.html 342}
153
+ # @param [MARC::Record] record
154
+ # @return [Array<String>]
155
+ def cartographic_show(record)
156
+ record.fields(%w[255 342]).map do |field|
157
+ join_subfields(field, &subfield_not_in?(%w[6 8]))
158
+ end
159
+ end
160
+
150
161
  # Check if a set of locations has any locations that include the term 'manuscripts'
151
162
  # @param [Array<String>] locations
152
163
  # @return [Boolean]
@@ -162,12 +173,12 @@ module PennMARC
162
173
  # @param [MARC::Record] record
163
174
  # @return [Array]
164
175
  def curated_format(record)
165
- record.fields('944').filter_map do |field|
176
+ record.fields('944').filter_map { |field|
166
177
  subfield_a = field.find { |sf| sf.code == 'a' }
167
178
  next if subfield_a.nil? || (subfield_a.value == subfield_a.value.to_i.to_s)
168
179
 
169
180
  subfield_a.value
170
- end.uniq
181
+ }.uniq
171
182
  end
172
183
 
173
184
  # @param [String] format_code