pennmarc 1.0.15 → 1.0.16
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 +5 -4
- data/lib/pennmarc/helpers/format.rb +4 -1
- data/lib/pennmarc/helpers/location.rb +65 -23
- data/lib/pennmarc/helpers/note.rb +8 -1
- data/lib/pennmarc/helpers/subject.rb +23 -7
- data/lib/pennmarc/mappers.rb +5 -0
- data/lib/pennmarc/mappings/location_overrides.yml +5 -0
- data/lib/pennmarc/util.rb +17 -7
- data/lib/pennmarc/version.rb +1 -1
- data/spec/lib/pennmarc/helpers/format_spec.rb +14 -0
- data/spec/lib/pennmarc/helpers/location_spec.rb +16 -0
- data/spec/lib/pennmarc/helpers/note_spec.rb +18 -0
- data/spec/lib/pennmarc/helpers/subject_spec.rb +54 -22
- data/spec/support/marc_spec_helpers.rb +5 -4
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 248327cbd8c1447d2ff8a6d857d47a12cc9c5952f3432f86ef559faa3ca4201c
|
4
|
+
data.tar.gz: a5fd079bf3e1a0bf6fcb77de70e78f0dbd75b330b7c3ddfeb70c3aa9a1b29837
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e10f30375935e9b9f4adba832b935c350a6e7f2460d4742f3951edf6d5b7c7dddc261335bf634ccc282893b2d24135fe2551b027e5d8ecfaba6886ba6fd98d88
|
7
|
+
data.tar.gz: fe87ecedca3979f909d2e2d64cfd956b3e9c3836eb2dcb3f23f60aef07c1754a1621a4ab84cdeb5be699e0c1029a58a34c70b6fa3d18069d95c83d1635ed751a
|
@@ -16,15 +16,16 @@ module PennMARC
|
|
16
16
|
# @param [MARC::Record] record
|
17
17
|
# @return [Array]
|
18
18
|
def facet(record)
|
19
|
-
|
19
|
+
values = record.filter_map do |field|
|
20
20
|
next AT_THE_LIBRARY if physical_holding_tag?(field)
|
21
21
|
next ONLINE if electronic_holding_tag?(field)
|
22
22
|
end
|
23
23
|
|
24
|
-
return
|
24
|
+
return values if values.size == 2 # return early if all values are already present
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
# only check if ONLINE isn't already there
|
27
|
+
values << ONLINE if values.exclude?(ONLINE) && finding_aid_linkage?(record)
|
28
|
+
values.uniq
|
28
29
|
end
|
29
30
|
|
30
31
|
private
|
@@ -27,7 +27,7 @@ module PennMARC
|
|
27
27
|
WEBSITE_DATABASE = 'Website/Database'
|
28
28
|
|
29
29
|
# Get any Format values from {https://www.oclc.org/bibformats/en/3xx/300.html 300},
|
30
|
-
# 254, 255, 310, 342, 352 or {https://www.oclc.org/bibformats/en/3xx/340.html 340} field. based on the source
|
30
|
+
# 254, 255, 310, 342, 352, 362 or {https://www.oclc.org/bibformats/en/3xx/340.html 340} field. based on the source
|
31
31
|
# field, different subfields are used.
|
32
32
|
# @note ported from get_format_display
|
33
33
|
# @param [MARC::Record] record
|
@@ -39,6 +39,9 @@ module PennMARC
|
|
39
39
|
end
|
40
40
|
results += record.fields('340').map { |f| join_subfields(f, &subfield_not_in?(%w[0 2 6 8])) }
|
41
41
|
results += record.fields('880').map do |f|
|
42
|
+
# skip any 880s associated with non format fields
|
43
|
+
next unless subfield_value_in?(f, '6', %w[254 255 300 310 340 342 352 362])
|
44
|
+
|
42
45
|
subfield_to_ignore = if subfield_value?(f, 6, /^300/)
|
43
46
|
%w[3 6 8]
|
44
47
|
elsif subfield_value?(f, 6, /^340/)
|
@@ -4,6 +4,7 @@ module PennMARC
|
|
4
4
|
# Methods that return Library and Location values from Alma enhanced MARC fields
|
5
5
|
class Location < Helper
|
6
6
|
ONLINE_LIBRARY = 'Online library'
|
7
|
+
WEB_LOCATION_CODE = 'web'
|
7
8
|
|
8
9
|
class << self
|
9
10
|
# Retrieves library location from enriched marc 'itm' or 'hld' fields, giving priority to the item location over
|
@@ -41,43 +42,45 @@ module PennMARC
|
|
41
42
|
# @param [Hash] location_map hash with location_code as key and location hash as value
|
42
43
|
# @return [Array<String>]
|
43
44
|
def location(record:, display_value:, location_map:)
|
44
|
-
# get enriched marc location tag and
|
45
|
-
|
45
|
+
# get enriched marc location tag and relevant subfields
|
46
|
+
enriched_location_tag_and_subfields(record) => {tag:, location_code_sf:, call_num_sf:}
|
46
47
|
|
47
48
|
locations = record.fields(tag).flat_map { |field|
|
48
49
|
field.filter_map { |subfield|
|
49
50
|
# skip unless subfield code does not match enriched marc tag subfield code
|
50
|
-
next unless subfield.code ==
|
51
|
+
next unless subfield.code == location_code_sf
|
51
52
|
|
52
|
-
|
53
|
-
# we don't facet for 'web' which is the 'Penn Library Web' location used in Voyager.
|
54
|
-
# this location should eventually go away completely with data cleanup in Alma.
|
55
|
-
next if subfield.value == 'web'
|
53
|
+
location_code = subfield.value
|
56
54
|
|
57
|
-
|
58
|
-
# sometimes "happening locations" are mistakenly used in holdings records.
|
59
|
-
# that's a data problem that should be fixed.
|
60
|
-
# here, if we encounter a code we can't map, we ignore it, for faceting purposes
|
61
|
-
next unless location_map.key?(subfield.value.to_sym)
|
55
|
+
next if location_code_to_ignore?(location_map, location_code)
|
62
56
|
|
63
|
-
|
57
|
+
override = specific_location_override(display_value: display_value, location_code: location_code,
|
58
|
+
field: field, call_num_sf: call_num_sf)
|
59
|
+
|
60
|
+
if override.present?
|
61
|
+
override
|
62
|
+
else
|
63
|
+
location_map[location_code.to_sym][display_value.to_sym]
|
64
|
+
end
|
64
65
|
}.flatten.compact_blank
|
65
66
|
}.uniq
|
66
67
|
if record.tags.intersect?([Enriched::Pub::ELEC_INVENTORY_TAG, Enriched::Api::ELEC_INVENTORY_TAG])
|
67
68
|
locations << ONLINE_LIBRARY
|
68
69
|
end
|
70
|
+
|
69
71
|
locations
|
70
72
|
end
|
71
73
|
|
72
74
|
private
|
73
75
|
|
74
|
-
# Determine enriched marc location tag
|
75
|
-
#
|
76
|
+
# Determine enriched marc location tag, location code subfield, and call number subfield,
|
77
|
+
# giving priority to using 'itm', 'AVA', or 'AVE' fields.
|
76
78
|
# @param [MARC::Record]
|
77
79
|
# @return [Hash<String, String>] containing location tag and subfield code
|
78
80
|
# - `:tag` (String): The enriched marc location tag
|
79
|
-
# - `:
|
80
|
-
|
81
|
+
# - `:location_code_sf` (String): The subfield code where location code is stored
|
82
|
+
# - `:call_num_sf` (String): The subfield code where call number is stored
|
83
|
+
def enriched_location_tag_and_subfields(record)
|
81
84
|
# in holdings records, the shelving location is always the permanent location.
|
82
85
|
# in item records, the current location takes into account
|
83
86
|
# temporary locations and permanent locations. if you update the item's perm location,
|
@@ -89,18 +92,57 @@ module PennMARC
|
|
89
92
|
# if the record has an enriched item field present, use it
|
90
93
|
if field_defined?(record, Enriched::Pub::ITEM_TAG)
|
91
94
|
tag = Enriched::Pub::ITEM_TAG
|
92
|
-
|
93
|
-
|
95
|
+
location_code_sf = Enriched::Pub::ITEM_CURRENT_LOCATION
|
96
|
+
call_num_sf = Enriched::Pub::ITEM_CALL_NUMBER
|
97
|
+
# if the record has API inventory tags, use them
|
94
98
|
elsif field_defined?(record, Enriched::Api::PHYS_INVENTORY_TAG)
|
95
99
|
tag = Enriched::Api::PHYS_INVENTORY_TAG
|
96
|
-
|
97
|
-
|
100
|
+
location_code_sf = Enriched::Api::PHYS_LOCATION_CODE
|
101
|
+
call_num_sf = Enriched::Api::PHYS_CALL_NUMBER
|
102
|
+
# otherwise use Pub holding tags
|
98
103
|
else
|
99
104
|
tag = Enriched::Pub::PHYS_INVENTORY_TAG
|
100
|
-
|
105
|
+
location_code_sf = Enriched::Pub::PHYS_LOCATION_CODE
|
106
|
+
call_num_sf = Enriched::Pub::HOLDING_CLASSIFICATION_PART
|
107
|
+
end
|
108
|
+
|
109
|
+
{ tag: tag, location_code_sf: location_code_sf, call_num_sf: call_num_sf }
|
110
|
+
end
|
111
|
+
|
112
|
+
# Determines whether to ignore a location code.
|
113
|
+
# We ignore location codes that are not keys in the location map. Sometimes "happening locations" are
|
114
|
+
# mistakenly used in holdings records. That's a data problem that should be fixed. If we encounter a code we can't
|
115
|
+
# map, we ignore it, for faceting purposes. We also ignore the location code 'web'. We don't facet for 'web'
|
116
|
+
# which is the 'Penn Library Web' location used in Voyager. This location should eventually go away completely
|
117
|
+
# with data cleanup in Alma.
|
118
|
+
# @param [location_map] location_map hash with location_code as key and location hash as value
|
119
|
+
# @param [location_code] location_code retrieved from record
|
120
|
+
# @return [Boolean]
|
121
|
+
def location_code_to_ignore?(location_map, location_code)
|
122
|
+
location_map.key?(location_code.to_sym) == false || location_code == WEB_LOCATION_CODE
|
123
|
+
end
|
124
|
+
|
125
|
+
# Retrieves a specific location override based on location code and call number. Specific location overrides are
|
126
|
+
# located in `location_overrides.yml`.
|
127
|
+
# @param [String] display_value
|
128
|
+
# @param [String] location_code
|
129
|
+
# @param [MARC::Field] field
|
130
|
+
# @param [String] call_num_sf
|
131
|
+
# @return [String, Nil]
|
132
|
+
def specific_location_override(display_value:, location_code:, field:, call_num_sf:)
|
133
|
+
return unless display_value == :specific_location
|
134
|
+
|
135
|
+
locations_overrides = Mappers.location_overrides
|
136
|
+
|
137
|
+
call_numbers = subfield_values(field, call_num_sf)
|
138
|
+
|
139
|
+
override = locations_overrides.select do |_key, value|
|
140
|
+
value[:location_code] == location_code && call_numbers.any? { |num| num.match?(value[:call_num_pattern]) }
|
101
141
|
end
|
102
142
|
|
103
|
-
|
143
|
+
return if override.blank?
|
144
|
+
|
145
|
+
override[override.keys.first][:specific_location]
|
104
146
|
end
|
105
147
|
end
|
106
148
|
end
|
@@ -166,12 +166,19 @@ module PennMARC
|
|
166
166
|
system_details_notes.uniq
|
167
167
|
end
|
168
168
|
|
169
|
+
# Retrieve "With" notes for display from field {https://www.loc.gov/marc/bibliographic/bd501.html 501}
|
170
|
+
# @param [Marc::Record] record
|
171
|
+
# @return [Array<String>]
|
172
|
+
def bound_with_show(record)
|
173
|
+
record.fields('501').filter_map { |field| join_subfields(field, &subfield_in?(['a'])).presence }.uniq
|
174
|
+
end
|
175
|
+
|
169
176
|
private
|
170
177
|
|
171
178
|
# For system details: extract subfield ǂ3 plus other subfields as specified by passed-in block. Pays special
|
172
179
|
# attention to punctuation, joining subfield ǂ3 values with a colon-space (': ').
|
173
180
|
# @param [MARC::DataField] field
|
174
|
-
# @param [Proc]
|
181
|
+
# @param [Proc] &
|
175
182
|
# @return [String]
|
176
183
|
def sub3_and_other_subs(field, &)
|
177
184
|
sub3 = field.filter_map { |sf| trim_trailing('period', sf.value) if sf.code == '3' }.join(': ')
|
@@ -160,7 +160,6 @@ module PennMARC
|
|
160
160
|
|
161
161
|
# Format a term hash as a string for display
|
162
162
|
#
|
163
|
-
# @todo confirm punctuation handling
|
164
163
|
# @todo support search field formatting?
|
165
164
|
# @param [Symbol] type
|
166
165
|
# @param [Hash] term components and information as a hash
|
@@ -171,11 +170,12 @@ module PennMARC
|
|
171
170
|
# attempt to handle poorly coded record
|
172
171
|
normalize_single_subfield(term[:parts].first) if term[:count] == 1 && term[:parts].first.present?
|
173
172
|
|
174
|
-
case type
|
173
|
+
case type
|
175
174
|
when :facet
|
176
|
-
term[:parts].join('--').strip
|
175
|
+
trim_trailing(:period, term[:parts].join('--').strip)
|
177
176
|
when :display
|
178
|
-
"#{term[:parts].join('--')} #{term[:append].join(' ')}".strip
|
177
|
+
display_value = "#{term[:parts].join('--')} #{term[:append].join(' ')}".strip
|
178
|
+
display_value.ends_with?('.') ? display_value : "#{display_value}."
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
@@ -225,9 +225,8 @@ module PennMARC
|
|
225
225
|
# because we're using (where? - MK) "subdivision count" as a heuristic for the quality level of the
|
226
226
|
# heading. - MG
|
227
227
|
# @todo do i need all this?
|
228
|
-
# @todo do i need to handle punctuation? see append_new_part
|
229
228
|
# @param [MARC::DataField] field
|
230
|
-
# @return [Hash{Symbol => Integer, Array}, Nil]
|
229
|
+
# @return [Hash{Symbol => Integer, Array, Boolean}, Nil]
|
231
230
|
def build_subject_hash(field)
|
232
231
|
term_info = { count: 0, parts: [], append: [], uri: nil,
|
233
232
|
local: field.indicator2 == '4' || field.tag.starts_with?('69'), # local subject heading
|
@@ -243,6 +242,9 @@ module PennMARC
|
|
243
242
|
# filter out PRO/CHR entirely (but only need to check on local heading types)
|
244
243
|
return nil if term_info[:local] && subfield.value =~ /^%?(PRO|CHR)([ $]|$)/
|
245
244
|
|
245
|
+
# remove trailing punctuation of previous subject part
|
246
|
+
trim_trailing_commas_or_periods!(term_info[:parts].last)
|
247
|
+
|
246
248
|
term_info[:parts] << subfield.value.strip
|
247
249
|
term_info[:count] += 1
|
248
250
|
when '2'
|
@@ -252,11 +254,16 @@ module PennMARC
|
|
252
254
|
term_info[:append] << subfield.value.strip # TODO: map relator code?
|
253
255
|
when 'b', 'c', 'd', 'p', 'q', 't'
|
254
256
|
# these are appended to the last component (part) if possible (i.e., when joined, should have no delimiter)
|
255
|
-
|
257
|
+
# assume that there is an 'a' preceding value
|
258
|
+
term_info[:parts].last << " #{subfield.value.strip}"
|
256
259
|
term_info[:count] += 1
|
257
260
|
else
|
258
261
|
# the usual case; add a new component to `parts`
|
259
262
|
# this typically includes g, v, x, y, z, 4
|
263
|
+
|
264
|
+
# remove trailing punctuation of previous subject part
|
265
|
+
trim_trailing_commas_or_periods!(term_info[:parts].last)
|
266
|
+
|
260
267
|
term_info[:parts] << subfield.value.strip
|
261
268
|
term_info[:count] += 1
|
262
269
|
end
|
@@ -299,6 +306,15 @@ module PennMARC
|
|
299
306
|
first_part.gsub!(/([[[:alpha:]])])\s+-\s+([[:upper:]]|[[:digit:]]{2,})/, '\1--\2')
|
300
307
|
first_part.gsub!(/([[[:alnum:]])])\s+-\s+([[:upper:]])/, '\1--\2')
|
301
308
|
end
|
309
|
+
|
310
|
+
# removes trailing comma or period, manipulating the string in place
|
311
|
+
# @param [String, NilClass] subject_part
|
312
|
+
# @return [String, NilClass]
|
313
|
+
def trim_trailing_commas_or_periods!(subject_part)
|
314
|
+
return if subject_part.blank?
|
315
|
+
|
316
|
+
trim_trailing!(:comma, subject_part) || trim_trailing!(:period, subject_part)
|
317
|
+
end
|
302
318
|
end
|
303
319
|
end
|
304
320
|
end
|
data/lib/pennmarc/mappers.rb
CHANGED
@@ -18,6 +18,11 @@ module PennMARC
|
|
18
18
|
@location ||= load_map('locations.yml')
|
19
19
|
end
|
20
20
|
|
21
|
+
# @return [Hash]
|
22
|
+
def location_overrides
|
23
|
+
@location_overrides ||= load_map('location_overrides.yml')
|
24
|
+
end
|
25
|
+
|
21
26
|
# @return [Hash]
|
22
27
|
def relator
|
23
28
|
@relator ||= load_map('relator.yml')
|
data/lib/pennmarc/util.rb
CHANGED
@@ -5,6 +5,13 @@ require_relative 'heading_control'
|
|
5
5
|
module PennMARC
|
6
6
|
# class to hold "utility" methods used in MARC parsing methods
|
7
7
|
module Util
|
8
|
+
TRAILING_PUNCTUATIONS_PATTERNS = { semicolon: /\s*;\s*$/,
|
9
|
+
colon: /\s*:\s*$/,
|
10
|
+
equal: /=$/,
|
11
|
+
slash: %r{\s*/\s*$},
|
12
|
+
comma: /\s*,\s*$/,
|
13
|
+
period: /\.\s*$/ }.freeze # TODO: revise to exclude "etc."
|
14
|
+
|
8
15
|
# Check if a given record has a field present by tag (e.g., '041')
|
9
16
|
# @param [MARC::Record] record
|
10
17
|
# @param [String] marc_field
|
@@ -115,14 +122,17 @@ module PennMARC
|
|
115
122
|
|
116
123
|
# @param [Symbol|String] trailer to target for removal
|
117
124
|
# @param [String] string to modify
|
125
|
+
# @return [String]
|
118
126
|
def trim_trailing(trailer, string)
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
127
|
+
string.sub TRAILING_PUNCTUATIONS_PATTERNS[trailer.to_sym], ''
|
128
|
+
end
|
129
|
+
|
130
|
+
# trim trailing punctuation, manipulating string in place
|
131
|
+
# @param [Symbol|String] trailer to target for removal
|
132
|
+
# @param [String] string to modify
|
133
|
+
# @return [String, Nil] string to modify
|
134
|
+
def trim_trailing!(trailer, string)
|
135
|
+
string.sub! TRAILING_PUNCTUATIONS_PATTERNS[trailer.to_sym], ''
|
126
136
|
end
|
127
137
|
|
128
138
|
# Intelligently append given punctuation to the end of a string
|
data/lib/pennmarc/version.rb
CHANGED
@@ -181,6 +181,20 @@ describe 'PennMARC::Format' do
|
|
181
181
|
expect(value.join(' ')).not_to include 'excluded'
|
182
182
|
end
|
183
183
|
end
|
184
|
+
|
185
|
+
context 'with an unrelated linked alternate' do
|
186
|
+
let(:fields) do
|
187
|
+
[marc_field(tag: '300', subfields: { a: '96 pages ;', c: '23 cm ' }),
|
188
|
+
marc_field(tag: '880', subfields: { '6': '700', a: 'Schweizer, Shlomo,', d: '1903-',
|
189
|
+
'0': 'https://id.loc.gov/authorities/names/no95018724' })]
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'returns the expected format values' do
|
193
|
+
value = helper.show(record)
|
194
|
+
expect(value).to contain_exactly '96 pages ; 23 cm'
|
195
|
+
expect(value.join(' ')).not_to include 'https://id.loc.gov/authorities/names/no95018724'
|
196
|
+
end
|
197
|
+
end
|
184
198
|
end
|
185
199
|
|
186
200
|
describe '.other_show' do
|
@@ -111,4 +111,20 @@ describe 'PennMARC::Location' do
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
114
|
+
|
115
|
+
context 'with a specific location override' do
|
116
|
+
let(:record) do
|
117
|
+
marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
|
118
|
+
subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'vanp',
|
119
|
+
enriched_marc::Pub::ITEM_CALL_NUMBER => 'ML3534 .D85 1984' }),
|
120
|
+
marc_field(tag: enriched_marc::Pub::ITEM_TAG,
|
121
|
+
subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor',
|
122
|
+
enriched_marc::Pub::ITEM_CALL_NUMBER => 'L3534 .D85 1984' })])
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'returns expected values' do
|
126
|
+
expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
|
127
|
+
.to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
|
128
|
+
end
|
129
|
+
end
|
114
130
|
end
|
@@ -296,5 +296,23 @@ text for URI http://www.universal.resource/locator'.squish,
|
|
296
296
|
)
|
297
297
|
end
|
298
298
|
end
|
299
|
+
|
300
|
+
describe '.bound_with_show' do
|
301
|
+
let(:record) { marc_record(fields: fields) }
|
302
|
+
|
303
|
+
let(:fields) do
|
304
|
+
[
|
305
|
+
marc_field(tag: '501', subfields: { a: 'With: Peer Gynt (Suite) no. 1-2 / Edvard Grieg' }),
|
306
|
+
marc_field(tag: '501', subfields: { a: 'With: Schumann, C. Romances, piano, op. 11. No. 2' })
|
307
|
+
]
|
308
|
+
end
|
309
|
+
|
310
|
+
let(:values) { helper.bound_with_show(record) }
|
311
|
+
|
312
|
+
it 'returns expected values' do
|
313
|
+
expect(values).to contain_exactly('With: Peer Gynt (Suite) no. 1-2 / Edvard Grieg',
|
314
|
+
'With: Schumann, C. Romances, piano, op. 11. No. 2')
|
315
|
+
end
|
316
|
+
end
|
299
317
|
end
|
300
318
|
end
|
@@ -101,7 +101,7 @@ describe 'PennMARC::Subject' do
|
|
101
101
|
let(:fields) do
|
102
102
|
[marc_field(tag: '650', indicator2: '7',
|
103
103
|
subfields: {
|
104
|
-
a: 'Libraries', d: '22nd Century', x: 'History', e: 'relator',
|
104
|
+
a: 'Libraries,', d: '22nd Century,', x: 'History.', e: 'relator',
|
105
105
|
'2': 'fast', '0': 'http://fast.org/libraries'
|
106
106
|
})]
|
107
107
|
end
|
@@ -127,6 +127,21 @@ describe 'PennMARC::Subject' do
|
|
127
127
|
expect(values.first).to eq 'Libraries, 22nd Century--History'
|
128
128
|
end
|
129
129
|
end
|
130
|
+
|
131
|
+
context 'with a record with trailing periods' do
|
132
|
+
let(:fields) do
|
133
|
+
[marc_field(tag: '600', indicator2: '0',
|
134
|
+
subfields: {
|
135
|
+
a: 'R.G.', q: '(Robert Gordon).',
|
136
|
+
t: 'Spiritual order and Christian liberty proved to be consistent in the Churches of Christ. '
|
137
|
+
})]
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'drops the final trailing period' do
|
141
|
+
expect(values).to contain_exactly('R.G. (Robert Gordon). Spiritual order and Christian liberty proved ' \
|
142
|
+
'to be consistent in the Churches of Christ')
|
143
|
+
end
|
144
|
+
end
|
130
145
|
end
|
131
146
|
|
132
147
|
describe '.show' do
|
@@ -146,8 +161,8 @@ describe 'PennMARC::Subject' do
|
|
146
161
|
end
|
147
162
|
|
148
163
|
it 'shows all valid subject headings without duplicates' do
|
149
|
-
expect(helper.show(record)).to contain_exactly('Nephrology--Periodicals', 'Nephrology', 'Kidney Diseases',
|
150
|
-
'Local Heading')
|
164
|
+
expect(helper.show(record)).to contain_exactly('Nephrology--Periodicals.', 'Nephrology.', 'Kidney Diseases.',
|
165
|
+
'Local Heading.')
|
151
166
|
end
|
152
167
|
end
|
153
168
|
|
@@ -155,7 +170,7 @@ describe 'PennMARC::Subject' do
|
|
155
170
|
let(:fields) do
|
156
171
|
[marc_field(tag: '650', indicator2: '0', subfields: {
|
157
172
|
a: 'Subways',
|
158
|
-
z: ['Pennsylvania', 'Philadelphia Metropolitan Area'],
|
173
|
+
z: ['Pennsylvania,', 'Philadelphia Metropolitan Area,'],
|
159
174
|
v: 'Maps',
|
160
175
|
y: '1989',
|
161
176
|
e: 'relator'
|
@@ -163,7 +178,7 @@ describe 'PennMARC::Subject' do
|
|
163
178
|
end
|
164
179
|
|
165
180
|
it 'properly formats the heading parts' do
|
166
|
-
expect(values.first).to eq 'Subways--Pennsylvania--Philadelphia Metropolitan Area--Maps--1989 relator'
|
181
|
+
expect(values.first).to eq 'Subways--Pennsylvania--Philadelphia Metropolitan Area--Maps--1989 relator.'
|
167
182
|
end
|
168
183
|
end
|
169
184
|
|
@@ -171,20 +186,37 @@ describe 'PennMARC::Subject' do
|
|
171
186
|
let(:fields) do
|
172
187
|
[marc_field(tag: '600', indicator2: '7', subfields: {
|
173
188
|
a: 'Franklin, Benjamin,',
|
174
|
-
d: '1706-1790',
|
189
|
+
d: '1706-1790.',
|
175
190
|
'2': 'fast',
|
176
191
|
'0': 'http://id.worldcat.org/fast/34115'
|
177
192
|
}),
|
178
193
|
marc_field(tag: '600', indicator1: '1', indicator2: '0', subfields: {
|
179
194
|
a: 'Franklin, Benjamin,',
|
180
|
-
d: '1706-1790
|
195
|
+
d: '1706-1790',
|
181
196
|
x: 'As inventor.'
|
197
|
+
}),
|
198
|
+
marc_field(tag: '650', indicator1: '1', indicator2: '0', subfields: {
|
199
|
+
a: 'Franklin stoves.'
|
182
200
|
})]
|
183
201
|
end
|
184
202
|
|
185
|
-
it '
|
203
|
+
it 'properly handles punctuation in subject parts' do
|
186
204
|
expect(values).to contain_exactly 'Franklin, Benjamin, 1706-1790.',
|
187
|
-
'Franklin, Benjamin, 1706-1790--As inventor.'
|
205
|
+
'Franklin, Benjamin, 1706-1790--As inventor.', 'Franklin stoves.'
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'with a record without trailing period in last subject part' do
|
210
|
+
let(:fields) do
|
211
|
+
[marc_field(tag: '651', indicator2: '7',
|
212
|
+
subfields: {
|
213
|
+
a: 'New York State (State)', z: 'New York', '2': 'fast', '0': '(OCoLC)fst01204333',
|
214
|
+
'1': 'https://id.oclc.org/worldcat/entity/E39QbtfRvQh7864Jh4rDGBFDWc'
|
215
|
+
})]
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'adds a trailing period' do
|
219
|
+
expect(values).to contain_exactly('New York State (State)--New York.')
|
188
220
|
end
|
189
221
|
end
|
190
222
|
|
@@ -200,40 +232,40 @@ describe 'PennMARC::Subject' do
|
|
200
232
|
end
|
201
233
|
|
202
234
|
it 'properly formats the heading parts' do
|
203
|
-
expect(values.first).to eq 'Chicago (Ill.)--Moral conditions--Church minutes--1875-1878'
|
235
|
+
expect(values.first).to eq 'Chicago (Ill.)--Moral conditions--Church minutes--1875-1878.'
|
204
236
|
end
|
205
237
|
end
|
206
238
|
|
207
239
|
context 'with a robust 611 heading including many subfields' do
|
208
240
|
let(:fields) do
|
209
241
|
[marc_field(tag: '611', indicator2: '0', subfields: {
|
210
|
-
a: 'Conference',
|
211
|
-
c: ['(Johannesburg, South Africa', 'Cape Town, South Africa'],
|
242
|
+
a: 'Conference,',
|
243
|
+
c: ['(Johannesburg, South Africa,', 'Cape Town, South Africa,'],
|
212
244
|
d: '2002)',
|
213
245
|
n: '2nd'
|
214
246
|
})]
|
215
247
|
end
|
216
248
|
|
217
249
|
it 'properly formats the heading parts' do
|
218
|
-
expect(values.first).to eq 'Conference, (Johannesburg, South Africa, Cape Town, South Africa, 2002)--2nd'
|
250
|
+
expect(values.first).to eq 'Conference, (Johannesburg, South Africa, Cape Town, South Africa, 2002)--2nd.'
|
219
251
|
end
|
220
252
|
end
|
221
253
|
|
222
254
|
context 'with a robust 600 heading including many subfields' do
|
223
255
|
let(:fields) do
|
224
256
|
[marc_field(tag: '600', indicator2: '0', subfields: {
|
225
|
-
a: 'Person, Significant Author',
|
226
|
-
b: 'Numerator',
|
227
|
-
c:
|
228
|
-
d: '1899-1971',
|
257
|
+
a: 'Person, Significant Author,',
|
258
|
+
b: 'Numerator,',
|
259
|
+
c: ['Title,', 'Rank,'],
|
260
|
+
d: '1899-1971,',
|
229
261
|
t: 'Collection',
|
230
|
-
v: 'Early works to 1950'
|
262
|
+
v: 'Early works to 1950.'
|
231
263
|
})]
|
232
264
|
end
|
233
265
|
|
234
266
|
it 'properly formats the heading parts' do
|
235
267
|
expect(values.first).to eq('Person, Significant Author, Numerator, Title, Rank, 1899-1971, Collection--' \
|
236
|
-
'Early works to 1950')
|
268
|
+
'Early works to 1950.')
|
237
269
|
end
|
238
270
|
end
|
239
271
|
end
|
@@ -249,7 +281,7 @@ describe 'PennMARC::Subject' do
|
|
249
281
|
let(:values) { helper.childrens_show(record) }
|
250
282
|
|
251
283
|
it 'includes heading terms only from subject tags with an indicator 2 of "1"' do
|
252
|
-
expect(values).to contain_exactly 'Frogs--Fiction', 'Toads--Fiction'
|
284
|
+
expect(values).to contain_exactly 'Frogs--Fiction.', 'Toads--Fiction.'
|
253
285
|
end
|
254
286
|
end
|
255
287
|
|
@@ -267,7 +299,7 @@ describe 'PennMARC::Subject' do
|
|
267
299
|
end
|
268
300
|
|
269
301
|
it 'includes heading terms only from subject tags with indicator 2 of "2"' do
|
270
|
-
expect(helper.medical_show(record)).to contain_exactly 'Nephrology'
|
302
|
+
expect(helper.medical_show(record)).to contain_exactly 'Nephrology.'
|
271
303
|
end
|
272
304
|
end
|
273
305
|
|
@@ -280,7 +312,7 @@ describe 'PennMARC::Subject' do
|
|
280
312
|
end
|
281
313
|
|
282
314
|
it 'includes heading terms only from subject tags with indicator 2 of "4" or in the 69X range' do
|
283
|
-
expect(helper.local_show(record)).to contain_exactly 'Local--Heading', 'Super Local.'
|
315
|
+
expect(helper.local_show(record)).to contain_exactly 'Local--Heading.', 'Super Local.'
|
284
316
|
end
|
285
317
|
end
|
286
318
|
end
|
@@ -72,13 +72,14 @@ module MarcSpecHelpers
|
|
72
72
|
# location_map[:stor][:library] #=> 'LIBRA'
|
73
73
|
# @return [Hash]
|
74
74
|
def location_map
|
75
|
-
{
|
76
|
-
dent: { specific_location: 'Levy Dental Medicine Library - Stacks',
|
75
|
+
{ dent: { specific_location: 'Levy Dental Medicine Library - Stacks',
|
77
76
|
library: ['Health Sciences Libraries', 'Levy Dental Medicine Library'],
|
78
77
|
display: 'Levy Dental Medicine Library - Stacks' },
|
79
78
|
stor: { specific_location: 'LIBRA',
|
80
79
|
library: 'LIBRA',
|
81
|
-
display: 'LIBRA' }
|
82
|
-
|
80
|
+
display: 'LIBRA' },
|
81
|
+
vanp: { specific_location: 'Van Pelt - Stacks',
|
82
|
+
library: 'Van Pelt-Dietrich Library Center',
|
83
|
+
display: 'Van Pelt Library' } }
|
83
84
|
end
|
84
85
|
end
|
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.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Kanning
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-02-
|
13
|
+
date: 2024-02-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- lib/pennmarc/mappings/iso639-2-languages.yml
|
120
120
|
- lib/pennmarc/mappings/iso639-3-languages.yml
|
121
121
|
- lib/pennmarc/mappings/loc_classification.yml
|
122
|
+
- lib/pennmarc/mappings/location_overrides.yml
|
122
123
|
- lib/pennmarc/mappings/locations.yml
|
123
124
|
- lib/pennmarc/mappings/relator.yml
|
124
125
|
- lib/pennmarc/parser.rb
|