pennmarc 0.0.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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