pennmarc 1.0.25 → 1.0.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +8 -9
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +2 -0
  5. data/README.md +16 -1
  6. data/lib/pennmarc/heading_control.rb +22 -4
  7. data/lib/pennmarc/helpers/creator.rb +139 -65
  8. data/lib/pennmarc/helpers/edition.rb +5 -3
  9. data/lib/pennmarc/helpers/note.rb +24 -19
  10. data/lib/pennmarc/helpers/production.rb +113 -20
  11. data/lib/pennmarc/helpers/subject.rb +32 -22
  12. data/lib/pennmarc/mappers.rb +22 -10
  13. data/lib/pennmarc/mappings/headings_override.yml +8 -0
  14. data/lib/pennmarc/mappings/headings_remove.yml +2 -0
  15. data/lib/pennmarc/test/marc_helpers.rb +83 -0
  16. data/lib/pennmarc/util.rb +98 -69
  17. data/lib/pennmarc/version.rb +1 -1
  18. data/lib/pennmarc.rb +7 -0
  19. data/pennmarc.gemspec +2 -1
  20. data/spec/lib/pennmarc/heading_control_spec.rb +45 -0
  21. data/spec/lib/pennmarc/helpers/access_spec.rb +0 -2
  22. data/spec/lib/pennmarc/helpers/citation_spec.rb +0 -2
  23. data/spec/lib/pennmarc/helpers/classification_spec.rb +0 -2
  24. data/spec/lib/pennmarc/helpers/creator_spec.rb +103 -2
  25. data/spec/lib/pennmarc/helpers/database_spec.rb +0 -2
  26. data/spec/lib/pennmarc/helpers/date_spec.rb +0 -2
  27. data/spec/lib/pennmarc/helpers/edition_spec.rb +4 -2
  28. data/spec/lib/pennmarc/helpers/format_spec.rb +0 -2
  29. data/spec/lib/pennmarc/helpers/genre_spec.rb +0 -2
  30. data/spec/lib/pennmarc/helpers/identifer_spec.rb +0 -2
  31. data/spec/lib/pennmarc/helpers/inventory_spec.rb +0 -2
  32. data/spec/lib/pennmarc/helpers/language_spec.rb +0 -2
  33. data/spec/lib/pennmarc/helpers/link_spec.rb +0 -2
  34. data/spec/lib/pennmarc/helpers/location_spec.rb +0 -2
  35. data/spec/lib/pennmarc/helpers/note_spec.rb +22 -29
  36. data/spec/lib/pennmarc/helpers/production_spec.rb +121 -22
  37. data/spec/lib/pennmarc/helpers/relation_spec.rb +0 -2
  38. data/spec/lib/pennmarc/helpers/series_spec.rb +0 -2
  39. data/spec/lib/pennmarc/helpers/subject_spec.rb +19 -2
  40. data/spec/lib/pennmarc/helpers/title_spec.rb +0 -2
  41. data/spec/lib/pennmarc/marc_util_spec.rb +0 -2
  42. data/spec/lib/pennmarc/parser_spec.rb +1 -1
  43. data/spec/spec_helper.rb +7 -0
  44. data/spec/support/fixture_helpers.rb +10 -0
  45. metadata +23 -3
  46. data/spec/support/marc_spec_helpers.rb +0 -85
@@ -12,7 +12,7 @@ module PennMARC
12
12
  # {https://www.oclc.org/bibformats/en/5xx/580.html 580}, {https://www.oclc.org/bibformats/en/5xx/586.html 586},
13
13
  # {https://www.oclc.org/bibformats/en/5xx/588.html 588}
14
14
  # and their linked alternates.
15
- # @param [MARC::Record] record
15
+ # @param record [MARC::Record]
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]
@@ -27,7 +27,7 @@ module PennMARC
27
27
  # {https://www.oclc.org/bibformats/en/5xx/562.html 562}, {https://www.oclc.org/bibformats/en/5xx/563.html 563},
28
28
  # {https://www.oclc.org/bibformats/en/5xx/585.html 585}, {https://www.oclc.org/bibformats/en/5xx/590.html 590}.
29
29
  # Includes linked alternates except for 561.
30
- # @param [MARC::Record] record
30
+ # @param record [MARC::Record]
31
31
  # @return [Array<String>]
32
32
  def local_notes_show(record)
33
33
  local_notes = record.fields('561').filter_map do |field|
@@ -50,7 +50,7 @@ module PennMARC
50
50
  # prefixed subject field {https://www.oclc.org/bibformats/en/6xx/650.html 650} and its linked alternate.
51
51
  # Ignores 561 fields with subfield 'a' values that begin with 'Athenaeum copy: ' and 650 fields where subfield 'a'
52
52
  # does not have the prefix 'PRO'.
53
- # @param [MARC::Record] record
53
+ # @param record [MARC::Record]
54
54
  # @return [Array<String>]
55
55
  def provenance_show(record)
56
56
  provenance_notes = record.fields(%w[561 880]).filter_map do |field|
@@ -68,20 +68,25 @@ module PennMARC
68
68
  notes.uniq
69
69
  end
70
70
 
71
- # Retrieve contents notes for display from fields {https://www.oclc.org/bibformats/en/5xx/505.html 505} and
72
- # its linked alternate.
73
- # @param [MARC::Record] record
71
+ # Retrieve contents notes for display from fields {https://www.oclc.org/bibformats/en/5xx/505.html 505} and, if
72
+ # include_vernacular param is true, its linked alternate. Used for display and searching.
73
+ # @param record [MARC::Record]
74
+ # @param with_alternate [Boolean]
74
75
  # @return [Array<String>]
75
- def contents_show(record)
76
+ def contents_values(record, with_alternate: true)
76
77
  record.fields(%w[505 880]).filter_map { |field|
77
- next if field.tag == '880' && no_subfield_value_matches?(field, '6', /^505/)
78
+ if field.tag == '880'
79
+ next unless with_alternate
80
+
81
+ next if no_subfield_value_matches?(field, '6', /^505/)
82
+ end
78
83
 
79
84
  join_subfields(field, &subfield_not_in?(%w[6 8])).split('--')
80
85
  }.flatten.uniq
81
86
  end
82
87
 
83
88
  # Retrieve access restricted notes for display from field {https://www.oclc.org/bibformats/en/5xx/506.html 506}.
84
- # @param [MARC::Record] record
89
+ # @param record [MARC::Record]
85
90
  # @return [Array<String>]
86
91
  def access_restriction_show(record)
87
92
  record.fields('506').filter_map { |field|
@@ -91,7 +96,7 @@ module PennMARC
91
96
 
92
97
  # Retrieve finding aid notes for display from field {https://www.oclc.org/bibformats/en/5xx/555.html 555} and its
93
98
  # linked alternate.
94
- # @param [MARC::Record] record
99
+ # @param record [MARC::Record]
95
100
  # @return [Array<String>]
96
101
  def finding_aid_show(record)
97
102
  datafield_and_linked_alternate(record, '555')
@@ -99,7 +104,7 @@ module PennMARC
99
104
 
100
105
  # Retrieve participant notes for display from field {https://www.oclc.org/bibformats/en/5xx/511.html 511} and its
101
106
  # linked alternate.
102
- # @param [MARC::Record] record
107
+ # @param record [MARC::Record]
103
108
  # @return [Array<String>]
104
109
  def participant_show(record)
105
110
  datafield_and_linked_alternate(record, '511')
@@ -107,7 +112,7 @@ module PennMARC
107
112
 
108
113
  # Retrieve credits notes for display from field {https://www.oclc.org/bibformats/en/5xx/508.html 508} and its
109
114
  # linked alternate.
110
- # @param [MARC::Record] record
115
+ # @param record [MARC::Record]
111
116
  # @return [Array<String>]
112
117
  def credits_show(record)
113
118
  datafield_and_linked_alternate(record, '508')
@@ -115,7 +120,7 @@ module PennMARC
115
120
 
116
121
  # Retrieve biography notes for display from field {https://www.oclc.org/bibformats/en/5xx/545.html 545} and its
117
122
  # linked alternate.
118
- # @param [MARC::Record] record
123
+ # @param record [MARC::Record]
119
124
  # @return [Array<String>]
120
125
  def biography_show(record)
121
126
  datafield_and_linked_alternate(record, '545')
@@ -123,14 +128,14 @@ module PennMARC
123
128
 
124
129
  # Retrieve summary notes for display from field {https://www.oclc.org/bibformats/en/5xx/520.html 520} and its
125
130
  # linked alternate.
126
- # @param [MARC::Record] record
131
+ # @param record [MARC::Record]
127
132
  # @return [Array<String>]
128
133
  def summary_show(record)
129
134
  datafield_and_linked_alternate(record, '520')
130
135
  end
131
136
 
132
137
  # Retrieve arrangement values for display from field field {https://www.oclc.org/bibformats/en/3xx/351.html 351}.
133
- # @param [MARC::Record] record
138
+ # @param record [MARC::Record]
134
139
  # @return [Array<String>]
135
140
  def arrangement_show(record)
136
141
  datafield_and_linked_alternate(record, '351')
@@ -140,7 +145,7 @@ module PennMARC
140
145
  # {https://www.oclc.org/bibformats/en/3xx/344.html 344}, {https://www.oclc.org/bibformats/en/3xx/345.html 345},
141
146
  # {https://www.oclc.org/bibformats/en/3xx/346.html 346}, {https://www.oclc.org/bibformats/en/3xx/347.html 347},
142
147
  # and their linked alternates.
143
- # @param [MARC::Record] record
148
+ # @param record [MARC::Record]
144
149
  # @return [Array<String>]
145
150
  def system_details_show(record)
146
151
  system_details_notes = record.fields(%w[538 880]).filter_map do |field|
@@ -167,7 +172,7 @@ module PennMARC
167
172
  end
168
173
 
169
174
  # Retrieve "With" notes for display from field {https://www.loc.gov/marc/bibliographic/bd501.html 501}
170
- # @param [Marc::Record] record
175
+ # @param record [Marc::Record]
171
176
  # @return [Array<String>]
172
177
  def bound_with_show(record)
173
178
  record.fields('501').filter_map { |field| join_subfields(field, &subfield_in?(['a'])).presence }.uniq
@@ -177,8 +182,8 @@ module PennMARC
177
182
 
178
183
  # For system details: extract subfield ǂ3 plus other subfields as specified by passed-in block. Pays special
179
184
  # attention to punctuation, joining subfield ǂ3 values with a colon-space (': ').
180
- # @param [MARC::DataField] field
181
- # @param [Proc] &
185
+ # @param field [MARC::DataField]
186
+ # @param & [Proc]
182
187
  # @return [String]
183
188
  def sub3_and_other_subs(field, &)
184
189
  sub3 = field.filter_map { |sf| trim_trailing('period', sf.value) if sf.code == '3' }.join(': ')
@@ -4,31 +4,47 @@ module PennMARC
4
4
  # Extracts data related to a resource's production, distribution, manufacture, and publication.
5
5
  class Production < Helper
6
6
  class << self
7
- # Retrieve production values for display from {https://www.oclc.org/bibformats/en/2xx/264.html 264 field}.
8
- # @param [MARC::Record] record
7
+ # Retrieve production values for display from {https://www.loc.gov/marc/bibliographic/bd264.html 264 field}.
8
+ # @param record [MARC::Record]
9
9
  # @return [Array<String>]
10
10
  def show(record)
11
11
  get_264_or_880_fields(record, '0').uniq
12
12
  end
13
13
 
14
- # Retrieve distribution values for display from {https://www.oclc.org/bibformats/en/2xx/264.html 264 field}.
15
- # @param [MARC::Record] record
14
+ # Retrieve production values for searching. Includes only
15
+ # {https://www.loc.gov/marc/bibliographic/bd260.html 260} and
16
+ # {https://www.loc.gov/marc/bibliographic/bd264.html 264}.
17
+ # @param record [MARC::Record]
18
+ # @return [Array<String>]
19
+ def search(record)
20
+ values = record.fields('260').filter_map do |field|
21
+ join_subfields(field, &subfield_in?(['b']))
22
+ end
23
+ values + record.fields('264').filter_map { |field|
24
+ next unless field.indicator2 == '1'
25
+
26
+ join_subfields(field, &subfield_in?(['b']))
27
+ }.uniq
28
+ end
29
+
30
+ # Retrieve distribution values for display from {https://www.loc.gov/marc/bibliographic/bd264.html 264 field}.
31
+ # @param record [MARC::Record]
16
32
  # @return [Array<String>]
17
33
  def distribution_show(record)
18
34
  get_264_or_880_fields(record, '2').uniq
19
35
  end
20
36
 
21
- # Retrieve manufacture values for display from {https://www.oclc.org/bibformats/en/2xx/264.html 264 field}.
22
- # @param [MARC::Record] record
37
+ # Retrieve manufacture values for display from {https://www.loc.gov/marc/bibliographic/bd264.html 264 field}.
38
+ # @param record [MARC::Record]
23
39
  # @return [Array<String>]
24
40
  def manufacture_show(record)
25
41
  get_264_or_880_fields(record, '3').uniq
26
42
  end
27
43
 
28
44
  # Retrieve publication values. Return publication values from
29
- # {https://www.oclc.org/bibformats/en/2xx/264.html 264 field} only if none found
30
- # {https://www.oclc.org/bibformats/en/2xx/260.html 260}-262 fields.
31
- # @param [MARC::Record] record
45
+ # {https://www.loc.gov/marc/bibliographic/bd264.html 264 field} only if none found
46
+ # {https://www.loc.gov/marc/bibliographic/bd260.html 260}-262 fields.
47
+ # @param record [MARC::Record]
32
48
  # @return [Array<String>]
33
49
  def publication_values(record)
34
50
  # first get inclusive dates
@@ -64,10 +80,10 @@ module PennMARC
64
80
  end
65
81
 
66
82
  # Retrieve publication values for display from fields
67
- # {https://www.oclc.org/bibformats/en/2xx/245.html 245},
68
- # {https://www.oclc.org/bibformats/en/2xx/260.html 260}-262 and their linked alternates,
69
- # and {https://www.oclc.org/bibformats/en/2xx/264.html 264} and its linked alternate.
70
- # @param [MARC::Record] record
83
+ # {https://www.loc.gov/marc/bibliographic/bd245.html 245},
84
+ # {https://www.loc.gov/marc/bibliographic/bd260.html 260}-262 and their linked alternates,
85
+ # and {https://www.loc.gov/marc/bibliographic/bd264.html 264} and its linked alternate.
86
+ # @param record [MARC::Record]
71
87
  # @return [Array<String>]
72
88
  def publication_show(record)
73
89
  values = record.fields('245').first(1).flat_map { |field| subfield_values(field, 'f') }
@@ -89,10 +105,49 @@ module PennMARC
89
105
  values.compact_blank.uniq
90
106
  end
91
107
 
92
- # Retrieve place of publication for display from {https://www.oclc.org/bibformats/en/7xx/752.html 752 field} and
108
+ # Retrieve publication values for citation
109
+ # {https://www.loc.gov/marc/bibliographic/bd245.html 245},
110
+ # {https://www.loc.gov/marc/bibliographic/bd260.html 260}-262 and their linked alternates,
111
+ # and {https://www.loc.gov/marc/bibliographic/bd264.html 264} and its linked alternate.
112
+ # @param [MARC::Record] record
113
+ # @param [Boolean] with_year: return results with publication year if true
114
+ # @return [Array<String>]
115
+ def publication_citation_show(record, with_year: true)
116
+ values = record.fields('245').first(1).flat_map { |field| subfield_values(field, 'f') }
117
+
118
+ subfields = with_year ? %w[6 8] : %w[6 8 c]
119
+ values += record.fields(%w[260 261 262]).first(1).map do |field|
120
+ join_subfields(field, &subfield_not_in?(subfields))
121
+ end
122
+
123
+ subfields = with_year ? %w[a b c] : %w[a b]
124
+ values += record.fields('264').filter_map do |field|
125
+ next unless field.indicator2 == '1'
126
+
127
+ join_subfields(field, &subfield_in?(subfields))
128
+ end
129
+
130
+ values.compact_blank.uniq
131
+ end
132
+
133
+ # Returns the place of publication for RIS
134
+ # @param [MARC::Record] record
135
+ # @return [Array<String>]
136
+ def publication_ris_place_of_pub(record)
137
+ get_publication_ris_values(record, 'a')
138
+ end
139
+
140
+ # Returns the publisher for RIS
141
+ # @param [MARC::Record] record
142
+ # @return [Array<String>]
143
+ def publication_ris_publisher(record)
144
+ get_publication_ris_values(record, 'b')
145
+ end
146
+
147
+ # Retrieve place of publication for display from {https://www.loc.gov/marc/bibliographic/bd752.html 752 field} and
93
148
  # its linked alternate.
94
149
  # @note legacy version returns array of hash objects including data for display link
95
- # @param [MARC::Record] record
150
+ # @param record [MARC::Record]
96
151
  # @return [Array<String>]
97
152
  def place_of_publication_show(record)
98
153
  record.fields(%w[752 880]).filter_map { |field|
@@ -104,13 +159,32 @@ module PennMARC
104
159
  }.uniq
105
160
  end
106
161
 
162
+ # Retrieves place of publication values for searching. Includes
163
+ # {https://www.loc.gov/marc/bibliographic/bd752.html 752} as well as sf a from
164
+ # {https://www.loc.gov/marc/bibliographic/bd260.html 260} and
165
+ # {https://www.loc.gov/marc/bibliographic/bd264.html 264} with an indicator2 of 1.
166
+ # @param record [MARC::Record]
167
+ # @return [Array<String>]
168
+ def place_of_publication_search(record)
169
+ values = record.fields('260').filter_map do |field|
170
+ join_subfields(field, &subfield_in?(['a']))
171
+ end
172
+ values += record.fields('264').filter_map do |field|
173
+ next unless field.indicator2 == '1'
174
+
175
+ join_subfields(field, &subfield_in?(['a']))
176
+ end
177
+ values + record.fields('752').filter_map { |field|
178
+ join_subfields(field, &subfield_in?(%w[a b c d f g h]))
179
+ }.uniq
180
+ end
181
+
107
182
  private
108
183
 
109
- # base method to retrieve production values from {https://www.oclc.org/bibformats/en/2xx/264.html 264 field} based
110
- # on indicator2.
111
- # distribution and manufacture share the same logic except for indicator2
112
- # @param [MARC::Record] record
113
- # @param [String] indicator2
184
+ # base method to retrieve production values from {https://www.loc.gov/marc/bibliographic/bd264.html 264 field}
185
+ # based on indicator2. "Distribution" and "manufacture" share the same logic except for indicator2.
186
+ # @param record [MARC::Record]
187
+ # @param indicator2 [String]
114
188
  # @return [Array<String>]
115
189
  def get_264_or_880_fields(record, indicator2)
116
190
  values = record.fields('264').filter_map do |field|
@@ -126,6 +200,25 @@ module PennMARC
126
200
  join_subfields(field, &subfield_in?(%w[a b c]))
127
201
  end
128
202
  end
203
+
204
+ # Returns the publication value of the given subfield
205
+ # @param [MARC::Record] record
206
+ # @param [String] subfield
207
+ def get_publication_ris_values(record, subfield)
208
+ values = record.fields('245').first(1).flat_map { |field| subfield_values(field, 'f') }
209
+
210
+ values += record.fields(%w[260 261 262]).first(1).map do |field|
211
+ join_subfields(field, &subfield_in?([subfield]))
212
+ end
213
+
214
+ values += record.fields('264').filter_map do |field|
215
+ next unless field.indicator2 == '1'
216
+
217
+ join_subfields(field, &subfield_in?([subfield]))
218
+ end
219
+
220
+ values.compact_blank.uniq
221
+ end
129
222
  end
130
223
  end
131
224
  end
@@ -62,67 +62,76 @@ module PennMARC
62
62
  #
63
63
  # @note this is ported mostly form MG's new-style Subject parsing
64
64
  # @param [MARC::Record] record
65
+ # @param [Boolean] override to remove undesirable terms or not
65
66
  # @return [Array<String>] array of all subject values for faceting
66
- def facet(record)
67
- subject_fields(record, type: :facet).filter_map { |field|
67
+ def facet(record, override: true)
68
+ values = subject_fields(record, type: :facet).filter_map { |field|
68
69
  term_hash = build_subject_hash(field)
69
70
  next if term_hash.blank? || term_hash[:count]&.zero?
70
71
 
71
72
  format_term type: :facet, term: term_hash
72
73
  }.uniq
74
+ override ? HeadingControl.term_override(values) : values
73
75
  end
74
76
 
75
77
  # All Subjects for display. This includes all {DISPLAY_TAGS} and {LOCAL_TAGS}. For tags that specify a source,
76
78
  # only those with an allowed source code (see ALLOWED_SOURCE_CODES) are included.
77
79
  #
78
80
  # @param [MARC::Record] record
81
+ # @param [Boolean] override to remove undesirable terms or not
79
82
  # @return [Array] array of all subject values for display
80
- def show(record)
81
- subject_fields(record, type: :all).filter_map { |field|
83
+ def show(record, override: true)
84
+ values = subject_fields(record, type: :all).filter_map { |field|
82
85
  term_hash = build_subject_hash(field)
83
86
  next if term_hash.blank? || term_hash[:count]&.zero?
84
87
 
85
88
  format_term type: :display, term: term_hash
86
89
  }.uniq
90
+ override ? HeadingControl.term_override(values) : values
87
91
  end
88
92
 
89
93
  # Get Subjects from "Children" ontology
90
94
  #
91
95
  # @param [MARC::Record] record
96
+ # @param [Boolean] override to remove undesirable terms or not
92
97
  # @return [Array] array of children's subject values for display
93
- def childrens_show(record)
94
- subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '1' })
95
- .filter_map { |field|
96
- term_hash = build_subject_hash(field)
97
- next if term_hash.blank? || term_hash[:count]&.zero?
98
-
99
- format_term type: :display, term: term_hash
100
- }.uniq
98
+ def childrens_show(record, override: true)
99
+ values = subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '1' })
100
+ .filter_map { |field|
101
+ term_hash = build_subject_hash(field)
102
+ next if term_hash.blank? || term_hash[:count]&.zero?
103
+
104
+ format_term type: :display, term: term_hash
105
+ }.uniq
106
+ override ? HeadingControl.term_override(values) : values
101
107
  end
102
108
 
103
109
  # Get Subjects from "MeSH" ontology
104
110
  #
105
111
  # @param [MARC::Record] record
112
+ # @param [Boolean] override to remove undesirable terms or not
106
113
  # @return [Array] array of MeSH subject values for display
107
- def medical_show(record)
108
- subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '2' })
109
- .filter_map { |field|
110
- term_hash = build_subject_hash(field)
111
- next if term_hash.blank? || term_hash[:count]&.zero?
112
-
113
- format_term type: :display, term: term_hash
114
- }.uniq
114
+ def medical_show(record, override: true)
115
+ values = subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '2' })
116
+ .filter_map { |field|
117
+ term_hash = build_subject_hash(field)
118
+ next if term_hash.blank? || term_hash[:count]&.zero?
119
+
120
+ format_term type: :display, term: term_hash
121
+ }.uniq
122
+ override ? HeadingControl.term_override(values) : values
115
123
  end
116
124
 
117
125
  # Get Subject values from {DISPLAY_TAGS} where indicator2 is 4 and {LOCAL_TAGS}. Do not include any values where
118
126
  # sf2 includes "penncoi" (Community of Interest).
119
127
  #
120
128
  # @param [MARC::Record] record
129
+ # @param [Boolean] override to remove undesirable terms
121
130
  # @return [Array] array of local subject values for display
122
- def local_show(record)
131
+ def local_show(record, override: true)
123
132
  local_fields = subject_fields(record, type: :display, options: { tags: DISPLAY_TAGS, indicator2: '4' }) +
124
133
  subject_fields(record, type: :local)
125
- local_fields.filter_map { |field|
134
+ values = local_fields.filter_map { |field|
126
135
  next if subfield_value?(field, '2', /penncoi/)
127
136
 
128
137
  term_hash = build_subject_hash(field)
@@ -130,6 +139,7 @@ module PennMARC
130
139
 
131
140
  format_term type: :display, term: term_hash
132
141
  }.uniq
142
+ override ? HeadingControl.term_override(values) : values
133
143
  end
134
144
 
135
145
  private
@@ -4,46 +4,58 @@ module PennMARC
4
4
  # reusable static mappers
5
5
  class Mappers
6
6
  class << self
7
- # @return [Hash]
7
+ # @return [Hash, nil]
8
+ def heading_overrides
9
+ @heading_overrides ||= load_map('headings_override.yml', symbolize_names: false)
10
+ end
11
+
12
+ # @return [Hash, nil]
13
+ def headings_to_remove
14
+ @headings_to_remove ||= load_map('headings_remove.yml', symbolize_names: false)
15
+ end
16
+
17
+ # @return [Hash, nil]
8
18
  def iso_639_2_language
9
19
  @iso_639_2_language ||= load_map('iso639-2-languages.yml')
10
20
  end
11
21
 
22
+ # @return [Hash, nil]
12
23
  def iso_639_3_language
13
24
  @iso_639_3_language ||= load_map('iso639-3-languages.yml')
14
25
  end
15
26
 
16
- # @return [Hash]
27
+ # @return [Hash, nil]
17
28
  def location
18
29
  @location ||= load_map('locations.yml')
19
30
  end
20
31
 
21
- # @return [Hash]
32
+ # @return [Hash, nil]
22
33
  def location_overrides
23
34
  @location_overrides ||= load_map('location_overrides.yml')
24
35
  end
25
36
 
26
- # @return [Hash]
37
+ # @return [Hash, nil]
27
38
  def relator
28
39
  @relator ||= load_map('relator.yml')
29
40
  end
30
41
 
31
- # @return [Hash]
42
+ # @return [Hash, nil]
32
43
  def loc_classification
33
44
  @loc_classification ||= load_map('loc_classification.yml')
34
45
  end
35
46
 
36
- # @return [Hash]
47
+ # @return [Hash, nil]
37
48
  def dewey_classification
38
49
  @dewey_classification ||= load_map('dewey_classification.yml')
39
50
  end
40
51
 
41
- # @param [String] filename of mapping file in config directory, with file extension
42
- # @return [Hash] mapping as hash
43
- def load_map(filename)
52
+ # @param filename [String] name of mapping file in config directory, with file extension
53
+ # @param symbolize_names [Boolean] whether or not to symbolize keys in returned hash
54
+ # @return [Hash, nil] mapping as hash
55
+ def load_map(filename, symbolize_names: true)
44
56
  puts { "Loading #{filename}" }
45
57
  YAML.safe_load(File.read(File.join(File.expand_path(__dir__), 'mappings', filename)),
46
- symbolize_names: true)
58
+ symbolize_names: symbolize_names)
47
59
  end
48
60
  end
49
61
  end
@@ -0,0 +1,8 @@
1
+ Aliens: Noncitizens
2
+ "Alien criminals": Noncitizen criminals
3
+ "Alien detention centers": Immigrant detention centers
4
+ "Alien labor": Foreign workers
5
+ "Alien property": Foreign-owned property
6
+ Gypsies: Romanies
7
+ "Illegal Alien Children": Undocumented immigrant children
8
+ "Illegal Aliens": Undocumented immigrants
@@ -0,0 +1,2 @@
1
+ - Jewish Question
2
+ - Yellow Peril
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nokogiri'
4
+ require 'marc'
5
+
6
+ module PennMARC
7
+ module Test
8
+ # Helper methods for use in constructing MARC objects for testing
9
+ module MarcHelpers
10
+ # Return a MARC::XMLReader that will parse a given file and return MARC::Record objects
11
+ # @param [String] filename of MARCXML fixture
12
+ # @return [MARC::Record, NilClass]
13
+ def record_from(filename)
14
+ MARC::XMLReader.new(marc_xml_path(filename)).first
15
+ end
16
+
17
+ # Create an isolated MARC::Subfield object for use in specs or as part of a MARC::Field
18
+ # @param [String] code
19
+ # @param [String] value
20
+ # @return [MARC::Subfield]
21
+ def marc_subfield(code, value)
22
+ MARC::Subfield.new code.to_s, value
23
+ end
24
+
25
+ # Return a new ControlField (000-009)
26
+ # @param [String] tag
27
+ # @param [String] value
28
+ # @return [MARC::ControlField]
29
+ def marc_control_field(tag:, value:)
30
+ MARC::ControlField.new tag, value
31
+ end
32
+
33
+ # Create an isolated MARC::DataField object for use in specs
34
+ # Can pass in tag, indicators and subfields (using simple hash structure). E.g.,
35
+ # marc_field(tag: '650', indicator2: '7'),
36
+ # subfields: { a: 'Tax planning',
37
+ # m: ['Multiple', 'Subfields']
38
+ # z: 'United States.',
39
+ # '0': http://id.loc.gov/authorities/subjects/sh2008112546 }
40
+ # )
41
+ # @param [String (frozen)] tag MARC tag, e.g., 001, 665
42
+ # @param [String (frozen)] indicator1 MARC indicator, e.g., 0
43
+ # @param [String (frozen)] indicator2
44
+ # @param [Hash] subfields hash of subfield values as code => value or code => [value, value]
45
+ # @return [MARC::DataField]
46
+ def marc_field(tag: 'TST', indicator1: ' ', indicator2: ' ', subfields: {})
47
+ subfield_objects = subfields.each_with_object([]) do |(code, value), array|
48
+ Array.wrap(value).map { |v| array << marc_subfield(code, v) }
49
+ end
50
+ MARC::DataField.new tag, indicator1, indicator2, *subfield_objects
51
+ end
52
+
53
+ # Return a MARC::Record containing passed in DataFields
54
+ # @param [Array<MARC::DataField>] fields
55
+ # @param [String, nil] leader
56
+ # @return [MARC::Record]
57
+ def marc_record(fields: [], leader: nil)
58
+ record = MARC::Record.new
59
+ fields.each { |field| record << field }
60
+ record.leader = leader if leader
61
+ record
62
+ end
63
+
64
+ # Mock map for location lookup using Location helper
65
+ # The location codes :dent and :stor are the two outermost keys
66
+ # :specific_location, :library, :display are the inner keys that store location values
67
+ # @example
68
+ # location_map[:stor][:library] #=> 'LIBRA'
69
+ # @return [Hash]
70
+ def location_map
71
+ { dent: { specific_location: 'Levy Dental Medicine Library - Stacks',
72
+ library: ['Health Sciences Libraries', 'Levy Dental Medicine Library'],
73
+ display: 'Levy Dental Medicine Library - Stacks' },
74
+ stor: { specific_location: 'LIBRA',
75
+ library: 'LIBRA',
76
+ display: 'LIBRA' },
77
+ vanp: { specific_location: 'Van Pelt - Stacks',
78
+ library: 'Van Pelt-Dietrich Library Center',
79
+ display: 'Van Pelt Library' } }
80
+ end
81
+ end
82
+ end
83
+ end