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
@@ -26,14 +26,14 @@ module PennMARC
26
26
  # Local subject heading tags
27
27
  LOCAL_TAGS = %w[690 691 697].freeze
28
28
 
29
- # All Subjects for searching. This includes most subfield content from any field contained in {SEARCH_TAGS} or 69X,
30
- # including any linked 880 fields. Fields must have an indicator2 value in {SEARCH_SOURCE_INDICATORS}.
29
+ # All Subjects for searching. This includes most subfield content from any field contained in {SEARCH_TAGS} or
30
+ # 69X, including any linked 880 fields. Fields must have an indicator2 value in {SEARCH_SOURCE_INDICATORS}.
31
31
  # @todo this includes subfields that may not be desired like 1 (uri) and 2 (source code) but this might be OK for
32
32
  # a search (non-display) field?
33
33
  # @param [Hash] relator_map
34
34
  # @param [MARC::Record] record
35
35
  # @return [Array] array of all subject values for search
36
- def search(record, relator_map)
36
+ def search(record, relator_map: Mappers.relator)
37
37
  subject_fields(record, type: :search).filter_map do |field|
38
38
  subj_parts = field.filter_map do |subfield|
39
39
  # TODO: use term hash here? pro/chr would be rejected...
@@ -45,10 +45,9 @@ module PennMARC
45
45
  # remove any ? at the end
46
46
  subfield.value.gsub(/^%?(PRO|CHR)/, '').gsub(/\?$/, '').strip
47
47
  when '4'
48
- # TODO: use relation mapping method from Title helper? for potential URI support?
49
48
  # sf 4 should contain a 3-letter code or URI "that specifies the relationship from the entity described
50
49
  # in the record to the entity referenced in the field"
51
- "#{subfield.value} #{relator_map[subfield.value.to_sym]}".strip
50
+ "#{subfield.value} #{translate_relator(subfield.value.to_sym, relator_map)}".strip
52
51
  else
53
52
  subfield.value
54
53
  end
@@ -79,12 +78,12 @@ module PennMARC
79
78
  # @param [MARC::Record] record
80
79
  # @return [Array] array of all subject values for display
81
80
  def show(record)
82
- subject_fields(record, type: :all).filter_map do |field|
81
+ subject_fields(record, type: :all).filter_map { |field|
83
82
  term_hash = build_subject_hash(field)
84
83
  next if term_hash.blank? || term_hash[:count]&.zero?
85
84
 
86
85
  format_term type: :display, term: term_hash
87
- end.uniq
86
+ }.uniq
88
87
  end
89
88
 
90
89
  # Get Subjects from "Children" ontology
@@ -93,12 +92,12 @@ module PennMARC
93
92
  # @return [Array] array of children's subject values for display
94
93
  def childrens_show(record)
95
94
  subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '1' })
96
- .filter_map do |field|
95
+ .filter_map { |field|
97
96
  term_hash = build_subject_hash(field)
98
97
  next if term_hash.blank? || term_hash[:count]&.zero?
99
98
 
100
99
  format_term type: :display, term: term_hash
101
- end.uniq
100
+ }.uniq
102
101
  end
103
102
 
104
103
  # Get Subjects from "MeSH" ontology
@@ -107,12 +106,12 @@ module PennMARC
107
106
  # @return [Array] array of MeSH subject values for display
108
107
  def medical_show(record)
109
108
  subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '2' })
110
- .filter_map do |field|
109
+ .filter_map { |field|
111
110
  term_hash = build_subject_hash(field)
112
111
  next if term_hash.blank? || term_hash[:count]&.zero?
113
112
 
114
113
  format_term type: :display, term: term_hash
115
- end.uniq
114
+ }.uniq
116
115
  end
117
116
 
118
117
  # Get Subject values from {DISPLAY_TAGS} where indicator2 is 4 and {LOCAL_TAGS}. Do not include any values where
@@ -123,14 +122,14 @@ module PennMARC
123
122
  def local_show(record)
124
123
  local_fields = subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '4' }) +
125
124
  subject_fields(record, type: :local)
126
- local_fields.filter_map do |field|
125
+ local_fields.filter_map { |field|
127
126
  next if subfield_value?(field, '2', /penncoi/)
128
127
 
129
128
  term_hash = build_subject_hash(field)
130
129
  next if term_hash.blank? || term_hash[:count]&.zero?
131
130
 
132
131
  format_term type: :display, term: term_hash
133
- end.uniq
132
+ }.uniq
134
133
  end
135
134
 
136
135
  private
@@ -183,7 +182,7 @@ module PennMARC
183
182
  # @param [MARC::DataField] field
184
183
  # @return [Boolean] whether a MARC field is intended for display under general "Subjects"
185
184
  def subject_general_display_field?(field)
186
- return false unless field.tag.in? DISPLAY_TAGS + LOCAL_TAGS
185
+ return false unless field.tag.in?(DISPLAY_TAGS + LOCAL_TAGS) && field.respond_to?(:indicator2)
187
186
 
188
187
  return false if field.indicator2 == '7' && !valid_subject_genre_source_code?(field)
189
188
 
@@ -200,7 +199,7 @@ module PennMARC
200
199
  # @param [Hash] options include :tags and :indicator2 values
201
200
  # @return [Boolean] whether a MARC field should be considered for display
202
201
  def subject_display_field?(field, options)
203
- return false if field.blank?
202
+ return false unless field.respond_to?(:indicator2)
204
203
 
205
204
  return true if field.tag.in?(options[:tags]) && field.indicator2.in?(options[:indicator2])
206
205
 
@@ -210,7 +209,7 @@ module PennMARC
210
209
  # @param [MARC::DataField] field
211
210
  # @return [Boolean]
212
211
  def subject_facet_field?(field)
213
- return false if field.blank?
212
+ return false unless field.respond_to?(:indicator2)
214
213
 
215
214
  return true if field.tag.in?(DISPLAY_TAGS) && field.indicator2.in?(%w[0 2 4])
216
215
 
@@ -269,7 +268,7 @@ module PennMARC
269
268
  # @param [MARC::DataField] field
270
269
  # @return [Boolean]
271
270
  def subject_search_field?(field)
272
- return false if field.blank? || SEARCH_SOURCE_INDICATORS.exclude?(field.indicator2)
271
+ return false unless field.respond_to?(:indicator2) && SEARCH_SOURCE_INDICATORS.include?(field.indicator2)
273
272
 
274
273
  tag = if field.tag == '880'
275
274
  subfield_values(field, '6').first
@@ -82,7 +82,7 @@ module PennMARC
82
82
  def sort(record)
83
83
  title_field = record.fields('245').first
84
84
  # attempt to get number of non-filing characters present, default to 0
85
- offset = if title_field.indicator2 =~ /^[0-9]$/
85
+ offset = if /^[0-9]$/.match?(title_field.indicator2)
86
86
  title_field.indicator2.to_i
87
87
  else
88
88
  0
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PennMARC
4
+ # reusable static mappers
5
+ class Mappers
6
+ class << self
7
+ # @return [Hash]
8
+ def language
9
+ @language ||= load_map('language.yml')
10
+ end
11
+
12
+ # @return [Hash]
13
+ def location
14
+ @location ||= load_map('locations.yml')
15
+ end
16
+
17
+ # @return [Hash]
18
+ def relator
19
+ @relator ||= load_map('relator.yml')
20
+ end
21
+
22
+ # @param [String] filename of mapping file in config directory, with file extension
23
+ # @return [Hash] mapping as hash
24
+ def load_map(filename)
25
+ puts { "Loading #{filename}" }
26
+ YAML.safe_load(File.read(File.join(File.expand_path(__dir__), 'mappings', filename)),
27
+ symbolize_names: true)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -2,176 +2,53 @@
2
2
 
3
3
  require 'active_support/all'
4
4
  require_relative 'helpers/helper'
5
- require_relative 'helpers/creator'
6
- require_relative 'helpers/database'
7
- require_relative 'helpers/date'
8
- require_relative 'helpers/format'
9
- require_relative 'helpers/genre'
10
- require_relative 'helpers/identifier'
11
- require_relative 'helpers/language'
12
- require_relative 'helpers/link'
13
- require_relative 'helpers/location'
14
- require_relative 'helpers/subject'
15
- require_relative 'helpers/title'
16
- require_relative 'helpers/citation'
17
- require_relative 'helpers/relation'
18
- require_relative 'helpers/production'
19
- require_relative 'helpers/edition'
20
- require_relative 'helpers/note'
21
5
 
22
- module PennMARC
23
- attr_accessor :mappings
24
-
25
- DEFINED_HELPERS = %w[Creator Database Date Format Genre Language Link Location Subject Title Relation].freeze
6
+ # Require all files in helpers directory
7
+ # TODO: this double-requires Helper, but that needs to be required before other helpers...
8
+ Dir[File.join(__dir__, 'helpers', '*.rb')].each { |file| require file }
26
9
 
27
- # Methods here should return values used in the indexer. The parsing logic should
28
- # NOT return values specific to any particular site/interface, but just general
29
- # MARC parsing logic for "title", "subject", "author", etc., as much as reasonably
30
- # possible. We'll see how it goes.
31
- #
32
- # Methods should, by default, take in a MARC::Record
10
+ # Top level gem namespace
11
+ module PennMARC
12
+ # Access point for magic calls to helper methods
33
13
  class Parser
34
- def initialize(helpers: DEFINED_HELPERS)
35
- @mappings = {}
36
- @helpers = Array.wrap(helpers) # TODO: load helpers dynamically?
37
- end
38
-
39
- def respond_to_missing?(name)
40
- name.split('_').first.in? @helpers
14
+ # Allow calls to `respond_to?` on parser instances to respond accurately by checking helper classes
15
+ # @param [String, Symbol] name
16
+ # @return [Boolean]
17
+ def respond_to_missing?(name, include_private = false)
18
+ helper, method_name = parse_call(name)
19
+ begin
20
+ "PennMARC::#{helper}".constantize.respond_to?(method_name)
21
+ rescue NameError
22
+ super # Helper is not defined, so check self
23
+ end
41
24
  end
42
25
 
43
- # Call helper class methods, e.g.,
26
+ # Call helper class methods, passing along additional arguments as needed, e.g.:
44
27
  # #title_show -> PennMARC::Title.show
45
28
  # #subject_facet -> PennMARC::Subject.facet
46
- def method_missing(name, opts)
47
- call = name.to_s.split('_')
48
- helper = call.shift
49
- meth = call.join('_')
50
- "PennMARC::#{helper.titleize}".constantize.public_send(meth, opts)
51
- end
52
-
53
- # @todo does this fit in an existing helper?
29
+ # @param [Symbol] name
54
30
  # @param [MARC::Record] record
55
- # @return [Object]
56
- def cartographic_show(record)
57
- record.fields(%w{255 342}).map do |field|
58
- join_subfields(field, &subfield_not_6_or_8)
59
- end
60
- end
31
+ # @param [Array] opts
32
+ def method_missing(name, record, *opts)
33
+ helper, method_name = parse_call(name)
34
+ raise NoMethodError unless helper && method_name
61
35
 
62
- # @todo move to Identifier helper
63
- # @param [MARC::Record] record
64
- # @return [Object]
65
- def fingerprint_show(record)
66
- record.fields('026').map do |field|
67
- join_subfields(field, &subfield_not_in(%w{2 5 6 8}))
36
+ helper_klass = "PennMARC::#{helper.titleize}".constantize
37
+ if opts.any?
38
+ helper_klass.public_send(method_name, record, **opts.first)
39
+ else
40
+ helper_klass.public_send(method_name, record)
68
41
  end
69
42
  end
70
43
 
71
- # @todo does this fit in an existing helper?
72
- # @param [MARC::Record] record
73
- # @return [Object]
74
- def arrangement_show(record)
75
- get_datafield_and_880(record, '351')
76
- end
44
+ private
77
45
 
78
- # @param [MARC::Record] record
79
- # @return [Object]
80
- def system_details_show(record)
81
- acc = []
82
- acc += record.fields('538').map do |field|
83
- get_sub3_and_other_subs(field, &subfield_in(%w{a i u}))
84
- end
85
- acc += record.fields('344').map do |field|
86
- get_sub3_and_other_subs(field, &subfield_in(%w{a b c d e f g h}))
87
- end
88
- acc += record.fields(%w{345 346}).map do |field|
89
- get_sub3_and_other_subs(field, &subfield_in(%w{a b}))
90
- end
91
- acc += record.fields('347').map do |field|
92
- get_sub3_and_other_subs(field, &subfield_in(%w{a b c d e f}))
93
- end
94
- acc += record.fields('880')
95
- .select { |f| has_subfield6_value(f, /^538/) }
96
- .map do |field|
97
- get_sub3_and_other_subs(field, &subfield_in(%w{a i u}))
98
- end
99
- acc += record.fields('880')
100
- .select { |f| has_subfield6_value(f, /^344/) }
101
- .map do |field|
102
- get_sub3_and_other_subs(field, &subfield_in(%w{a b c d e f g h}))
103
- end
104
- acc += record.fields('880')
105
- .select { |f| has_subfield6_value(f, /^(345|346)/) }
106
- .map do |field|
107
- get_sub3_and_other_subs(field, &subfield_in(%w{a b}))
108
- end
109
- acc += record.fields('880')
110
- .select { |f| has_subfield6_value(f, /^347/) }
111
- .map do |field|
112
- get_sub3_and_other_subs(field, &subfield_in(%w{a b c d e f}))
113
- end
114
- acc
115
- end
116
-
117
- # @todo the legacy code here is a hot mess for a number of reasons, what do we need this field to do?
118
- # @note port the needed parts from get_offsite_display, don't return HTML
119
- # @param [MARC::Record] record
120
- # @return [Object]
121
- def offsite_show(record); end
122
-
123
- # @todo move this to Creator helper
124
- # @param [MARC::Record] record
125
- # @return [Object]
126
- def contributor_show(record)
127
- acc = []
128
- acc += record.fields(%w{700 710})
129
- .select { |f| ['', ' ', '0'].member?(f.indicator2) }
130
- .select { |f| f.none? { |sf| sf.code == 'i' } }
131
- .map do |field|
132
- contributor = join_subfields(field, &subfield_in(%w{a b c d j q}))
133
- contributor_append = field.select(&subfield_in(%w{e u 3 4})).map do |sf|
134
- if sf.code == '4'
135
- ", #{relator_codes[sf.value]}"
136
- else
137
- " #{sf.value}"
138
- end
139
- end.join
140
- { value: contributor, value_append: contributor_append, link_type: 'author_creator_xfacet2' }
141
- end
142
- acc += record.fields('880')
143
- .select { |f| has_subfield6_value(f, /^(700|710)/) && (f.none? { |sf| sf.code == 'i' }) }
144
- .map do |field|
145
- contributor = join_subfields(field, &subfield_in(%w{a b c d j q}))
146
- contributor_append = join_subfields(field, &subfield_in(%w{e u 3}))
147
- { value: contributor, value_append: contributor_append, link_type: 'author_creator_xfacet2' }
148
- end
149
- acc
150
- end
151
-
152
- # Load language map from YAML and memoize in @mappings hash
153
- # @return [Hash]
154
- def language_map
155
- @mappings[:language] ||= load_map('language.yml')
156
- end
157
-
158
- # Load location map from YAML and memoize in @mappings hash
159
- # @return [Hash]
160
- def location_map
161
- @mappings[:location] ||= load_map('locations.yml')
162
- end
163
-
164
- # Load relator map from YAML and memoize in @mappings hash
165
- # @return [Hash]
166
- def relator_map
167
- @mappings[:relator] ||= load_map('relator.yml')
168
- end
169
-
170
- # @param [String] filename of mapping file in config directory, with file extension
171
- # @return [Hash] mapping as hash
172
- def load_map(filename)
173
- YAML.safe_load(File.read(File.join(File.expand_path(__dir__), 'mappings', filename)),
174
- symbolize_names: true)
46
+ # Parse out a method call name in the way method_missing is configured to handle
47
+ # @param [String, Symbol] name
48
+ # @return [Array]
49
+ def parse_call(name)
50
+ call = name.to_s.split('_')
51
+ [call.shift&.titleize, call.join('_').to_sym]
175
52
  end
176
53
  end
177
54
  end
data/lib/pennmarc/util.rb CHANGED
@@ -10,9 +10,11 @@ module PennMARC
10
10
  # @param [Proc] selector
11
11
  # @return [String]
12
12
  def join_subfields(field, &selector)
13
- field.select { |v| selector.call(v) }.filter_map { |sf|
13
+ return '' unless field
14
+
15
+ field.select(&selector).filter_map { |sf|
14
16
  value = sf.value&.strip
15
- next unless value.present?
17
+ next if value.blank?
16
18
 
17
19
  value
18
20
  }.join(' ').squish
@@ -26,7 +28,7 @@ module PennMARC
26
28
  # @param [Regexp] regex
27
29
  # @return [TrueClass, FalseClass]
28
30
  def subfield_value?(field, subfield, regex)
29
- field.any? { |sf| sf.code == subfield.to_s && sf.value =~ regex }
31
+ field&.any? { |sf| sf.code == subfield.to_s && sf.value =~ regex }
30
32
  end
31
33
 
32
34
  # returns true if a given field has a given subfield value in a given array
@@ -49,7 +51,6 @@ module PennMARC
49
51
  end
50
52
 
51
53
  # returns a lambda checking if passed-in subfield's code is a member of array
52
- # TODO: include lambda returning methods in their own module?
53
54
  # @param [Array] array
54
55
  # @return [Proc]
55
56
  def subfield_in?(array)
@@ -57,7 +58,6 @@ module PennMARC
57
58
  end
58
59
 
59
60
  # returns a lambda checking if passed-in subfield's code is NOT a member of array
60
- # TODO: include lambda returning methods in their own module?
61
61
  # @param [Array] array
62
62
  # @return [Proc]
63
63
  def subfield_not_in?(array)
@@ -88,7 +88,7 @@ module PennMARC
88
88
  field.filter_map do |sf|
89
89
  next unless sf.code == subfield.to_s
90
90
 
91
- next unless sf.value.present?
91
+ next if sf.value.blank?
92
92
 
93
93
  sf.value
94
94
  end
@@ -124,16 +124,15 @@ module PennMARC
124
124
  # See: https://www.loc.gov/marc/bibliographic/bd880.html
125
125
  # @param [MARC::Record] record
126
126
  # @param [String|Array] subfield6_value either a string to look for in sub6 or an array of them
127
- # @param selector [Proc] takes a subfield as argument, returns a boolean
127
+ # @param [Proc] selector takes a subfield as argument, returns a boolean
128
128
  # @return [Array] array of linked alternates
129
129
  def linked_alternate(record, subfield6_value, &selector)
130
130
  record.fields('880').filter_map do |field|
131
131
  next unless subfield_value?(field, '6', /^#{Array.wrap(subfield6_value).join('|')}/)
132
132
 
133
- field.select { |sf| selector.call(sf) }.map(&:value).join(' ')
133
+ field.select(&selector).map(&:value).join(' ')
134
134
  end
135
135
  end
136
- alias get_880 linked_alternate
137
136
 
138
137
  # Common case of wanting to extract all the subfields besides 6 or 8,
139
138
  # from 880 datafield that has a particular subfield 6 value. We exclude 6 because
@@ -142,8 +141,9 @@ module PennMARC
142
141
  # @param [String|Array] subfield6_value either a string to look for in sub6 or an array of them
143
142
  # @return [Array] array of linked alternates without 8 or 6 values
144
143
  def linked_alternate_not_6_or_8(record, subfield6_value)
144
+ excluded_subfields = %w[6 8]
145
145
  linked_alternate(record, subfield6_value) do |sf|
146
- %w[6 8].exclude?(sf.code)
146
+ excluded_subfields.exclude?(sf.code)
147
147
  end
148
148
  end
149
149
 
@@ -152,9 +152,9 @@ module PennMARC
152
152
  # @param [String] tag
153
153
  # @return [Array] acc
154
154
  def datafield_and_linked_alternate(record, tag)
155
- record.fields(tag).filter_map do |field|
155
+ record.fields(tag).filter_map { |field|
156
156
  join_subfields(field, &subfield_not_in?(%w[6 8]))
157
- end + linked_alternate_not_6_or_8(record, tag)
157
+ } + linked_alternate_not_6_or_8(record, tag)
158
158
  end
159
159
 
160
160
  # Get the substring of a string up to a given target character
@@ -179,14 +179,13 @@ module PennMARC
179
179
  def join_and_squish(array)
180
180
  array.join(' ').squish
181
181
  end
182
- alias join_and_trim_whitespace join_and_squish
183
182
 
184
183
  # If there's a subfield i, extract its value, and if there's something
185
184
  # in parentheses in that value, extract that.
186
185
  # @param [MARC::Field] field
187
186
  # @return [String] subfield i without parentheses value
188
187
  def remove_paren_value_from_subfield_i(field)
189
- val = field.filter_map do |sf|
188
+ val = field.filter_map { |sf|
190
189
  next unless sf.code == 'i'
191
190
 
192
191
  match = /\((.+?)\)/.match(sf.value)
@@ -195,7 +194,7 @@ module PennMARC
195
194
  else
196
195
  sf.value
197
196
  end
198
- end.first || ''
197
+ }.first || ''
199
198
  trim_trailing(:colon, trim_trailing(:period, val))
200
199
  end
201
200
 
@@ -205,7 +204,7 @@ module PennMARC
205
204
  # @param [Hash] mapping
206
205
  # @return [String, NilClass] full relator string
207
206
  def translate_relator(relator_code, mapping)
208
- return unless relator_code.present?
207
+ return if relator_code.blank?
209
208
 
210
209
  mapping[relator_code.to_sym]
211
210
  end
data/pennmarc.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'pennmarc'
5
- s.version = '0.0.2'
5
+ s.version = '1.0.1'
6
6
  s.summary = 'Penn Libraries Catalog MARC parsing wisdom for cross-project usage'
7
7
  s.description = 'This gem provides methods for parsing a Penn Libraries MARCXML record into string, array and date
8
8
  objects for use in discovery or preservation applications.'
@@ -19,5 +19,5 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency 'marc', '~> 1.2'
20
20
  s.add_dependency 'nokogiri', '~> 1.15'
21
21
 
22
- s.add_development_dependency 'rspec', '~> 3.12'
22
+ s.metadata['rubygems_mfa_required'] = 'true'
23
23
  end
@@ -17,11 +17,10 @@ describe 'PennMARC::Citation' do
17
17
  end
18
18
 
19
19
  describe '.cite_as_show' do
20
- let(:record) { marc_record fields: [marc_field(tag: '524', subfields: {a: 'Perkins Historical Archive, Box 2'})] }
20
+ let(:record) { marc_record fields: [marc_field(tag: '524', subfields: { a: 'Perkins Historical Archive, Box 2' })] }
21
21
 
22
22
  it 'returns expected citation values' do
23
23
  expect(helper.cite_as_show(record)).to contain_exactly('Perkins Historical Archive, Box 2')
24
24
  end
25
25
  end
26
26
  end
27
-