pennmarc 1.0.31 → 1.0.32
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/lib/pennmarc/helpers/access.rb +4 -4
- data/lib/pennmarc/helpers/citation.rb +2 -2
- data/lib/pennmarc/helpers/classification.rb +10 -7
- data/lib/pennmarc/helpers/creator.rb +10 -10
- data/lib/pennmarc/helpers/database.rb +8 -8
- data/lib/pennmarc/helpers/date.rb +5 -5
- data/lib/pennmarc/helpers/edition.rb +7 -7
- data/lib/pennmarc/helpers/format.rb +36 -40
- data/lib/pennmarc/helpers/genre.rb +5 -5
- data/lib/pennmarc/helpers/identifier.rb +18 -18
- data/lib/pennmarc/helpers/inventory.rb +7 -7
- data/lib/pennmarc/helpers/inventory_entry/base.rb +2 -2
- data/lib/pennmarc/helpers/language.rb +4 -4
- data/lib/pennmarc/helpers/link.rb +6 -6
- data/lib/pennmarc/helpers/location.rb +14 -14
- data/lib/pennmarc/helpers/note.rb +2 -2
- data/lib/pennmarc/helpers/production.rb +7 -6
- data/lib/pennmarc/helpers/relation.rb +14 -14
- data/lib/pennmarc/helpers/series.rb +19 -19
- data/lib/pennmarc/helpers/subject.rb +28 -28
- data/lib/pennmarc/helpers/title.rb +18 -18
- data/lib/pennmarc/parser.rb +5 -5
- data/lib/pennmarc/test/marc_helpers.rb +11 -11
- data/lib/pennmarc/util.rb +18 -18
- data/lib/pennmarc/version.rb +1 -1
- data/spec/lib/pennmarc/marc_util_spec.rb +12 -0
- data/spec/support/fixture_helpers.rb +1 -1
- metadata +2 -2
@@ -30,8 +30,8 @@ module PennMARC
|
|
30
30
|
# 69X, including any linked 880 fields. Fields must have an indicator2 value in {VALID_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
|
-
# @param [Hash]
|
34
|
-
# @param [MARC::Record]
|
33
|
+
# @param relator_map [Hash]
|
34
|
+
# @param record [MARC::Record]
|
35
35
|
# @return [Array<String>] array of all subject values for search
|
36
36
|
def search(record, relator_map: Mappers.relator)
|
37
37
|
subject_fields(record, type: :search).filter_map { |field|
|
@@ -61,8 +61,8 @@ module PennMARC
|
|
61
61
|
# All Subjects for faceting
|
62
62
|
#
|
63
63
|
# @note this is ported mostly form MG's new-style Subject parsing
|
64
|
-
# @param [MARC::Record]
|
65
|
-
# @param [Boolean]
|
64
|
+
# @param record [MARC::Record]
|
65
|
+
# @param override [Boolean] remove undesirable terms or not
|
66
66
|
# @return [Array<String>] array of all subject values for faceting
|
67
67
|
def facet(record, override: true)
|
68
68
|
values = subject_fields(record, type: :facet).filter_map { |field|
|
@@ -77,8 +77,8 @@ module PennMARC
|
|
77
77
|
# All Subjects for display. This includes all {DISPLAY_TAGS} and {LOCAL_TAGS}. For tags that specify a source,
|
78
78
|
# only those with an allowed source code (see ALLOWED_SOURCE_CODES) are included.
|
79
79
|
#
|
80
|
-
# @param [MARC::Record]
|
81
|
-
# @param [Boolean]
|
80
|
+
# @param record [MARC::Record]
|
81
|
+
# @param override [Boolean] to remove undesirable terms or not
|
82
82
|
# @return [Array] array of all subject values for display
|
83
83
|
def show(record, override: true)
|
84
84
|
values = subject_fields(record, type: :all).filter_map { |field|
|
@@ -92,8 +92,8 @@ module PennMARC
|
|
92
92
|
|
93
93
|
# Get Subjects from "Children" ontology
|
94
94
|
#
|
95
|
-
# @param [MARC::Record]
|
96
|
-
# @param [Boolean]
|
95
|
+
# @param record [MARC::Record]
|
96
|
+
# @param override [Boolean] remove undesirable terms or not
|
97
97
|
# @return [Array] array of children's subject values for display
|
98
98
|
def childrens_show(record, override: true)
|
99
99
|
values = subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '1' })
|
@@ -108,8 +108,8 @@ module PennMARC
|
|
108
108
|
|
109
109
|
# Get Subjects from "MeSH" ontology
|
110
110
|
#
|
111
|
-
# @param [MARC::Record]
|
112
|
-
# @param [Boolean]
|
111
|
+
# @param record [MARC::Record]
|
112
|
+
# @param override [Boolean] remove undesirable terms or not
|
113
113
|
# @return [Array] array of MeSH subject values for display
|
114
114
|
def medical_show(record, override: true)
|
115
115
|
values = subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '2' })
|
@@ -125,8 +125,8 @@ module PennMARC
|
|
125
125
|
# Get Subject values from {DISPLAY_TAGS} where indicator2 is 4 and {LOCAL_TAGS}. Do not include any values where
|
126
126
|
# sf2 includes "penncoi" (Community of Interest).
|
127
127
|
#
|
128
|
-
# @param [MARC::Record]
|
129
|
-
# @param [Boolean]
|
128
|
+
# @param record [MARC::Record]
|
129
|
+
# @param override [Boolean] to remove undesirable terms
|
130
130
|
# @return [Array] array of local subject values for display
|
131
131
|
def local_show(record, override: true)
|
132
132
|
local_fields = subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '4' }) +
|
@@ -149,9 +149,9 @@ module PennMARC
|
|
149
149
|
# - facet
|
150
150
|
# - display
|
151
151
|
# - local
|
152
|
-
# @param [MARC::Record]
|
153
|
-
# @param [String, Symbol] type of fields desired
|
154
|
-
# @param [Hash] options to be passed to the selector method
|
152
|
+
# @param record [MARC::Record]
|
153
|
+
# @param type [String, Symbol] type of fields desired
|
154
|
+
# @param options [Hash] options to be passed to the selector method
|
155
155
|
# @return [Array<MARC::DataField>] selected fields
|
156
156
|
def subject_fields(record, type:, options: {})
|
157
157
|
selector_method = case type.to_sym
|
@@ -171,8 +171,8 @@ module PennMARC
|
|
171
171
|
# Format a term hash as a string for display
|
172
172
|
#
|
173
173
|
# @todo support search field formatting?
|
174
|
-
# @param [Symbol]
|
175
|
-
# @param [Hash]
|
174
|
+
# @param type [Symbol]
|
175
|
+
# @param term [Hash] components and information as a hash
|
176
176
|
# @return [String]
|
177
177
|
def format_term(type:, term:)
|
178
178
|
return unless type.in? %i[facet display]
|
@@ -194,7 +194,7 @@ module PennMARC
|
|
194
194
|
# indicator 2 is '7' - indicating "source specified", the specified source must be in our approved source code
|
195
195
|
# list.
|
196
196
|
# @see Util.valid_subject_genre_source_code?
|
197
|
-
# @param [MARC::DataField]
|
197
|
+
# @param field [MARC::DataField]
|
198
198
|
# @return [Boolean] whether a MARC field is intended for display under general "Subjects"
|
199
199
|
def subject_general_display_field?(field)
|
200
200
|
return false unless field.tag.in?(DISPLAY_TAGS + LOCAL_TAGS) && field.respond_to?(:indicator2)
|
@@ -206,14 +206,14 @@ module PennMARC
|
|
206
206
|
true
|
207
207
|
end
|
208
208
|
|
209
|
-
# @param [MARC::DataField]
|
209
|
+
# @param field [MARC::DataField]
|
210
210
|
# @return [Boolean] whether a MARC field is a local subject field (69X)
|
211
211
|
def subject_local_field?(field)
|
212
212
|
field.tag.in? LOCAL_TAGS
|
213
213
|
end
|
214
214
|
|
215
|
-
# @param [MARC::DataField]
|
216
|
-
# @param [Hash]
|
215
|
+
# @param field [MARC::DataField]
|
216
|
+
# @param options [Hash] include :tags and :indicator2 values
|
217
217
|
# @return [Boolean] whether a MARC field should be considered for display
|
218
218
|
def subject_display_field?(field, options)
|
219
219
|
return false unless field.respond_to?(:indicator2)
|
@@ -223,7 +223,7 @@ module PennMARC
|
|
223
223
|
false
|
224
224
|
end
|
225
225
|
|
226
|
-
# @param [MARC::DataField]
|
226
|
+
# @param field [MARC::DataField]
|
227
227
|
# @return [Boolean]
|
228
228
|
def subject_facet_field?(field)
|
229
229
|
return false unless field.respond_to?(:indicator2)
|
@@ -241,7 +241,7 @@ module PennMARC
|
|
241
241
|
# because we're using (where? - MK) "subdivision count" as a heuristic for the quality level of the
|
242
242
|
# heading. - MG
|
243
243
|
# @todo do i need all this?
|
244
|
-
# @param [MARC::DataField]
|
244
|
+
# @param field [MARC::DataField]
|
245
245
|
# @return [Hash{Symbol => Integer, Array, Boolean}, Nil]
|
246
246
|
def build_subject_hash(field)
|
247
247
|
term_info = { count: 0, parts: [], append: [], uri: nil,
|
@@ -291,7 +291,7 @@ module PennMARC
|
|
291
291
|
|
292
292
|
# Determine if a field should be considered for Subject search inclusion. It must be either contained in
|
293
293
|
# {SEARCH_TAGS}, be an 880 field otherwise linked to a valid Search tag, or be in {LOCAL_TAGS}.
|
294
|
-
# @param [MARC::DataField]
|
294
|
+
# @param field [MARC::DataField]
|
295
295
|
# @return [Boolean]
|
296
296
|
def subject_search_field?(field)
|
297
297
|
return false unless field.respond_to?(:indicator2) && VALID_SOURCE_INDICATORS.include?(field.indicator2)
|
@@ -305,7 +305,7 @@ module PennMARC
|
|
305
305
|
end
|
306
306
|
|
307
307
|
# Is a given tag a subject search field? Yes if it is contained in {SEARCH_TAGS} or starts with 69.
|
308
|
-
# @param [String,
|
308
|
+
# @param tag [String, nil]
|
309
309
|
# @return [Boolean]
|
310
310
|
def subject_search_tag?(tag)
|
311
311
|
return false if tag.blank?
|
@@ -317,7 +317,7 @@ module PennMARC
|
|
317
317
|
# when we've only encountered one subfield, assume that it might be a poorly-coded record
|
318
318
|
# with a bunch of subdivisions mashed together, and attempt to convert it to a consistent
|
319
319
|
# form.
|
320
|
-
# @param [String]
|
320
|
+
# @param first_part [String]
|
321
321
|
# @return [String, nil] normalized string
|
322
322
|
def normalize_single_subfield(first_part)
|
323
323
|
first_part.gsub!(/([[[:alnum:]])])(\s+--\s*|\s*--\s+)([[[:upper:]][[:digit:]]])/, '\1--\3')
|
@@ -326,8 +326,8 @@ module PennMARC
|
|
326
326
|
end
|
327
327
|
|
328
328
|
# removes trailing comma or period, manipulating the string in place
|
329
|
-
# @param [String,
|
330
|
-
# @return [String,
|
329
|
+
# @param subject_part [String, nil]
|
330
|
+
# @return [String, nil]
|
331
331
|
def trim_trailing_commas_or_periods!(subject_part)
|
332
332
|
return if subject_part.blank?
|
333
333
|
|
@@ -35,7 +35,7 @@ module PennMARC
|
|
35
35
|
class << self
|
36
36
|
# Main Title Search field. Takes from {https://www.loc.gov/marc/bibliographic/bd245.html 245} and linked 880.
|
37
37
|
# @note Ported from get_title_1_search_values.
|
38
|
-
# @param [MARC::Record]
|
38
|
+
# @param record [MARC::Record]
|
39
39
|
# @return [Array<String>] array of title values for search
|
40
40
|
def search(record)
|
41
41
|
record.fields(%w[245 880]).filter_map { |field|
|
@@ -47,7 +47,7 @@ module PennMARC
|
|
47
47
|
|
48
48
|
# Auxiliary Title Search field. Takes from many fields defined in {AUX_TITLE_TAGS} that contain title-like
|
49
49
|
# information.
|
50
|
-
# @param [MARC::Record]
|
50
|
+
# @param record [MARC::Record]
|
51
51
|
# @return [Array<String>] array of auxiliary title values for search
|
52
52
|
def search_aux(record)
|
53
53
|
values = search_aux_values(record: record, title_type: :main, &subfield_not_in?(%w[c 6 8])) +
|
@@ -60,7 +60,7 @@ module PennMARC
|
|
60
60
|
# Journal Title Search field. Takes from {https://www.loc.gov/marc/bibliographic/bd245.html 245} and linked 880.
|
61
61
|
# We do not return any values if the {https://www.loc.gov/marc/bibliographic/bdleader.html MARC leader}
|
62
62
|
# indicates that the record is not a serial.
|
63
|
-
# @param [MARC::Record]
|
63
|
+
# @param record [MARC::Record]
|
64
64
|
# @return [Array<String>] journal title information for search
|
65
65
|
def journal_search(record)
|
66
66
|
return [] if not_a_serial?(record)
|
@@ -75,7 +75,7 @@ module PennMARC
|
|
75
75
|
# Auxiliary Journal Title Search field. Takes from many fields defined in {AUX_TITLE_TAGS} that contain title-like
|
76
76
|
# information. Does not return any titles if the {https://www.loc.gov/marc/bibliographic/bdleader.html MARC leader}
|
77
77
|
# indicates that the record is not a serial.
|
78
|
-
# @param [MARC::Record]
|
78
|
+
# @param record [MARC::Record]
|
79
79
|
# @return [Array<String>] auxiliary journal title information for search
|
80
80
|
def journal_search_aux(record)
|
81
81
|
values = search_aux_values(record: record, title_type: :main, journal: true, &subfield_not_in?(%w[c 6 8])) +
|
@@ -90,7 +90,7 @@ module PennMARC
|
|
90
90
|
# {https://www.oclc.org/bibformats/en/2xx/245.html#punctuation punctuation practices}.
|
91
91
|
# @todo still consider ǂh? medium, which OCLC doc says DO NOT USE...but that is OCLC...
|
92
92
|
# @todo is punctuation handling still as desired? treatment here is described in spreadsheet from 2011
|
93
|
-
# @param [MARC::Record]
|
93
|
+
# @param record [MARC::Record]
|
94
94
|
# @return [String] single title for display
|
95
95
|
def show(record)
|
96
96
|
field = record.fields('245').first
|
@@ -117,7 +117,7 @@ module PennMARC
|
|
117
117
|
# title_sort_tl (text left justified). It is not yet clear why this distinction is useful. For now, use a
|
118
118
|
# properly normalized (leading articles and punctuation removed) single title value here.
|
119
119
|
# @todo refactor to reduce complexity
|
120
|
-
# @param [MARC::Record]
|
120
|
+
# @param record [MARC::Record]
|
121
121
|
# @return [String] title value for sorting
|
122
122
|
def sort(record)
|
123
123
|
title_field = record.fields('245').first
|
@@ -152,7 +152,7 @@ module PennMARC
|
|
152
152
|
|
153
153
|
# @note this is simplified from legacy practice as a linking hash is not returned. I believe this only supported
|
154
154
|
# title browse and we will not be supporting that at this time
|
155
|
-
# @param [MARC::Record]
|
155
|
+
# @param record [MARC::Record]
|
156
156
|
# @return [Array<String>] Array of standardized titles as strings
|
157
157
|
def standardized_show(record)
|
158
158
|
standardized_titles = record.fields(%w[130 240]).map do |field|
|
@@ -181,7 +181,7 @@ module PennMARC
|
|
181
181
|
# Data comes from 246 ({https://www.oclc.org/bibformats/en/2xx/246.htm OCLC docs}) and 740
|
182
182
|
# ({https://www.oclc.org/bibformats/en/7xx/740.html OCLC docs)}
|
183
183
|
#
|
184
|
-
# @param [MARC::Record]
|
184
|
+
# @param record [MARC::Record]
|
185
185
|
# @return [Array<String>] Array of other titles as strings
|
186
186
|
def other_show(record)
|
187
187
|
other_titles = record.fields('246').map do |field|
|
@@ -207,7 +207,7 @@ module PennMARC
|
|
207
207
|
# @note Ported from get_former_title_display. That method returns a hash for constructing a search link.
|
208
208
|
# We may need to do something like that eventually.
|
209
209
|
# @todo what are e and w subfields?
|
210
|
-
# @param [MARC::Record]
|
210
|
+
# @param record [MARC::Record]
|
211
211
|
# @return [Array<String>] array of former titles
|
212
212
|
def former_show(record)
|
213
213
|
record.fields
|
@@ -221,7 +221,7 @@ module PennMARC
|
|
221
221
|
end
|
222
222
|
|
223
223
|
# Determine if the record is a "Host" bibliographic record for other bib records ("bound-withs")
|
224
|
-
# @param [MARC::Record]
|
224
|
+
# @param record [MARC::Record]
|
225
225
|
# @return [Boolean]
|
226
226
|
def host_bib_record?(record)
|
227
227
|
record.fields('245').any? do |f|
|
@@ -235,7 +235,7 @@ module PennMARC
|
|
235
235
|
# Create prefix/filing hash for representing a title value with filing characters removed, with special
|
236
236
|
# consideration for bracketed titles
|
237
237
|
# @todo Is this still useful?
|
238
|
-
# @param [String]
|
238
|
+
# @param title [String]
|
239
239
|
# @return [Hash]
|
240
240
|
def handle_bracket_prefix(title)
|
241
241
|
if title.starts_with? '['
|
@@ -246,14 +246,14 @@ module PennMARC
|
|
246
246
|
end
|
247
247
|
|
248
248
|
# Evaluate {https://www.loc.gov/marc/bibliographic/bdleader.html MARC leader} to determine if record is a serial.
|
249
|
-
# @param [MARC::Record]
|
249
|
+
# @param record [MARC::Record]
|
250
250
|
# @return [Boolean]
|
251
251
|
def not_a_serial?(record)
|
252
252
|
!record.leader[6..7].ends_with?('s')
|
253
253
|
end
|
254
254
|
|
255
|
-
# @param [MARC::DataField]
|
256
|
-
# @param [String]
|
255
|
+
# @param field [MARC::DataField]
|
256
|
+
# @param value [String]
|
257
257
|
# @return [Boolean]
|
258
258
|
def indicators_are_not_value?(field, value)
|
259
259
|
field.indicator1 != value && field.indicator2 != value
|
@@ -263,10 +263,10 @@ module PennMARC
|
|
263
263
|
# {https://www.loc.gov/marc/bibliographic/bdleader.html MARC leader} indicates that the record is not a serial.
|
264
264
|
# We take special consideration for the {https://www.loc.gov/marc/bibliographic/bd505.html 505 field}, extracting
|
265
265
|
# values only when indicator1 and indicator2 are both '0'.
|
266
|
-
# @param [MARC::Record]
|
267
|
-
# @param [Symbol]
|
268
|
-
# @param [Boolean]
|
269
|
-
# @
|
266
|
+
# @param record [MARC::Record]
|
267
|
+
# @param title_type [Symbol]
|
268
|
+
# @param journal [Boolean]
|
269
|
+
# @param join_selector [Proc]
|
270
270
|
# @return [Array<String>]
|
271
271
|
def search_aux_values(record:, title_type:, journal: false, &join_selector)
|
272
272
|
return [] if journal && not_a_serial?(record)
|
data/lib/pennmarc/parser.rb
CHANGED
@@ -12,7 +12,7 @@ module PennMARC
|
|
12
12
|
# Access point for magic calls to helper methods
|
13
13
|
class Parser
|
14
14
|
# Allow calls to `respond_to?` on parser instances to respond accurately by checking helper classes
|
15
|
-
# @param [String, Symbol]
|
15
|
+
# @param name [String, Symbol]
|
16
16
|
# @return [Boolean]
|
17
17
|
def respond_to_missing?(name, include_private = false)
|
18
18
|
helper, method_name = parse_call(name)
|
@@ -26,9 +26,9 @@ module PennMARC
|
|
26
26
|
# Call helper class methods, passing along additional arguments as needed, e.g.:
|
27
27
|
# #title_show -> PennMARC::Title.show
|
28
28
|
# #subject_facet -> PennMARC::Subject.facet
|
29
|
-
# @param [Symbol]
|
30
|
-
# @param [MARC::Record]
|
31
|
-
# @param [Array]
|
29
|
+
# @param name [Symbol]
|
30
|
+
# @param record [MARC::Record]
|
31
|
+
# @param opts [Array]
|
32
32
|
def method_missing(name, record, *opts)
|
33
33
|
helper, method_name = parse_call(name)
|
34
34
|
raise NoMethodError unless helper && method_name
|
@@ -44,7 +44,7 @@ module PennMARC
|
|
44
44
|
private
|
45
45
|
|
46
46
|
# Parse out a method call name in the way method_missing is configured to handle
|
47
|
-
# @param [String, Symbol]
|
47
|
+
# @param name [String, Symbol]
|
48
48
|
# @return [Array]
|
49
49
|
def parse_call(name)
|
50
50
|
call = name.to_s.split('_')
|
@@ -8,23 +8,23 @@ module PennMARC
|
|
8
8
|
# Helper methods for use in constructing MARC objects for testing
|
9
9
|
module MarcHelpers
|
10
10
|
# Return a MARC::XMLReader that will parse a given file and return MARC::Record objects
|
11
|
-
# @param [String] filename of MARCXML fixture
|
11
|
+
# @param filename [String] filename of MARCXML fixture
|
12
12
|
# @return [MARC::Record, NilClass]
|
13
13
|
def record_from(filename)
|
14
14
|
MARC::XMLReader.new(marc_xml_path(filename)).first
|
15
15
|
end
|
16
16
|
|
17
17
|
# Create an isolated MARC::Subfield object for use in specs or as part of a MARC::Field
|
18
|
-
# @param [String]
|
19
|
-
# @param [String]
|
18
|
+
# @param code [String]
|
19
|
+
# @param value [String]
|
20
20
|
# @return [MARC::Subfield]
|
21
21
|
def marc_subfield(code, value)
|
22
22
|
MARC::Subfield.new code.to_s, value
|
23
23
|
end
|
24
24
|
|
25
25
|
# Return a new ControlField (000-009)
|
26
|
-
# @param [String]
|
27
|
-
# @param [String]
|
26
|
+
# @param tag [String]
|
27
|
+
# @param value [String]
|
28
28
|
# @return [MARC::ControlField]
|
29
29
|
def marc_control_field(tag:, value:)
|
30
30
|
MARC::ControlField.new tag, value
|
@@ -38,10 +38,10 @@ module PennMARC
|
|
38
38
|
# z: 'United States.',
|
39
39
|
# '0': http://id.loc.gov/authorities/subjects/sh2008112546 }
|
40
40
|
# )
|
41
|
-
# @param [String (frozen)]
|
42
|
-
# @param [String (frozen)]
|
43
|
-
# @param [String (frozen)]
|
44
|
-
# @param [Hash]
|
41
|
+
# @param tag [String (frozen)] MARC tag, e.g., 001, 665
|
42
|
+
# @param indicator1 [String (frozen)] MARC indicator 1, e.g., 0
|
43
|
+
# @param indicator2 [String (frozen)]
|
44
|
+
# @param subfields [Hash] hash of subfield values as code => value or code => [value, value]
|
45
45
|
# @return [MARC::DataField]
|
46
46
|
def marc_field(tag: 'TST', indicator1: ' ', indicator2: ' ', subfields: {})
|
47
47
|
subfield_objects = subfields.each_with_object([]) do |(code, value), array|
|
@@ -51,8 +51,8 @@ module PennMARC
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# Return a MARC::Record containing passed in DataFields
|
54
|
-
# @param [Array<MARC::DataField>]
|
55
|
-
# @param [String, nil]
|
54
|
+
# @param fields [Array<MARC::DataField>]
|
55
|
+
# @param leader [String, nil]
|
56
56
|
# @return [MARC::Record]
|
57
57
|
def marc_record(fields: [], leader: nil)
|
58
58
|
record = MARC::Record.new
|
data/lib/pennmarc/util.rb
CHANGED
@@ -56,7 +56,7 @@ module PennMARC
|
|
56
56
|
end
|
57
57
|
|
58
58
|
# returns true if a given field has a given subfield value in a given array
|
59
|
-
# @param field [MARC
|
59
|
+
# @param field [MARC::DataField]
|
60
60
|
# @param subfield [String|Integer|Symbol]
|
61
61
|
# @param array [Array]
|
62
62
|
# @return [Boolean]
|
@@ -118,9 +118,9 @@ module PennMARC
|
|
118
118
|
end
|
119
119
|
|
120
120
|
# Get all subfield values for a provided subfield from any occurrence of a provided tag/tags
|
121
|
-
# @param tag [String
|
122
|
-
# @param subfield [String
|
123
|
-
# @param record [MARC::Record]
|
121
|
+
# @param tag [String,Array] tags to consider
|
122
|
+
# @param subfield [String,Symbol] subfield to take the values from
|
123
|
+
# @param record [MARC::Record] source
|
124
124
|
# @return [Array] array of subfield values
|
125
125
|
def subfield_values_for(tag:, subfield:, record:)
|
126
126
|
record.fields(tag).flat_map do |field|
|
@@ -155,8 +155,8 @@ module PennMARC
|
|
155
155
|
end
|
156
156
|
|
157
157
|
# trim trailing punctuation, manipulating string in place
|
158
|
-
# @param trailer [Symbol
|
159
|
-
# @param string [String] to modify
|
158
|
+
# @param trailer [Symbol,String] trailer to target for removal
|
159
|
+
# @param string [String] string to modify
|
160
160
|
# @return [String, Nil] string to modify
|
161
161
|
def trim_trailing!(trailer, string)
|
162
162
|
string.sub! TRAILING_PUNCTUATIONS_PATTERNS[trailer.to_sym], ''
|
@@ -218,17 +218,17 @@ module PennMARC
|
|
218
218
|
end
|
219
219
|
|
220
220
|
# Get the substring of a string up to a given target character
|
221
|
-
# @param string [
|
222
|
-
# @param target [
|
223
|
-
# @return [String (frozen)]
|
221
|
+
# @param string [String] string to split
|
222
|
+
# @param target [String] character to split upon
|
223
|
+
# @return [String (frozen), nil]
|
224
224
|
def substring_before(string, target)
|
225
225
|
string.scan(target).present? ? string.split(target, 2).first : ''
|
226
226
|
end
|
227
227
|
|
228
228
|
# Get the substring of a string after the first occurrence of a target character
|
229
|
-
# @param string [
|
230
|
-
# @param target [
|
231
|
-
# @return [String (frozen)]
|
229
|
+
# @param string [String] string to split
|
230
|
+
# @param target [String] character to split upon
|
231
|
+
# @return [String (frozen), nil]
|
232
232
|
def substring_after(string, target)
|
233
233
|
string.scan(target).present? ? string.split(target, 2).second : ''
|
234
234
|
end
|
@@ -262,7 +262,7 @@ module PennMARC
|
|
262
262
|
# @todo handle case of receiving a URI? E.g., http://loc.gov/relator/aut
|
263
263
|
# @param relator_code [String, NilClass]
|
264
264
|
# @param mapping [Hash]
|
265
|
-
# @return [String,
|
265
|
+
# @return [String, nil] full relator string
|
266
266
|
def translate_relator(relator_code, mapping)
|
267
267
|
return if relator_code.blank?
|
268
268
|
|
@@ -272,7 +272,7 @@ module PennMARC
|
|
272
272
|
# Get 650 & 880 for Provenance and Chronology: prefix should be 'PRO' or 'CHR' and may be preceded by a '%'
|
273
273
|
# @note 11/2018: do not display $5 in PRO or CHR subjs
|
274
274
|
# @param record [MARC::Record]
|
275
|
-
# @param prefix [String] to select from subject field
|
275
|
+
# @param prefix [String] prefix to select from subject field
|
276
276
|
# @return [Array] array of values
|
277
277
|
def prefixed_subject_and_alternate(record, prefix)
|
278
278
|
record.fields(%w[650 880]).filter_map { |field|
|
@@ -340,7 +340,7 @@ module PennMARC
|
|
340
340
|
|
341
341
|
relator = subfield_values(field, '4').filter_map { |code| translate_relator(code, relator_map) }
|
342
342
|
|
343
|
-
relator = subfield_values(field, relator_term_sf) if relator.blank?
|
343
|
+
relator = subfield_values(field, relator_term_sf).map { |term| trim_trailing(:comma, term) } if relator.blank?
|
344
344
|
|
345
345
|
relator = append_trailing(:period, relator.join(', ')) if relator.present?
|
346
346
|
|
@@ -349,9 +349,9 @@ module PennMARC
|
|
349
349
|
|
350
350
|
# Returns a relator value of the given field. Like append_relator, it prioritizes relator codes found in subfileld
|
351
351
|
# $4 and falls back to the specified relator term subfield relator_term_sf if no valid codes are found in $4
|
352
|
-
# @param [MARC::Field]
|
353
|
-
# @param [String]
|
354
|
-
# @param [Hash]
|
352
|
+
# @param field [MARC::Field] where relator values are stored
|
353
|
+
# @param relator_term_sf [String] MARC subfield that stores relator term
|
354
|
+
# @param relator_map [Hash]
|
355
355
|
# @return [String]
|
356
356
|
def relator(field:, relator_term_sf:, relator_map: Mappers.relator)
|
357
357
|
relator = subfield_values(field, '4').filter_map { |code| translate_relator(code, relator_map) }
|
data/lib/pennmarc/version.rb
CHANGED
@@ -323,6 +323,18 @@ describe 'PennMARC::Util' do
|
|
323
323
|
end
|
324
324
|
end
|
325
325
|
|
326
|
+
context 'when relator term has trailing comma' do
|
327
|
+
let(:field) do
|
328
|
+
marc_field(tag: '100', subfields: {
|
329
|
+
a: 'Capus, Alex,', e: ['author,', 'illustrator,', 'translator']
|
330
|
+
})
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'punctuates the value as expected' do
|
334
|
+
expect(result).to eq 'Capus, Alex, author, illustrator, translator.'
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
326
338
|
context 'when joined subfield values ends with an open date' do
|
327
339
|
let(:joined_subfields) { [field.subfields.first.value, field.subfields.second.value].join(' ') }
|
328
340
|
let(:field) { marc_field(tag: '100', subfields: { a: 'Capus, Alex,', d: '1808-', '4': %w[aut ill] }) }
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module FixtureHelpers
|
4
4
|
# Get the path for a test MARC XML file
|
5
|
-
# @param [String] filename of MARCXML fixture
|
5
|
+
# @param filename [String] filename of MARCXML fixture
|
6
6
|
# @return [String] full path of MARCXML fixture
|
7
7
|
def marc_xml_path(filename)
|
8
8
|
File.join File.dirname(__FILE__), '..', 'fixtures', 'marcxml', filename
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pennmarc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.32
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Kanning
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2024-07-
|
15
|
+
date: 2024-07-30 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activesupport
|