traject_umich_format 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.gitignore +4 -0
- data/.travis.yml +7 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +4 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +20 -0
- data/README.md +94 -0
- data/Rakefile +38 -0
- data/lib/traject/umich_format.rb +40 -0
- data/lib/traject/umich_format/bib_format.rb +62 -0
- data/lib/traject/umich_format/bib_types.rb +540 -0
- data/lib/traject/umich_format/format_finder.rb +32 -0
- data/lib/traject/umich_format/macros.rb +52 -0
- data/lib/traject/umich_format/version.rb +5 -0
- data/lib/traject/umich_format/xv6xx.rb +24 -0
- data/lib/translation_maps/umich/format.rb +41 -0
- data/spec/audio_spec.rb +119 -0
- data/spec/helper.rb +23 -0
- data/spec/spec_support/RL.seq +52 -0
- data/spec/spec_support/audio.mrc +1 -0
- data/spec/spec_support/fmt_sample.mrc +1 -0
- data/spec/version_spec.rb +9 -0
- data/traject_umich_format.gemspec +23 -0
- metadata +116 -0
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
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --title "traject_umich_format Documentation" --protected
|
data/ChangeLog.md
ADDED
data/Gemfile
ADDED
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
|