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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +143 -0
- data/Gemfile +1 -1
- data/README.md +12 -2
- data/lib/pennmarc/helpers/creator.rb +59 -21
- data/lib/pennmarc/helpers/database.rb +8 -8
- data/lib/pennmarc/helpers/date.rb +16 -15
- data/lib/pennmarc/helpers/edition.rb +25 -20
- data/lib/pennmarc/helpers/format.rb +15 -4
- data/lib/pennmarc/helpers/genre.rb +13 -11
- data/lib/pennmarc/helpers/helper.rb +1 -0
- data/lib/pennmarc/helpers/identifier.rb +16 -7
- data/lib/pennmarc/helpers/language.rb +3 -3
- data/lib/pennmarc/helpers/link.rb +6 -0
- data/lib/pennmarc/helpers/location.rb +8 -8
- data/lib/pennmarc/helpers/note.rb +52 -2
- data/lib/pennmarc/helpers/relation.rb +4 -4
- data/lib/pennmarc/helpers/series.rb +171 -85
- data/lib/pennmarc/helpers/subject.rb +16 -17
- data/lib/pennmarc/helpers/title.rb +1 -1
- data/lib/pennmarc/mappers.rb +31 -0
- data/lib/pennmarc/parser.rb +34 -157
- data/lib/pennmarc/util.rb +15 -16
- data/pennmarc.gemspec +2 -2
- data/spec/lib/pennmarc/helpers/citation_spec.rb +1 -2
- data/spec/lib/pennmarc/helpers/creator_spec.rb +54 -19
- data/spec/lib/pennmarc/helpers/date_spec.rb +5 -5
- data/spec/lib/pennmarc/helpers/edition_spec.rb +4 -6
- data/spec/lib/pennmarc/helpers/format_spec.rb +30 -10
- data/spec/lib/pennmarc/helpers/genre_spec.rb +4 -4
- data/spec/lib/pennmarc/helpers/identifer_spec.rb +15 -0
- data/spec/lib/pennmarc/helpers/language_spec.rb +1 -1
- data/spec/lib/pennmarc/helpers/location_spec.rb +2 -1
- data/spec/lib/pennmarc/helpers/note_spec.rb +67 -2
- data/spec/lib/pennmarc/helpers/relation_spec.rb +2 -2
- data/spec/lib/pennmarc/helpers/series_spec.rb +54 -0
- data/spec/lib/pennmarc/helpers/subject_spec.rb +9 -9
- data/spec/lib/pennmarc/helpers/title_spec.rb +3 -1
- data/spec/lib/pennmarc/marc_util_spec.rb +9 -8
- data/spec/lib/pennmarc/parser_spec.rb +24 -3
- data/spec/spec_helper.rb +1 -1
- metadata +8 -20
- data/legacy/indexer.rb +0 -568
- data/legacy/marc.rb +0 -2964
- 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
|
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} #{
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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?
|
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
|
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
|
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
|
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
|
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
|
data/lib/pennmarc/parser.rb
CHANGED
@@ -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
|
-
|
23
|
-
|
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
|
-
|
28
|
-
|
29
|
-
#
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
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
|
-
# @
|
56
|
-
def
|
57
|
-
|
58
|
-
|
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
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
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
|
-
#
|
79
|
-
# @
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
13
|
+
return '' unless field
|
14
|
+
|
15
|
+
field.select(&selector).filter_map { |sf|
|
14
16
|
value = sf.value&.strip
|
15
|
-
next
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
155
|
+
record.fields(tag).filter_map { |field|
|
156
156
|
join_subfields(field, &subfield_not_in?(%w[6 8]))
|
157
|
-
|
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
|
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
|
-
|
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
|
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 = '
|
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.
|
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
|
-
|