pennmarc 1.0.12 → 1.0.15.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +7 -12
- data/.rubocop_todo.yml +2 -2
- data/lib/pennmarc/enriched.rb +93 -0
- data/lib/pennmarc/helpers/access.rb +2 -2
- data/lib/pennmarc/helpers/citation.rb +4 -4
- data/lib/pennmarc/helpers/classification.rb +8 -8
- data/lib/pennmarc/helpers/creator.rb +70 -73
- data/lib/pennmarc/helpers/database.rb +6 -6
- data/lib/pennmarc/helpers/date.rb +3 -3
- data/lib/pennmarc/helpers/edition.rb +4 -2
- data/lib/pennmarc/helpers/format.rb +15 -14
- data/lib/pennmarc/helpers/helper.rb +1 -1
- data/lib/pennmarc/helpers/identifier.rb +16 -14
- data/lib/pennmarc/helpers/inventory.rb +92 -0
- data/lib/pennmarc/helpers/inventory_entry/base.rb +23 -0
- data/lib/pennmarc/helpers/inventory_entry/electronic.rb +20 -0
- data/lib/pennmarc/helpers/inventory_entry/physical.rb +38 -0
- data/lib/pennmarc/helpers/language.rb +3 -2
- data/lib/pennmarc/helpers/location.rb +19 -14
- data/lib/pennmarc/helpers/note.rb +10 -8
- data/lib/pennmarc/helpers/production.rb +9 -9
- data/lib/pennmarc/helpers/relation.rb +12 -9
- data/lib/pennmarc/helpers/series.rb +10 -8
- data/lib/pennmarc/helpers/subject.rb +12 -12
- data/lib/pennmarc/helpers/title.rb +20 -16
- data/lib/pennmarc/mappings/locations.yml +4 -0
- data/lib/pennmarc/util.rb +19 -4
- data/lib/pennmarc/version.rb +1 -1
- data/spec/lib/pennmarc/helpers/access_spec.rb +5 -5
- data/spec/lib/pennmarc/helpers/classification_spec.rb +6 -6
- data/spec/lib/pennmarc/helpers/creator_spec.rb +41 -7
- data/spec/lib/pennmarc/helpers/format_spec.rb +4 -4
- data/spec/lib/pennmarc/helpers/inventory_spec.rb +129 -0
- data/spec/lib/pennmarc/helpers/location_spec.rb +40 -9
- data/spec/lib/pennmarc/helpers/subject_spec.rb +37 -13
- metadata +10 -5
- data/lib/pennmarc/enriched_marc.rb +0 -49
@@ -34,11 +34,12 @@ module PennMARC
|
|
34
34
|
# @param [MARC::Record] record
|
35
35
|
# @return [Array<String>]
|
36
36
|
def isbn_show(record)
|
37
|
-
|
37
|
+
values = record.fields('020').filter_map do |field|
|
38
38
|
joined_isbn = join_subfields(field, &subfield_in?(%w[a]))
|
39
39
|
joined_isbn.presence
|
40
40
|
end
|
41
|
-
isbn_values + linked_alternate(record, '020', &subfield_in?(%w[a]))
|
41
|
+
isbn_values = values + linked_alternate(record, '020', &subfield_in?(%w[a]))
|
42
|
+
isbn_values.uniq
|
42
43
|
end
|
43
44
|
|
44
45
|
# Get ISSN values for display from the {https://www.oclc.org/bibformats/en/0xx/022.html 022 field} and related
|
@@ -47,11 +48,12 @@ module PennMARC
|
|
47
48
|
# @param [MARC::Record] record
|
48
49
|
# @return [Array<String>]
|
49
50
|
def issn_show(record)
|
50
|
-
|
51
|
+
values = record.fields('022').filter_map do |field|
|
51
52
|
joined_issn = join_subfields(field, &subfield_in?(%w[a]))
|
52
53
|
joined_issn.presence
|
53
54
|
end
|
54
|
-
issn_values + linked_alternate(record, '022', &subfield_in?(%w[a]))
|
55
|
+
issn_values = values + linked_alternate(record, '022', &subfield_in?(%w[a]))
|
56
|
+
issn_values.uniq
|
55
57
|
end
|
56
58
|
|
57
59
|
# Get numeric OCLC ID of first {https://www.oclc.org/bibformats/en/0xx/035.html 035 field}
|
@@ -82,7 +84,7 @@ module PennMARC
|
|
82
84
|
# @param [MARC::Record] record
|
83
85
|
# @return [Array<String>]
|
84
86
|
def oclc_id_search(record)
|
85
|
-
record.fields('035').flat_map
|
87
|
+
record.fields('035').flat_map { |field|
|
86
88
|
field.filter_map do |subfield|
|
87
89
|
# skip unless subfield 'a' or 'z'
|
88
90
|
next unless subfield.code.in?(%w[a z])
|
@@ -98,7 +100,7 @@ module PennMARC
|
|
98
100
|
|
99
101
|
match[1]
|
100
102
|
end
|
101
|
-
|
103
|
+
}.uniq
|
102
104
|
end
|
103
105
|
|
104
106
|
# Get publisher issued identifiers from fields {https://www.oclc.org/bibformats/en/0xx/024.html 024},
|
@@ -109,7 +111,7 @@ module PennMARC
|
|
109
111
|
# @param [MARC::Record] record
|
110
112
|
# @return [Array<string>]
|
111
113
|
def publisher_number_show(record)
|
112
|
-
record.fields(%w[024 028 880]).filter_map
|
114
|
+
record.fields(%w[024 028 880]).filter_map { |field|
|
113
115
|
next if field.tag == '880' && subfield_value_not_in?(field, '6', %w[024 028])
|
114
116
|
|
115
117
|
# do not return doi values from 024 ǂ2
|
@@ -118,7 +120,7 @@ module PennMARC
|
|
118
120
|
else
|
119
121
|
join_subfields(field, &subfield_not_in?(%w[5 6])).presence
|
120
122
|
end
|
121
|
-
|
123
|
+
}.uniq
|
122
124
|
end
|
123
125
|
|
124
126
|
# Get publisher issued identifiers for searching of a record. Values extracted from fields
|
@@ -127,19 +129,19 @@ module PennMARC
|
|
127
129
|
# @param [MARC::Record] record
|
128
130
|
# @return [Array<String>]
|
129
131
|
def publisher_number_search(record)
|
130
|
-
record.fields(%w[024 028]).filter_map
|
132
|
+
record.fields(%w[024 028]).filter_map { |field|
|
131
133
|
joined_identifiers = join_subfields(field, &subfield_in?(%w[a]))
|
132
134
|
joined_identifiers.presence
|
133
|
-
|
135
|
+
}.uniq
|
134
136
|
end
|
135
137
|
|
136
138
|
# Retrieve fingerprint for display from the {https://www.oclc.org/bibformats/en/0xx/026.html 026} field
|
137
139
|
# @param [MARC::Record] record
|
138
140
|
# @return [Array<String>]
|
139
141
|
def fingerprint_show(record)
|
140
|
-
record.fields('026').map
|
142
|
+
record.fields('026').map { |field|
|
141
143
|
join_subfields(field, &subfield_not_in?(%w[2 5 6 8]))
|
142
|
-
|
144
|
+
}.uniq
|
143
145
|
end
|
144
146
|
|
145
147
|
# Retrieve DOI values stored in {https://www.oclc.org/bibformats/en/0xx/024.html 024}.
|
@@ -147,14 +149,14 @@ module PennMARC
|
|
147
149
|
# @param [MARC::Record] record
|
148
150
|
# @return [Array<String>]
|
149
151
|
def doi_show(record)
|
150
|
-
record.fields('024').filter_map
|
152
|
+
record.fields('024').filter_map { |field|
|
151
153
|
# skip unless indicator1 is '7'
|
152
154
|
next unless field.indicator1.in?(%w[7])
|
153
155
|
# skip unless ǂ2 is the string literal 'doi'
|
154
156
|
next unless subfield_value_in?(field, '2', %w[doi])
|
155
157
|
|
156
158
|
join_subfields(field, &subfield_in?(%w[a]))
|
157
|
-
|
159
|
+
}.uniq
|
158
160
|
end
|
159
161
|
|
160
162
|
private
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'inventory_entry/electronic'
|
4
|
+
require_relative 'inventory_entry/physical'
|
5
|
+
|
6
|
+
module PennMARC
|
7
|
+
# Methods for extracting holdings information ("inventory") when available
|
8
|
+
class Inventory < Helper
|
9
|
+
PHYSICAL_INVENTORY_TAGS = [
|
10
|
+
Enriched::Pub::PHYS_INVENTORY_TAG,
|
11
|
+
Enriched::Api::PHYS_INVENTORY_TAG
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
ELECTRONIC_INVENTORY_TAGS = [
|
15
|
+
Enriched::Pub::ELEC_INVENTORY_TAG,
|
16
|
+
Enriched::Api::ELEC_INVENTORY_TAG
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
class << self
|
20
|
+
# Hash of Physical holdings information
|
21
|
+
# @param [MARC::Record] record
|
22
|
+
# @return [Array, nil]
|
23
|
+
def physical(record)
|
24
|
+
source = enrichment_source(record)
|
25
|
+
return unless source
|
26
|
+
|
27
|
+
record.fields(PHYSICAL_INVENTORY_TAGS).map do |entry|
|
28
|
+
InventoryEntry::Physical.new(entry, source).to_h
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Hash of Electronic inventory information
|
33
|
+
# @param [MARC::Record] record
|
34
|
+
# @return [Array, nil]
|
35
|
+
def electronic(record)
|
36
|
+
source = enrichment_source(record)
|
37
|
+
return unless source
|
38
|
+
|
39
|
+
record.fields(ELECTRONIC_INVENTORY_TAGS).map do |entry|
|
40
|
+
InventoryEntry::Electronic.new(entry, source).to_h
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Count of all electronic portfolios
|
45
|
+
# @param [MARC::Record] record
|
46
|
+
# @return [Integer]
|
47
|
+
def electronic_portfolio_count(record)
|
48
|
+
record.count { |field| field.tag.in? %w[AVE prt] }
|
49
|
+
end
|
50
|
+
|
51
|
+
# Count of all physical holdings
|
52
|
+
# @param [MARC::Record] record
|
53
|
+
# @return [Integer]
|
54
|
+
def physical_holding_count(record)
|
55
|
+
record.count { |field| field.tag.in? %w[AVA hld] }
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# Determine the source of the MARC inventory enrichment
|
61
|
+
# @param [MARC::Record] record
|
62
|
+
# @return [Symbol, nil]
|
63
|
+
def enrichment_source(record)
|
64
|
+
if pub_enrichment_tags?(record)
|
65
|
+
:pub
|
66
|
+
elsif api_enrichment_tags?(record)
|
67
|
+
:api
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Does the record include tags from Publishing inventory enrichment?
|
72
|
+
# @todo move to Util?
|
73
|
+
# @param [MARC::Record] record
|
74
|
+
# @return [Boolean]
|
75
|
+
def pub_enrichment_tags?(record)
|
76
|
+
record.tags.intersect?(
|
77
|
+
[Enriched::Pub::PHYS_INVENTORY_TAG, Enriched::Pub::ELEC_INVENTORY_TAG, Enriched::Pub::ITEM_TAG]
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Does the record include tags from API inventory enrichment?
|
82
|
+
# @todo move to Util?
|
83
|
+
# @param [MARC::Record] record
|
84
|
+
# @return [Boolean]
|
85
|
+
def api_enrichment_tags?(record)
|
86
|
+
record.tags.intersect?(
|
87
|
+
[Enriched::Api::PHYS_INVENTORY_TAG, Enriched::Api::ELEC_INVENTORY_TAG]
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PennMARC
|
4
|
+
module InventoryEntry
|
5
|
+
# Base class for InventoryEntry classes, defines required interface
|
6
|
+
class Base
|
7
|
+
attr_reader :source, :field, :mapper
|
8
|
+
|
9
|
+
# @param [MARC::DataField] inventory_field
|
10
|
+
# @param [Symbol] source
|
11
|
+
def initialize(inventory_field, source)
|
12
|
+
@source = source
|
13
|
+
@field = inventory_field
|
14
|
+
@mapper = @source == :api ? Enriched::Api : Enriched::Pub
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Hash]
|
18
|
+
def to_h
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module PennMARC
|
6
|
+
module InventoryEntry
|
7
|
+
# Represent a Electronic inventory entry - simple because the subfield specification is identical across
|
8
|
+
# entries returned by the API and Alma Publishing enrichment
|
9
|
+
class Electronic < Base
|
10
|
+
# @return [Hash{Symbol->Unknown}]
|
11
|
+
def to_h
|
12
|
+
{ portfolio_id: field[mapper::ELEC_PORTFOLIO_ID],
|
13
|
+
url: field[mapper::ELEC_SERVICE_URL],
|
14
|
+
collection_name: field[mapper::ELEC_COLLECTION_NAME],
|
15
|
+
coverage: field[mapper::ELEC_COVERAGE_STMT],
|
16
|
+
note: field[mapper::ELEC_PUBLIC_NOTE] }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module PennMARC
|
6
|
+
module InventoryEntry
|
7
|
+
# Represent a Physical inventory entry
|
8
|
+
class Physical < Base
|
9
|
+
# Call number from inventory entry
|
10
|
+
# @return [String (frozen)]
|
11
|
+
def call_num
|
12
|
+
if source == :pub
|
13
|
+
"#{field[mapper::HOLDING_CLASSIFICATION_PART]}#{field[mapper::HOLDING_ITEM_PART]}"
|
14
|
+
elsif source == :api
|
15
|
+
field[mapper::PHYS_CALL_NUMBER]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Priority for inventory entry
|
20
|
+
# @note we currently don't return priority in our publishing enrichment
|
21
|
+
# @return [String, nil]
|
22
|
+
def priority
|
23
|
+
return nil if source == :pub
|
24
|
+
|
25
|
+
field[mapper::PHYS_PRIORITY]
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Hash{Symbol->Unknown}]
|
29
|
+
def to_h
|
30
|
+
{ holding_id: field[mapper::PHYS_HOLDING_ID],
|
31
|
+
location_name: field[mapper::PHYS_LOCATION_NAME],
|
32
|
+
location_code: field[mapper::PHYS_LOCATION_CODE],
|
33
|
+
call_num: call_num,
|
34
|
+
priority: priority }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -18,7 +18,8 @@ module PennMARC
|
|
18
18
|
values = record.fields('546').map do |field|
|
19
19
|
join_subfields field, &subfield_not_in?(%w[6 8])
|
20
20
|
end
|
21
|
-
values + linked_alternate(record, '546', &subfield_not_in?(%w[6 8]))
|
21
|
+
language_values = values + linked_alternate(record, '546', &subfield_not_in?(%w[6 8]))
|
22
|
+
language_values.uniq
|
22
23
|
end
|
23
24
|
|
24
25
|
# Get language values for searching and faceting of a record. The values are extracted from subfields
|
@@ -33,7 +34,7 @@ module PennMARC
|
|
33
34
|
# @param [MARC::Record] record
|
34
35
|
# @param [Hash] iso_639_2_mapping iso-639-2 spec hash for language code translation
|
35
36
|
# @param [Hash] iso_639_3_mapping iso-639-3 spec hash for language code translation
|
36
|
-
# @return [Array] array of language values
|
37
|
+
# @return [Array<String>] array of language values
|
37
38
|
def values(record, iso_639_2_mapping: Mappers.iso_639_2_language, iso_639_3_mapping: Mappers.iso_639_3_language)
|
38
39
|
values = record.fields('041').filter_map { |field|
|
39
40
|
mapper = subfield_value?(field, '2', /iso639-3/) ? iso_639_3_mapping : iso_639_2_mapping
|
@@ -3,10 +3,12 @@
|
|
3
3
|
module PennMARC
|
4
4
|
# Methods that return Library and Location values from Alma enhanced MARC fields
|
5
5
|
class Location < Helper
|
6
|
+
ONLINE_LIBRARY = 'Online library'
|
7
|
+
|
6
8
|
class << self
|
7
9
|
# Retrieves library location from enriched marc 'itm' or 'hld' fields, giving priority to the item location over
|
8
10
|
# the holdings location. Returns item's location if available. Otherwise, returns holding's location.
|
9
|
-
# {PennMARC::
|
11
|
+
# {PennMARC::Enriched} maps enriched marc fields and subfields created during Alma publishing.
|
10
12
|
# @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/
|
11
13
|
# Alma documentation for these added fields
|
12
14
|
# @param [MARC::Record] record
|
@@ -19,7 +21,7 @@ module PennMARC
|
|
19
21
|
# Retrieves the specific location from enriched marc 'itm' or 'hld' fields, giving priority to the item location
|
20
22
|
# over the holdings location. Returns item library location if available. Otherwise, returns holdings library
|
21
23
|
# location.
|
22
|
-
# {PennMARC::
|
24
|
+
# {PennMARC::Enriched} maps enriched marc fields and subfields created during Alma publishing.
|
23
25
|
# @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/
|
24
26
|
# Alma documentation for these added fields
|
25
27
|
# @param [MARC::Record] record
|
@@ -31,7 +33,7 @@ module PennMARC
|
|
31
33
|
|
32
34
|
# Base method to retrieve location data from enriched marc 'itm' or 'hld' fields, giving priority to the item
|
33
35
|
# location over the holdings location. Returns item location if available. Otherwise, returns holdings location.
|
34
|
-
# {PennMARC::
|
36
|
+
# {PennMARC::Enriched} maps enriched marc fields and subfields created during Alma publishing.
|
35
37
|
# @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/
|
36
38
|
# Alma documentation for these added fields
|
37
39
|
# @param [MARC::Record] record
|
@@ -61,7 +63,9 @@ module PennMARC
|
|
61
63
|
location_map[subfield.value.to_sym][display_value.to_sym]
|
62
64
|
}.flatten.compact_blank
|
63
65
|
}.uniq
|
64
|
-
|
66
|
+
if record.tags.intersect?([Enriched::Pub::ELEC_INVENTORY_TAG, Enriched::Api::ELEC_INVENTORY_TAG])
|
67
|
+
locations << ONLINE_LIBRARY
|
68
|
+
end
|
65
69
|
locations
|
66
70
|
end
|
67
71
|
|
@@ -82,17 +86,18 @@ module PennMARC
|
|
82
86
|
# Since item records may reflect locations more accurately, we use them if they exist;
|
83
87
|
# if not, we use the holdings.
|
84
88
|
|
85
|
-
tag = PennMARC::EnrichedMarc::TAG_HOLDING
|
86
|
-
subfield_code = PennMARC::EnrichedMarc::SUB_HOLDING_SHELVING_LOCATION
|
87
|
-
|
88
89
|
# if the record has an enriched item field present, use it
|
89
|
-
if field_defined?(record,
|
90
|
-
tag =
|
91
|
-
subfield_code =
|
92
|
-
#
|
93
|
-
elsif field_defined?(record,
|
94
|
-
tag =
|
95
|
-
subfield_code =
|
90
|
+
if field_defined?(record, Enriched::Pub::ITEM_TAG)
|
91
|
+
tag = Enriched::Pub::ITEM_TAG
|
92
|
+
subfield_code = Enriched::Pub::ITEM_CURRENT_LOCATION
|
93
|
+
# if the record has API inventory tags, use them
|
94
|
+
elsif field_defined?(record, Enriched::Api::PHYS_INVENTORY_TAG)
|
95
|
+
tag = Enriched::Api::PHYS_INVENTORY_TAG
|
96
|
+
subfield_code = Enriched::Api::PHYS_LOCATION_CODE
|
97
|
+
# otherwise use Pub holding tags
|
98
|
+
else
|
99
|
+
tag = Enriched::Pub::PHYS_INVENTORY_TAG
|
100
|
+
subfield_code = Enriched::Pub::PHYS_LOCATION_CODE
|
96
101
|
end
|
97
102
|
|
98
103
|
{ tag: tag, subfield_code: subfield_code }
|
@@ -16,11 +16,11 @@ module PennMARC
|
|
16
16
|
# @return [Array<String>]
|
17
17
|
def notes_show(record)
|
18
18
|
notes_fields = %w[500 502 504 515 518 525 533 540 550 580 586 588]
|
19
|
-
record.fields(notes_fields + ['880']).filter_map
|
19
|
+
record.fields(notes_fields + ['880']).filter_map { |field|
|
20
20
|
next if field.tag == '880' && subfield_value_not_in?(field, '6', notes_fields)
|
21
21
|
|
22
22
|
join_subfields(field, &subfield_not_in?(%w[5 6 8]))
|
23
|
-
|
23
|
+
}.uniq
|
24
24
|
end
|
25
25
|
|
26
26
|
# Retrieve local notes for display from fields {https://www.oclc.org/bibformats/en/5xx/561.html 561},
|
@@ -38,11 +38,12 @@ module PennMARC
|
|
38
38
|
|
39
39
|
additional_fields = %w[562 563 585 590]
|
40
40
|
|
41
|
-
local_notes + record.fields(additional_fields + ['880']).filter_map do |field|
|
41
|
+
notes = local_notes + record.fields(additional_fields + ['880']).filter_map do |field|
|
42
42
|
next if field.tag == '880' && subfield_value_not_in?(field, '6', additional_fields)
|
43
43
|
|
44
44
|
join_subfields(field, &subfield_not_in?(%w[5 6 8]))
|
45
45
|
end
|
46
|
+
notes.uniq
|
46
47
|
end
|
47
48
|
|
48
49
|
# Retrieve provenance notes for display from fields {https://www.oclc.org/bibformats/en/5xx/561.html 561} and
|
@@ -63,7 +64,8 @@ module PennMARC
|
|
63
64
|
|
64
65
|
join_subfields(field, &subfield_in?(%w[a]))
|
65
66
|
end
|
66
|
-
provenance_notes + prefixed_subject_and_alternate(record, 'PRO')
|
67
|
+
notes = provenance_notes + prefixed_subject_and_alternate(record, 'PRO')
|
68
|
+
notes.uniq
|
67
69
|
end
|
68
70
|
|
69
71
|
# Retrieve contents notes for display from fields {https://www.oclc.org/bibformats/en/5xx/505.html 505} and
|
@@ -75,16 +77,16 @@ module PennMARC
|
|
75
77
|
next if field.tag == '880' && subfield_value_not_in?(field, '6', %w[505])
|
76
78
|
|
77
79
|
join_subfields(field, &subfield_not_in?(%w[6 8])).split('--')
|
78
|
-
}.flatten
|
80
|
+
}.flatten.uniq
|
79
81
|
end
|
80
82
|
|
81
83
|
# Retrieve access restricted notes for display from field {https://www.oclc.org/bibformats/en/5xx/506.html 506}.
|
82
84
|
# @param [MARC::Record] record
|
83
85
|
# @return [Array<String>]
|
84
86
|
def access_restriction_show(record)
|
85
|
-
record.fields('506').filter_map
|
87
|
+
record.fields('506').filter_map { |field|
|
86
88
|
join_subfields(field, &subfield_not_in?(%w[5 6]))
|
87
|
-
|
89
|
+
}.uniq
|
88
90
|
end
|
89
91
|
|
90
92
|
# Retrieve finding aid notes for display from field {https://www.oclc.org/bibformats/en/5xx/555.html 555} and its
|
@@ -161,7 +163,7 @@ module PennMARC
|
|
161
163
|
|
162
164
|
sub3_and_other_subs(field, &subfield_in?(%w[a b c d e f]))
|
163
165
|
end
|
164
|
-
system_details_notes
|
166
|
+
system_details_notes.uniq
|
165
167
|
end
|
166
168
|
|
167
169
|
private
|
@@ -8,21 +8,21 @@ module PennMARC
|
|
8
8
|
# @param [MARC::Record] record
|
9
9
|
# @return [Array<String>]
|
10
10
|
def show(record)
|
11
|
-
get_264_or_880_fields(record, '0')
|
11
|
+
get_264_or_880_fields(record, '0').uniq
|
12
12
|
end
|
13
13
|
|
14
14
|
# Retrieve distribution values for display from {https://www.oclc.org/bibformats/en/2xx/264.html 264 field}.
|
15
15
|
# @param [MARC::Record] record
|
16
16
|
# @return [Array<String>]
|
17
17
|
def distribution_show(record)
|
18
|
-
get_264_or_880_fields(record, '2')
|
18
|
+
get_264_or_880_fields(record, '2').uniq
|
19
19
|
end
|
20
20
|
|
21
21
|
# Retrieve manufacture values for display from {https://www.oclc.org/bibformats/en/2xx/264.html 264 field}.
|
22
22
|
# @param [MARC::Record] record
|
23
23
|
# @return [Array<String>]
|
24
24
|
def manufacture_show(record)
|
25
|
-
get_264_or_880_fields(record, '3')
|
25
|
+
get_264_or_880_fields(record, '3').uniq
|
26
26
|
end
|
27
27
|
|
28
28
|
# Retrieve publication values. Return publication values from
|
@@ -60,7 +60,7 @@ module PennMARC
|
|
60
60
|
|
61
61
|
values += joined264
|
62
62
|
end
|
63
|
-
values.filter_map { |value| value&.strip }
|
63
|
+
values.filter_map { |value| value&.strip }.uniq
|
64
64
|
end
|
65
65
|
|
66
66
|
# Retrieve publication values for display from fields
|
@@ -68,7 +68,7 @@ module PennMARC
|
|
68
68
|
# {https://www.oclc.org/bibformats/en/2xx/260.html 260}-262 and their linked alternates,
|
69
69
|
# and {https://www.oclc.org/bibformats/en/2xx/264.html 264} and its linked alternate.
|
70
70
|
# @param [MARC::Record] record
|
71
|
-
# @return [
|
71
|
+
# @return [Array<String>]
|
72
72
|
def publication_show(record)
|
73
73
|
values = record.fields('245').first(1).flat_map { |field| subfield_values(field, 'f') }
|
74
74
|
|
@@ -86,22 +86,22 @@ module PennMARC
|
|
86
86
|
end
|
87
87
|
|
88
88
|
values += get_264_or_880_fields(record, '1')
|
89
|
-
values.compact_blank
|
89
|
+
values.compact_blank.uniq
|
90
90
|
end
|
91
91
|
|
92
92
|
# Retrieve place of publication for display from {https://www.oclc.org/bibformats/en/7xx/752.html 752 field} and
|
93
93
|
# its linked alternate.
|
94
94
|
# @note legacy version returns array of hash objects including data for display link
|
95
95
|
# @param [MARC::Record] record
|
96
|
-
# @return [
|
96
|
+
# @return [Array<String>]
|
97
97
|
def place_of_publication_show(record)
|
98
|
-
record.fields(%w[752 880]).filter_map
|
98
|
+
record.fields(%w[752 880]).filter_map { |field|
|
99
99
|
next if field.tag == '880' && subfield_values(field, '6').exclude?('752')
|
100
100
|
|
101
101
|
place = join_subfields(field, &subfield_not_in?(%w[6 8 e w]))
|
102
102
|
place_extra = join_subfields(field, &subfield_in?(%w[e w]))
|
103
103
|
"#{place} #{place_extra}"
|
104
|
-
|
104
|
+
}.uniq
|
105
105
|
end
|
106
106
|
|
107
107
|
private
|
@@ -14,11 +14,11 @@ module PennMARC
|
|
14
14
|
# in this field should be sufficient to locate host item record.
|
15
15
|
#
|
16
16
|
# @param [MARC::Record] record
|
17
|
-
# @return [Array] contained in values for display
|
17
|
+
# @return [Array<String>] contained in values for display
|
18
18
|
def contained_in_show(record)
|
19
|
-
record.fields('773').map
|
19
|
+
record.fields('773').map { |field|
|
20
20
|
join_subfields(field, &subfield_not_in?(%w[6 7 8 w]))
|
21
|
-
|
21
|
+
}.uniq
|
22
22
|
end
|
23
23
|
|
24
24
|
# Get "chronology" information from specially-prefixed 650 (subject) fields
|
@@ -56,7 +56,7 @@ module PennMARC
|
|
56
56
|
|
57
57
|
values_with_title_prefix(field, sf_exclude: %w[0 4 6 8 i], relator_map: relator_map)
|
58
58
|
end
|
59
|
-
values + record.fields('880').filter_map do |field|
|
59
|
+
relation_values = values + record.fields('880').filter_map do |field|
|
60
60
|
next if field.indicator2.present?
|
61
61
|
|
62
62
|
next unless subfield_value?(field, '6', /^(#{RELATED_WORK_FIELDS.join('|')})/)
|
@@ -65,6 +65,7 @@ module PennMARC
|
|
65
65
|
|
66
66
|
values_with_title_prefix(field, sf_exclude: %w[0 4 6 8 i], relator_map: relator_map)
|
67
67
|
end
|
68
|
+
relation_values.uniq
|
68
69
|
end
|
69
70
|
|
70
71
|
# Get "Contains" values from {CONTAINS_FIELDS} in the 7XX range. Must have indicator 2 value of 2 indicating an
|
@@ -72,20 +73,21 @@ module PennMARC
|
|
72
73
|
# values in sf 0, 5, 6, and 8.
|
73
74
|
# @param [MARC::Record] record
|
74
75
|
# @param [Hash] relator_map
|
75
|
-
# @return [Array]
|
76
|
+
# @return [Array<String>]
|
76
77
|
def contains_show(record, relator_map: Mappers.relator)
|
77
|
-
|
78
|
+
values = record.fields(CONTAINS_FIELDS).filter_map do |field|
|
78
79
|
next unless field.indicator2 == '2'
|
79
80
|
|
80
81
|
values_with_title_prefix(field, sf_exclude: %w[0 4 5 6 8 i], relator_map: relator_map)
|
81
82
|
end
|
82
|
-
|
83
|
+
contains_values = values + record.fields('880').filter_map do |field|
|
83
84
|
next unless field.indicator2 == '2'
|
84
85
|
|
85
86
|
next unless subfield_value?(field, '6', /^(#{CONTAINS_FIELDS.join('|')})/)
|
86
87
|
|
87
88
|
values_with_title_prefix(field, sf_include: %w[0 5 6 8 i])
|
88
89
|
end
|
90
|
+
contains_values.uniq
|
89
91
|
end
|
90
92
|
|
91
93
|
# Get "Constituent Unit" values from {https://www.oclc.org/bibformats/en/7xx/774.html MARC 774}. Include
|
@@ -93,10 +95,11 @@ module PennMARC
|
|
93
95
|
# @param [MARC::Record] record
|
94
96
|
# @return [Array]
|
95
97
|
def constituent_unit_show(record)
|
96
|
-
|
98
|
+
values = record.fields('774').filter_map do |field|
|
97
99
|
join_subfields(field, &subfield_in?(%w[i a s t]))
|
98
100
|
end
|
99
|
-
|
101
|
+
constituent_values = values + linked_alternate(record, '774', &subfield_in?(%w[i a s t]))
|
102
|
+
constituent_values.uniq
|
100
103
|
end
|
101
104
|
|
102
105
|
# Get "Has Supplement" values from {https://www.oclc.org/bibformats/en/7xx/770.html MARC 770}. Ignore
|
@@ -31,7 +31,8 @@ module PennMARC
|
|
31
31
|
end || []
|
32
32
|
|
33
33
|
values += remaining_show_entries(record, tags_present)
|
34
|
-
values + series_880_fields(record)
|
34
|
+
series_values = values + series_880_fields(record)
|
35
|
+
series_values.uniq
|
35
36
|
end
|
36
37
|
|
37
38
|
# Values from series fields for display.
|
@@ -75,7 +76,7 @@ module PennMARC
|
|
75
76
|
|
76
77
|
filtered_values.map { |v| v.gsub(/\(|\)/, '') }.join(' ')
|
77
78
|
end
|
78
|
-
values
|
79
|
+
values.uniq
|
79
80
|
end
|
80
81
|
|
81
82
|
# Information concerning the immediate predecessor of the target item (chronological relationship). When a note
|
@@ -83,9 +84,9 @@ module PennMARC
|
|
83
84
|
# indicator position for display.
|
84
85
|
# https://www.loc.gov/marc/bibliographic/bd780.html
|
85
86
|
# @param [MARC::Record] record
|
86
|
-
# @return [String] continues fields string
|
87
|
+
# @return [Array<String>] continues fields string
|
87
88
|
def get_continues_show(record)
|
88
|
-
continues(record, '780')
|
89
|
+
continues(record, '780').uniq
|
89
90
|
end
|
90
91
|
|
91
92
|
# Information concerning the immediate successor to the target item (chronological relationship). When a note is
|
@@ -93,9 +94,9 @@ module PennMARC
|
|
93
94
|
# position for display.
|
94
95
|
# https://www.loc.gov/marc/bibliographic/bd785.html
|
95
96
|
# @param [MARC::Record] record
|
96
|
-
# @return [String] continued by fields string
|
97
|
+
# @return [Array<String>] continued by fields string
|
97
98
|
def get_continued_by_show(record)
|
98
|
-
continues(record, '785')
|
99
|
+
continues(record, '785').uniq
|
99
100
|
end
|
100
101
|
|
101
102
|
private
|
@@ -127,7 +128,7 @@ module PennMARC
|
|
127
128
|
# @note added 2017/04/10: filter out 0 (authority record numbers) added by Alma
|
128
129
|
# @param [MARC::Record] record
|
129
130
|
# @param [String] first_tag
|
130
|
-
# @return [Array<
|
131
|
+
# @return [Array<String>] array of author show entry strings
|
131
132
|
def title_show_entries(record, first_tag)
|
132
133
|
record.fields(first_tag).map do |field|
|
133
134
|
series = join_subfields(field, &subfield_not_in?(%w[0 5 6 8 c e w v n]))
|
@@ -156,6 +157,7 @@ module PennMARC
|
|
156
157
|
# links that field to the 880 field. The data in field 880 may be in more than one script. This function exists
|
157
158
|
# because it differs than the tradition use of linked_alternate.
|
158
159
|
# @param [MARC::Record] record
|
160
|
+
# @return [Array<String>]
|
159
161
|
def series_880_fields(record)
|
160
162
|
record.fields('880').filter_map do |field|
|
161
163
|
next unless subfield_value?(field, '6', /^(800|810|811|830|400|410|411|440|490)/)
|
@@ -189,7 +191,7 @@ module PennMARC
|
|
189
191
|
# Get subfields from a given field (continues or continued_by).
|
190
192
|
# @param [MARC::Record] record
|
191
193
|
# @param [String] tag
|
192
|
-
# @return [String] joined subfields
|
194
|
+
# @return [Array<String>] joined subfields
|
193
195
|
def continues(record, tag)
|
194
196
|
record.fields.filter_map do |field|
|
195
197
|
next unless field.tag == tag || (field.tag == '880' && subfield_value?(field, '6', /^#{tag}/))
|