traject_umich_format 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a7113842cf09274c14d8075df5530382af465333
4
+ data.tar.gz: 5fa241fa4d01b9b43ca3afa25eb4f58f6b5e3ea4
5
+ SHA512:
6
+ metadata.gz: 10293427c26a8821321d51e3dfa616aba7651dadd2f3e03c9063b998e28db4938470e74faed48a98a25ecd31763e723fc10a6bb252e0ae5f7a7bcf51ce98191a
7
+ data.tar.gz: 84d6dead962758738a725b522137862aa5b7dc648e03d3a793380bf11f3d26b37407881f7541f7d29801d454339e195f950d6458b35f08056d3193b35e4837e6
data/.document ADDED
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.md
3
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ Gemfile.lock
2
+ doc/
3
+ pkg/
4
+ vendor/cache/*.gem
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - jruby-19mode
4
+ jdk:
5
+ - openjdk7
6
+ - openjdk6
7
+ bundler_args: --without debug
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --title "traject_umich_format Documentation" --protected
data/ChangeLog.md ADDED
@@ -0,0 +1,4 @@
1
+ ### 0.1.0 / 2013-10-07
2
+
3
+ * Initial release:
4
+
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'traject'
5
+ gem 'yell'
6
+
7
+ group :development do
8
+ gem 'kramdown'
9
+ gem 'minitest'
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Bill Dueber
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # traject_umich_format
2
+ * [Homepage](https://github.com/billdueber/traject_umich_format#readme)
3
+ * [Issues](https://github.com/billdueber/traject_umich_format/issues)
4
+ * [Documentation](http://rubydoc.info/gems/traject_umich_format/frames)
5
+ * [Email](mailto:bill at dueber.com)
6
+
7
+
8
+ Opnionated macros to provide bibliographic format/types based on information in the
9
+ MARC bibliographic record, in the manner of the University of Michigan
10
+ University Library.
11
+
12
+ We at UMich use ths to populate facets in our discovery layer.
13
+
14
+
15
+ *Note* This code is designed to be used with the [traject](http://github.com/jrochkind/traject)
16
+ indexing system, and relies on it to run.
17
+
18
+
19
+ ## Description
20
+
21
+ Looks at the values in a MARC record to determine a format and set of types for the object represented by the record.
22
+
23
+ ### Bib Formats
24
+
25
+ Each record is assigned exactly one format. Raw, untranslated codes are provided in brackets.
26
+
27
+ * Book [BK]
28
+ * Data File [CF]
29
+ * Visual Material [VM]
30
+ * Music [MU]
31
+ * Map [MP]
32
+ * Serial [SE]
33
+ * Mixed Materials [MX]
34
+ * No match [XX]
35
+
36
+ ### Bib Types
37
+
38
+ Additionally, each record may have one or more of the following more specific types associated with it.
39
+
40
+ * Archive [MV]
41
+ * Audio (music) [RM]
42
+ * Audio (spoken word) [RS]
43
+ * Audio [RU]
44
+ * Audio CD [RC]
45
+ * Audio LP [RL]
46
+ * Biography [BI]
47
+ * CDROM [CR]
48
+ * Conference [XC]
49
+ * Dictionaries [DI]
50
+ * Directories [DR]
51
+ * Encyclopedias [EN]
52
+ * Journal [AJ]
53
+ * Manuscript [MW]
54
+ * Maps-Atlas [MN]
55
+ * Microform [WM]
56
+ * Motion Picture [VL]
57
+ * Music [MU]
58
+ * Musical Score [MS]
59
+ * Newspaper [AN]
60
+ * Photographs & Pictorial Works [PP]
61
+ * Serial [SX]
62
+ * Software [CS]
63
+ * Statistics [XS]
64
+ * Unknown [XX]
65
+ * Video (Blu-ray) [VB]
66
+ * Video (DVD) [VD]
67
+ * Video (VHS) [VH]
68
+ * Video Games [VG]
69
+
70
+
71
+ ## A sample traject configuration file
72
+
73
+ ```ruby
74
+ require 'traject'
75
+ require 'traject_umich_format'
76
+ extend Traject::UMichFormat::Macros
77
+
78
+ to_field 'id', extract_marc('001', :first=>true)
79
+ to_field 'bib_format', umich_format
80
+ to_field 'bib_types', umich_types
81
+ to_field 'bib_formats_and_types', umich_format_and_types
82
+
83
+ ```
84
+
85
+
86
+ ## Install
87
+
88
+ $ gem install traject_umich_format
89
+
90
+ ## Copyright
91
+
92
+ Copyright (c) 2013 Bill Dueber
93
+
94
+ See [LICENSE.txt](LICENSE.txt) for details.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit -1
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+
23
+ require "bundler/gem_tasks"
24
+
25
+ require 'yard'
26
+ YARD::Rake::YardocTask.new
27
+ task :doc => :yard
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new do |t|
31
+ t.libs.push 'lib'
32
+ t.libs.push 'spec'
33
+ t.test_files = Dir.glob('spec/**/*_spec.rb')
34
+ end
35
+
36
+ task :spec => :test
37
+
38
+ task(:default => :test)
@@ -0,0 +1,40 @@
1
+ require 'traject/umich_format/version'
2
+ require 'traject/umich_format/bib_format'
3
+ require 'traject/umich_format/bib_types'
4
+ require 'traject/umich_format/macros'
5
+
6
+ # Encapsulates logic that uses University of Michigan University Library
7
+ # rules to determine both bib format (book, serial, visual
8
+ # material, etc.) and type, a more expansive list including both format
9
+ # (blu-ray, microform) and more semantic categories (bibliography,
10
+ # conference)
11
+
12
+ class Traject::UMichFormat
13
+
14
+
15
+ # @!attribute [r] record
16
+ # The record passed into the constructor
17
+ # @!attribute [r] bib_format
18
+ # The bib format code as computed from the passed record
19
+ # @!attribute [r] types
20
+ # A (possibly empty) array of type codes as computed from record data
21
+ attr_reader :bib_format, :record, :types
22
+
23
+ # Construct a Formats object from the given record, calcuclating
24
+ # the bib_format and types
25
+ #
26
+ # @param [MARC::Record] record
27
+ def initialize(marc_record)
28
+ @record = marc_record
29
+ @bib_format = BibFormat.new(record).code
30
+ @types = BibTypes.new(@bib_format, record).codes
31
+ end
32
+
33
+ def format_and_types
34
+ types = @types.dup
35
+ types.unshift bib_format
36
+ types
37
+ end
38
+
39
+ end
40
+
@@ -0,0 +1,62 @@
1
+ # given a record, find the bib_format code
2
+ class Traject::UMichFormat::BibFormat
3
+
4
+ attr_reader :code
5
+
6
+ # Determine the bib format code
7
+ #
8
+ # @param [MARC::Record] record The record to test
9
+
10
+ def initialize(record)
11
+ ldr = record.leader
12
+
13
+ type = ldr[6]
14
+ lev = ldr[7]
15
+ @code = self.determine_bib_code(type, lev)
16
+ end
17
+
18
+ def determine_bib_code(type, lev)
19
+ return 'BK' if bibformat_bk(type, lev)
20
+ return "CF" if bibformat_cf(type, lev)
21
+ return "VM" if bibformat_vm(type, lev)
22
+ return "MU" if bibformat_mu(type, lev)
23
+ return "MP" if bibformat_mp(type, lev)
24
+ return "SE" if bibformat_se(type, lev)
25
+ return "MX" if bibformat_mx(type, lev)
26
+
27
+ # Extra check for serial
28
+ return "SE" if lev == 's'
29
+
30
+ # No match
31
+ return 'XX'
32
+
33
+ end
34
+
35
+ def bibformat_bk(type, lev)
36
+ %w[a t].include?(type) && %w[a c d m].include?(lev)
37
+ end
38
+
39
+ def bibformat_cf(type, lev)
40
+ (type == 'm') && %w[a b c d m s].include?(lev)
41
+ end
42
+
43
+ def bibformat_vm(type, lev)
44
+ %w[g k o r].include?(type) && %w[a b c d m s].include?(lev)
45
+ end
46
+
47
+ def bibformat_mu(type, lev)
48
+ %w[c d i j].include?(type) && %w[a b c d m s].include?(lev)
49
+ end
50
+
51
+ def bibformat_mp(type, lev)
52
+ %w[e f].include?(type) && %w[a b c d m s].include?(lev)
53
+ end
54
+
55
+ def bibformat_se(type, lev)
56
+ (type == 'a') && %w[b s i].include?(lev)
57
+ end
58
+
59
+ def bibformat_mx(type, lev)
60
+ %w[b p].include?(type) && %w[a b c d m s].include?(lev)
61
+ end
62
+ end
@@ -0,0 +1,540 @@
1
+ require 'traject'
2
+ require 'traject/umich_format/xv6xx'
3
+
4
+
5
+ # Determine the "types" of material represented by the bib record.
6
+ # The comments below come from the Ex Libris Aleph system and represent
7
+ # the logic used within it to determine types. This file is based
8
+ # on the logic use at the University of Michigan
9
+
10
+ class Traject::UMichFormat::BibTypes
11
+
12
+ attr_reader :codes, :bib_format, :record
13
+
14
+ def initialize(bib_format, record)
15
+ @bib_format = bib_format
16
+ @record = record
17
+ # Memoize values, since many of them are used several times
18
+ @spec_vals = Hash.new { |h, spec_string| h[spec_string] = Traject::MarcExtractor.new(spec_string).extract(@record) }
19
+
20
+ # Need these a lot -- the sub x and v from any 6XX field
21
+ @xv6XX = Traject::UMichFormat::XV6XX.new(@record)
22
+
23
+ @codes = []
24
+ @codes.concat self.video_types
25
+ @codes.concat self.audio_types
26
+ @codes.concat self.microform_types
27
+ @codes.concat self.musical_score_types
28
+ @codes.concat self.map_types
29
+ @codes.concat self.serial_types
30
+ @codes.concat self.mixed_types
31
+ @codes.concat self.software_types
32
+ @codes.concat self.statistics_types
33
+ @codes.concat self.conference_types
34
+ @codes.concat self.biography_types
35
+ @codes.concat self.reference_types
36
+ @codes.concat self.pp_types
37
+ @codes.concat self.videogame_types
38
+
39
+ @codes.uniq!
40
+ @codes.compact!
41
+
42
+ end
43
+
44
+ # Provide memoized values for on-the-fly created MarcExtractor
45
+ # objects
46
+ #
47
+ # @param [String] spec_string A Traject::MarcExtractor-compatible spec string
48
+ # @return [Array<String>] The strings in the specified subfields/byterange/whatever
49
+ def [](spec_string)
50
+ @spec_vals[spec_string]
51
+ end
52
+
53
+
54
+ ### Video stuff
55
+
56
+ # TYP VB Video (Blu-ray) 538## a MATCH *Blu-ray*
57
+ # TYP VB Video (Blu-ray) 007 F00-05 MATCH v???s
58
+ # TYP VB Video (Blu-ray) 250## a MATCH *Blu-ray*
59
+ # TYP VB Video (Blu-ray) 852## j MATCH video-b*
60
+ # TYP VB Video (Blu-ray) 852## j MATCH bd-rom*
61
+ #
62
+ # TYP VD Video (DVD) 538## a MATCH DVD*
63
+ # TYP VD Video (DVD) 007 F04-01 EQUAL v
64
+ # 007 F00-01 EQUAL v
65
+ # TYP VD Video (DVD) 007 F04-01 EQUAL v
66
+ # 008 F33-01 EQUAL v
67
+ # !
68
+ # ! Visual material: vHs
69
+ # TYP VH Video (VHS) 538## a MATCH VHS*
70
+ # TYP VH Video (VHS) 007 F04-01 EQUAL b
71
+ # 007 F00-01 EQUAL v
72
+ # TYP VH Video (VHS) 007 F04-01 EQUAL b
73
+ # 008 F33-01 EQUAL v
74
+ # !
75
+ # ! Visual materials: fiLm/video
76
+ # TYP VL Motion Picture 007 F00-01 EQUAL m
77
+ # TYP VL Motion Picture FMT F00-02 EQUAL VM
78
+ # 008 F33-01 EQUAL m
79
+
80
+ def video_types
81
+ types = []
82
+
83
+ types << 'VB' if self['538a:250a'].grep(/blu-ray/i).size > 0
84
+ types << 'VB' if self['007[0-5]'].grep(/v...s/i).size > 0
85
+ types << 'VB' if self['852j'].grep(/\A(?:bd-rom|video-b)/i).size > 0
86
+
87
+
88
+ types << 'VD' if self['007[4]'].include?('v') &&
89
+ (
90
+ self['007[0]'].include?('v') ||
91
+ self['008[33]'].include?('v')
92
+ )
93
+
94
+ types << 'VD' if self['538a'].grep(/\Advd/i).size > 0
95
+
96
+ types << 'VH' if self['538a'].grep(/\AVHS/i).size > 0
97
+
98
+ types << 'VH' if self['007[4]'].include?('b') &&
99
+ (
100
+ self['007[0]'].include?('v') ||
101
+ self['008[33]'].include?('v')
102
+ )
103
+
104
+ types << 'VL' if self['007[0]'].include?('m')
105
+ types << 'VL' if (self.bib_format == 'VM') && self['008[33]'].include?('m')
106
+
107
+ return types
108
+ end
109
+
110
+
111
+ # Audio/music
112
+ # ! Recording: Compact disc
113
+ # TYP RC Audio CD LDR F06-01 EQUAL [i,j]
114
+ # FMT F00-02 EQUAL MU
115
+ # 007 F01-01 EQUAL d
116
+ # 007 F12-01 EQUAL e
117
+ # TYP RC Audio CD 8524 j MATCH CD*
118
+ # 8524 b EQUAL MUSIC
119
+ # !
120
+ # ! Recording: LP record
121
+ # TYP RL Audio LP LDR F06-01 EQUAL [i,j]
122
+ # FMT F00-02 EQUAL MU
123
+ # 007 F01-01 EQUAL d
124
+ # 300 a MATCH *SOUND DISC*
125
+ # 300 b MATCH *33 1/3 RPM*
126
+ #
127
+ # TYP RL Audio LP 8524 j MATCH LP*
128
+ # 8524 c EQUAL MUSI
129
+ # TYP RL Audio LP 8524 j MATCH LP*
130
+ # 8524 b EQUAL MUSIC
131
+ # !
132
+ # ! Recording: Music
133
+ # TYP RM Audio (music) LDR F06-01 EQUAL j
134
+ # FMT F00-02 EQUAL MU
135
+ # !
136
+ # ! Recording: Spoken word
137
+ # TYP RS Audio (spoken word) LDR F06-01 EQUAL i
138
+ # FMT F00-02 EQUAL MU
139
+ # !
140
+ # ! Recording: Undefined
141
+ # TYP RU Audio LDR F06-01 EQUAL [i,j]
142
+ # FMT F00-02 EQUAL MU
143
+ #
144
+
145
+ def audio_types
146
+ ldr6 = record.leader[6]
147
+
148
+ types = []
149
+
150
+ # Get the 8524* fields
151
+ f8524 = record.fields('852').select{|f| f.indicator1 == '4'}
152
+
153
+ # RC
154
+ types << 'RC' if %w[i j].include?(ldr6) &&
155
+ (bib_format == 'MU') &&
156
+ self['007[1]'].include?('d') &&
157
+ self['007[12]'].include?('e')
158
+
159
+ f8524.each do |f|
160
+ if (f['b'].upcase == 'MUSIC') && (f['j'] =~ /\ACD/i)
161
+ types << 'RC'
162
+ break
163
+ end
164
+ end
165
+
166
+ # RL
167
+
168
+ if (bib_format == 'MU') && %w[i j].include?(ldr6) && self['007[1]'].include?('d')
169
+ record.fields('300').each do |f|
170
+ if (f['a'] =~ /SOUND DISC/i) && (f['b'] =~ /33 1\/3 RPM/i)
171
+ types << 'RL'
172
+ break
173
+ end
174
+ end
175
+ end
176
+
177
+
178
+ f8524.each do |f|
179
+ if (f['j'] =~ /\ALP/i) &&
180
+ ((f['b'].upcase == 'MUSIC') || (f['c'].upcase == 'MUSI'))
181
+ types << 'RL'
182
+ break
183
+ end
184
+ end
185
+
186
+ # RM
187
+ types << 'RM' if (ldr6 == 'j') && (bib_format == 'MU')
188
+
189
+ # RS
190
+ types << 'RS' if (ldr6 == 'i') && (bib_format == 'MU')
191
+
192
+ # RU
193
+ types << 'RU' if %w[i j].include?(ldr6) && (bib_format == 'MU')
194
+
195
+ return types
196
+ end
197
+
198
+
199
+ # Microform
200
+ # ! MicroForms
201
+ # TYP WM Microform FMT F00-02 EQUAL BK
202
+ # 008 F23-01 EQUAL [a,b,c]
203
+ # TYP WM Microform FMT F00-02 EQUAL MU
204
+ # 008 F23-01 EQUAL [a,b,c]
205
+ # TYP WM Microform FMT F00-02 EQUAL SE
206
+ # 008 F23-01 EQUAL [a,b,c]
207
+ # TYP WM Microform FMT F00-02 EQUAL MX
208
+ # 008 F23-01 EQUAL [a,b,c]
209
+
210
+ # TYP WM Microform 245## h MATCH *micro*
211
+
212
+ # TYP WM Microform FMT F00-02 EQUAL MP
213
+ # 008 F29-01 EQUAL [a,b,c]
214
+ # TYP WM Microform FMT F00-02 EQUAL VM
215
+ # 008 F29-01 EQUAL [a,b,c]
216
+
217
+
218
+ def microform_types
219
+ return [] unless record['008']
220
+ types = ['WM']
221
+ f8_23 = record['008'].value[23]
222
+ return types if %w[BK MU SE MX].include?(bib_format) && %w[a b c].include?(f8_23)
223
+
224
+ f8_29 = record['008'].value[29]
225
+ return types if %w[MP VM].include?(bib_format) && %w[a b c].include?(f8_29)
226
+
227
+ return types if record['245'] && (record['245']['h'] =~ /micro/i)
228
+
229
+ # Nope. Not microform
230
+ return []
231
+ end
232
+
233
+
234
+ # ! Musical Score
235
+ # TYP MS Musical Score LDR F06-01 EQUAL [c,d]
236
+
237
+ def musical_score_types
238
+ types = []
239
+ types << 'MS' if %w[c d].include?(record.leader[6])
240
+ return types
241
+ end
242
+
243
+
244
+ # ! Maps: Numerous
245
+ # TYP MN Maps-Atlas FMT F00-02 EQUAL MP
246
+ # TYP MN Maps-Atlas LDR F06-01 EQUAL [e,f]
247
+ # TYP MN Maps-Atlas 007 F00-01 EQUAL a
248
+ # !
249
+ # ! Maps: One (commented out as per Judy Ahronheim as this TYP duplicates MN)
250
+ # !TYP MO Map FMT F00-02 EQUAL MP
251
+ # !TYP MO Map 007 F00-01 EQUAL a
252
+
253
+
254
+ def map_types
255
+ types = []
256
+ if (bib_format == 'MP') || %w[e f].include?(record.leader[6]) || self['007[0]'].include?('a')
257
+ types << 'MN'
258
+ end
259
+ return types
260
+ end
261
+
262
+
263
+ # Serials
264
+ # ! serial: A Journal
265
+ # TYP AJ Journal FMT F00-02 EQUAL SE
266
+ # 008 F21-01 EQUAL p
267
+ # 008 F22-01 EQUAL [^,a,b,c,d,f,g,h,i,s,x,z,|]
268
+ # 008 F29-01 EQUAL [0,|]
269
+ # TYP AJ Journal FMT F00-02 EQUAL SE
270
+ # 008 F21-01 EQUAL [^,d,l,m,p,w,|]
271
+ # 008 F22-01 EQUAL [^,a,b,c,d,f,g,h,i,s,x,z,|]
272
+ # 008 F24-01 EQUAL [a,b,g,m,n,o,p,s,w,x,y,^]
273
+ # 008 F29-01 EQUAL [0,|]
274
+ # !
275
+ # ! serial: A Newspaper
276
+ # TYP AN Newspaper FMT F00-02 EQUAL SE
277
+ # 008 F21-01 EQUAL n
278
+ # TYP AN Newspaper FMT F00-02 EQUAL SE
279
+ # 008 F22-01 EQUAL e
280
+ #
281
+ # ! serial: All, including serials with other FMT codes
282
+ # TYP SX All Serials LDR F07-01 EQUAL [b,s]
283
+
284
+
285
+ # Wrap it all up in serial_types
286
+ def serial_types
287
+ types = []
288
+ types << 'SX' if %w[b s].include?(record.leader[7])
289
+ types.concat journal_types
290
+ types.concat newspaper_types
291
+ end
292
+
293
+
294
+ def journal_types
295
+
296
+ types = []
297
+ # gotta be SE and have a 008
298
+ return types unless (bib_format == 'SE') && record['008']
299
+
300
+
301
+ # We need lots of chars from the 008
302
+ f8 = record['008'].value
303
+
304
+ if (f8[21] == 'p') &&
305
+ [' ','a','b','c','d','f','g','h','i','s','x','z','|'].include?(f8[22]) &&
306
+ ['0', '|'].include?(f8[29])
307
+ types << 'AJ'
308
+ end
309
+
310
+ if [' ','d','l','m','p','w','|'].include?(f8[21]) &&
311
+ [' ','a','b','c','d','f','g','h','i','s','x','z','|'].include?(f8[22]) &&
312
+ ['a','b','g','m','n','o','p','s','w','x','y',' '].include?(f8[24]) &&
313
+ ['0', '|'].include?(f8[29])
314
+ types << 'AJ'
315
+ end
316
+
317
+ return types
318
+ end
319
+
320
+ def newspaper_types
321
+ types = []
322
+ types << 'AN' if (bib_format == 'SE') && record['008'] &&
323
+ ((record['008'].value[21] == 'n') || (record['008'].value[22] == 'e'))
324
+ return types
325
+ end
326
+
327
+
328
+ # ! Mixed material: archi-V-e
329
+ # TYP MV Archive FMT F00-02 EQUAL MX
330
+ # TYP MV Archive LDR F08-01 EQUAL a
331
+ # !
332
+ # ! Mixed material: manuscript
333
+ # TYP MW Manuscript LDR F06-01 EQUAL [d,f,p,t]
334
+
335
+ def mixed_types
336
+ types = []
337
+ types << 'MV' if (bib_format == 'MX') || (record.leader[8] == 'a')
338
+ types << 'MW' if %w[d f p t].include?(record.leader[6])
339
+ return types
340
+ end
341
+
342
+ # TYP CR CDROM 852## j MATCH cd-rom*
343
+ # TYP CR CDROM 852## j MATCH cdrom*
344
+ # TYP CR CDROM 852## j MATCH cd-rom*
345
+ # TYP CS Software 852## j MATCH software*
346
+
347
+ def software_types
348
+ types = []
349
+ self['852j'].each do |j|
350
+ if j =~ /\Acd-?rom/i
351
+ types << 'CR'
352
+ end
353
+ if j =~ /\Asoftware/i
354
+ types << 'CS'
355
+ end
356
+ end
357
+ return types
358
+ end
359
+
360
+ # ! X (no icon) - Conference
361
+ # TYP XC Conference 008 F29-01 EQUAL 1
362
+ # TYP XC Conference 111## EXIST
363
+ # TYP XC Conference 711## EXIST
364
+ # TYP XC Conference 811## EXIST
365
+ # TYP XC Conference FMT F00-02 EQUAL CF
366
+ # 006 F00-01 EQUAL [a,s]
367
+ # 006 F12-01 EQUAL 1
368
+ # TYP XC Conference FMT F00-02 EQUAL MU
369
+ # 008 F30-01 EQUAL c
370
+ # TYP XC Conference FMT F00-02 EQUAL MU
371
+ # 008 F31-01 EQUAL c
372
+ # ! additional types defined for vufind extract
373
+ # TYP XC Conference 6#### xv MATCH *congresses*
374
+
375
+ def conference_types
376
+ # Get the easy stuff done first
377
+
378
+ return ['XC'] if (record['008'] && (record['008'].value[29] == '1')) || record.fields(['111', '711', '811']).size > 0
379
+
380
+ if (bib_format == 'CF') &&
381
+ ((self['006[0]'] & %w[a s]).size > 0) &&
382
+ self['006[12]'].include?('1')
383
+ return ['XC']
384
+ end
385
+
386
+ if (bib_format == 'MU') &&
387
+ (record['008'].value[30-31] =~ /c/)
388
+ return ['XC']
389
+ end
390
+
391
+ return ['XC'] if @xv6XX.match? /congresses/i
392
+
393
+ # Nope.
394
+ return []
395
+ end
396
+
397
+ # ! X (no icon) - Statistics
398
+ # TYP XS Statistics 650## x MATCH Statistic*
399
+ # TYP XS Statistics 6#### x MATCH Statistic*
400
+ # TYP XS Statistics 6#### v MATCH Statistic*
401
+ # TYP XS Statistics FMT F00-02 EQUAL BK
402
+ # 008 F24-01 EQUAL s
403
+ # TYP XS Statistics FMT F00-02 EQUAL BK
404
+ # 008 F25-01 EQUAL s
405
+ # TYP XS Statistics FMT F00-02 EQUAL BK
406
+ # 008 F26-01 EQUAL s
407
+ # TYP XS Statistics FMT F00-02 EQUAL BK
408
+ # 008 F27-01 EQUAL s
409
+
410
+
411
+ def statistics_types
412
+
413
+ if bib_format == 'BK'
414
+ return ['XS'] if record['008'] && record['008'].value[24..27] =~ /s/
415
+ end
416
+
417
+ return ['XS'] if @xv6XX.match? /\AStatistic/i
418
+
419
+ # Nope
420
+ return []
421
+ end
422
+
423
+
424
+
425
+ # TYP EN Encyclopedias 6#### xv MATCH *encyclopedias*
426
+ # TYP EN Encyclopedias 008 F24-01 EQUAL e
427
+ # TYP EN Encyclopedias 006 F07-01 EQUAL e
428
+ #
429
+ # TYP DI Dictionaries 6#### xv MATCH *dictionaries*
430
+ # TYP DI Dictionaries 008 F24-01 EQUAL d
431
+ # TYP DI Dictionaries 006 F07-01 EQUAL d
432
+ #
433
+ # TYP DR Directories 6#### xv MATCH *directories*
434
+ # TYP DR Directories 008 F24-01 EQUAL r
435
+ # TYP DR Directories 006 F07-01 EQUAL d
436
+
437
+ def reference_types
438
+ types = []
439
+
440
+ # Will need the 008[24] and 006[7]
441
+ f8_24 = self['008[24]']
442
+ f6_7 = self['006[7]']
443
+
444
+
445
+
446
+ if (f8_24.include? 'e') || (f6_7.include? 'e')
447
+ types << 'EN'
448
+ end
449
+
450
+ if f6_7.include? 'd'
451
+ types << 'DI'
452
+ types << 'DR'
453
+ end
454
+
455
+ if f8_24.include? 'd'
456
+ types << 'DI'
457
+ end
458
+
459
+ if f8_24.include? 'r'
460
+ types << 'DR'
461
+ end
462
+
463
+ types << 'EN' if @xv6XX.match? /encyclopedias/i
464
+ types << 'DI' if @xv6XX.match? /dictionaries/i
465
+ types << 'DR' if @xv6XX.match? /directories/i
466
+
467
+ return types
468
+ end
469
+
470
+
471
+ # TYP BI Biography 6#### xv MATCH *biography*
472
+ # TYP BI Biography 6#### xv MATCH *diaries*
473
+ # TYP BI Biography 008 F34-01 EQUAL [a,b,c]
474
+ # TYP BI Biography 006 F17-01 EQUAL [a,b,c]
475
+
476
+ def biography_types
477
+ return ['BI'] if record['008'] && %w[a b c].include?(record['008'].value[34])
478
+ return ['BI'] if (%w[a b c ] & self['006[17]']).size > 0
479
+
480
+ return ['BI'] if @xv6XX.match? /(?:biography|diaries)/i
481
+
482
+ # Nope
483
+ return []
484
+ end
485
+
486
+
487
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH pictorial works
488
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH views
489
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH photographs
490
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH in art
491
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH aerial views
492
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH aerial photographs
493
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH art
494
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH cariacatures and cartoons
495
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH comic books
496
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH illustrations
497
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH drawings
498
+ # TYP PP Photographs & Pictorial Works 6#### xv MATCH slides
499
+
500
+ class << self
501
+ attr_accessor :pp_regexp
502
+ end
503
+
504
+ self.pp_regexp = Regexp.union [ 'pictorial works',
505
+ 'views',
506
+ 'photographs',
507
+ 'in art',
508
+ 'aerial views',
509
+ 'aerial photographs',
510
+ 'cariacatures and cartoons',
511
+ 'comic books',
512
+ 'illustrations',
513
+ 'drawings',
514
+ 'slides',
515
+ ].map{|s| Regexp.new('\b'+s+'\b', true)}
516
+ self.pp_regexp = Regexp.union(self.pp_regexp, /\bart\b/i)
517
+
518
+ def pp_types
519
+ if @xv6XX.match? self.class.pp_regexp
520
+ return ['PP']
521
+ else
522
+ return []
523
+ end
524
+ end
525
+
526
+
527
+
528
+ # TYP VG Video Games FMT F00-02 EQUAL CF
529
+ # 008 F26-01 EQUAL g
530
+
531
+ def videogame_types
532
+ if (bib_format == 'CF') && (self['008[26]'].include? 'g')
533
+ return ['VG']
534
+ else
535
+ return []
536
+ end
537
+ end
538
+
539
+
540
+ end