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 +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
|