enhanced_marc 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Changes +1 -0
- data/LICENSE +21 -0
- data/README +51 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/enhanced_marc-0.1.gem +0 -0
- data/enhanced_marc.gemspec +85 -0
- data/lib/enhanced_marc.rb +23 -0
- data/lib/enhanced_marc/book_record.rb +37 -0
- data/lib/enhanced_marc/book_type.rb +87 -0
- data/lib/enhanced_marc/computer_record.rb +37 -0
- data/lib/enhanced_marc/computer_type.rb +14 -0
- data/lib/enhanced_marc/leader.rb +132 -0
- data/lib/enhanced_marc/leftovers.rb +122 -0
- data/lib/enhanced_marc/map_record.rb +38 -0
- data/lib/enhanced_marc/map_type.rb +99 -0
- data/lib/enhanced_marc/mixed_record.rb +37 -0
- data/lib/enhanced_marc/mixed_type.rb +4 -0
- data/lib/enhanced_marc/reader.rb +105 -0
- data/lib/enhanced_marc/record.rb +96 -0
- data/lib/enhanced_marc/record_type.rb +310 -0
- data/lib/enhanced_marc/score_record.rb +38 -0
- data/lib/enhanced_marc/score_type.rb +4 -0
- data/lib/enhanced_marc/serial_record.rb +37 -0
- data/lib/enhanced_marc/serial_type.rb +87 -0
- data/lib/enhanced_marc/sound_record.rb +37 -0
- data/lib/enhanced_marc/sound_type.rb +4 -0
- data/lib/enhanced_marc/visual_record.rb +37 -0
- data/lib/enhanced_marc/visual_type.rb +38 -0
- data/lib/enhanced_marc/xmlreader.rb +58 -0
- data/pkg/enhanced_marc-0.1.gem +0 -0
- data/pkg/enhanced_marc-0.1.tgz +0 -0
- data/pkg/enhanced_marc-0.1.zip +0 -0
- data/pkg/enhanced_marc-0.1/Changes +1 -0
- data/pkg/enhanced_marc-0.1/LICENSE +21 -0
- data/pkg/enhanced_marc-0.1/README +51 -0
- data/pkg/enhanced_marc-0.1/Rakefile +41 -0
- data/pkg/enhanced_marc-0.1/test/ts_enhanced_marc.rb +5 -0
- data/test/ts_enhanced_marc.rb +5 -0
- metadata +113 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
def get_fixed_field_position
|
2
|
+
ff_pos = {
|
3
|
+
'Ctry' => {
|
4
|
+
'008' => {
|
5
|
+
'BKS' => {:start => 15, :len => 3, :def => ' ' },
|
6
|
+
'SER' => {:start => 15, :len => 3, :def => ' ' },
|
7
|
+
'VIS' => {:start => 15, :len => 3, :def => ' ' },
|
8
|
+
'MIX' => {:start => 15, :len => 3, :def => ' ' },
|
9
|
+
'MAP' => {:start => 15, :len => 3, :def => ' ' },
|
10
|
+
'SCO' => {:start => 15, :len => 3, :def => ' ' },
|
11
|
+
'REC' => {:start => 15, :len => 3, :def => ' ' },
|
12
|
+
'COM' => {:start => 15, :len => 3, :def => ' ' }
|
13
|
+
}
|
14
|
+
},
|
15
|
+
'Lang' => {
|
16
|
+
'008' => {
|
17
|
+
'BKS' => {:start => 35, :len => 3, :def => ' ' },
|
18
|
+
'SER' => {:start => 35, :len => 3, :def => ' ' },
|
19
|
+
'VIS' => {:start => 35, :len => 3, :def => ' ' },
|
20
|
+
'MIX' => {:start => 35, :len => 3, :def => ' ' },
|
21
|
+
'MAP' => {:start => 35, :len => 3, :def => ' ' },
|
22
|
+
'SCO' => {:start => 35, :len => 3, :def => ' ' },
|
23
|
+
'REC' => {:start => 35, :len => 3, :def => ' ' },
|
24
|
+
'COM' => {:start => 35, :len => 3, :def => ' ' }
|
25
|
+
}
|
26
|
+
},
|
27
|
+
'MRec' => {
|
28
|
+
'008' => {
|
29
|
+
'BKS' => {:start => 38, :len => 3, :def => ' ' },
|
30
|
+
'SER' => {:start => 38, :len => 3, :def => ' ' },
|
31
|
+
'VIS' => {:start => 38, :len => 3, :def => ' ' },
|
32
|
+
'MIX' => {:start => 38, :len => 3, :def => ' ' },
|
33
|
+
'MAP' => {:start => 38, :len => 3, :def => ' ' },
|
34
|
+
'SCO' => {:start => 38, :len => 3, :def => ' ' },
|
35
|
+
'REC' => {:start => 38, :len => 3, :def => ' ' },
|
36
|
+
'COM' => {:start => 38, :len => 3, :def => ' ' }
|
37
|
+
}
|
38
|
+
},
|
39
|
+
'DtSt' => {
|
40
|
+
'008' => {
|
41
|
+
'BKS' => {:start => 6, :len => 1, :def => ' ' },
|
42
|
+
'SER' => {:start => 6, :len => 1, :def => 'c' },
|
43
|
+
'VIS' => {:start => 6, :len => 1, :def => ' ' },
|
44
|
+
'MIX' => {:start => 6, :len => 1, :def => ' ' },
|
45
|
+
'MAP' => {:start => 6, :len => 1, :def => ' ' },
|
46
|
+
'SCO' => {:start => 6, :len => 1, :def => ' ' },
|
47
|
+
'REC' => {:start => 6, :len => 1, :def => ' ' },
|
48
|
+
'COM' => {:start => 6, :len => 1, :def => ' ' },
|
49
|
+
}
|
50
|
+
},
|
51
|
+
'Type' => {
|
52
|
+
'ldr' => {
|
53
|
+
'BKS' => {:start => 6, :len => 1, :def => 'a' },
|
54
|
+
'SER' => {:start => 6, :len => 1, :def => 'a' },
|
55
|
+
'VIS' => {:start => 6, :len => 1, :def => 'g' },
|
56
|
+
'MIX' => {:start => 6, :len => 1, :def => 'p' },
|
57
|
+
'MAP' => {:start => 6, :len => 1, :def => 'e' },
|
58
|
+
'SCO' => {:start => 6, :len => 1, :def => 'c' },
|
59
|
+
'REC' => {:start => 6, :len => 1, :def => 'i' },
|
60
|
+
'COM' => {:start => 6, :len => 1, :def => 'm' },
|
61
|
+
}
|
62
|
+
},
|
63
|
+
'Ctrl' => {
|
64
|
+
'ldr' => {
|
65
|
+
'BKS' => {:start => 8, :len => 1, :def => ' ' },
|
66
|
+
'SER' => {:start => 8, :len => 1, :def => ' ' },
|
67
|
+
'VIS' => {:start => 8, :len => 1, :def => ' ' },
|
68
|
+
'MIX' => {:start => 8, :len => 1, :def => ' ' },
|
69
|
+
'MAP' => {:start => 8, :len => 1, :def => ' ' },
|
70
|
+
'SCO' => {:start => 8, :len => 1, :def => ' ' },
|
71
|
+
'REC' => {:start => 8, :len => 1, :def => ' ' },
|
72
|
+
'COM' => {:start => 8, :len => 1, :def => ' ' },
|
73
|
+
}
|
74
|
+
},
|
75
|
+
'BLvl' => {
|
76
|
+
'ldr'=> {
|
77
|
+
'BKS' => {:start => 7, :len => 1, :def => 'm' },
|
78
|
+
'SER' => {:start => 7, :len => 1, :def => 's' },
|
79
|
+
'VIS' => {:start => 7, :len => 1, :def => 'm' },
|
80
|
+
'MIX' => {:start => 7, :len => 1, :def => 'c' },
|
81
|
+
'MAP' => {:start => 7, :len => 1, :def => 'm' },
|
82
|
+
'SCO' => {:start => 7, :len => 1, :def => 'm' },
|
83
|
+
'REC' => {:start => 7, :len => 1, :def => 'm' },
|
84
|
+
'COM' => {:start => 7, :len => 1, :def => 'm' },
|
85
|
+
}
|
86
|
+
},
|
87
|
+
'Desc' => {
|
88
|
+
'ldr' => {
|
89
|
+
'BKS' => {:start => 18, :len => 1, :def => ' ' },
|
90
|
+
'SER' => {:start => 18, :len => 1, :def => ' ' },
|
91
|
+
'VIS' => {:start => 18, :len => 1, :def => ' ' },
|
92
|
+
'MIX' => {:start => 18, :len => 1, :def => ' ' },
|
93
|
+
'MAP' => {:start => 18, :len => 1, :def => ' ' },
|
94
|
+
'SCO' => {:start => 18, :len => 1, :def => ' ' },
|
95
|
+
'REC' => {:start => 18, :len => 1, :def => ' ' },
|
96
|
+
'COM' => {:start => 18, :len => 1, :def => ' ' },
|
97
|
+
}
|
98
|
+
},
|
99
|
+
'ELvl' => {
|
100
|
+
'ldr' => {
|
101
|
+
'BKS' => {:start => 17, :len => 1, :def => ' ' },
|
102
|
+
'SER' => {:start => 17, :len => 1, :def => ' ' },
|
103
|
+
'VIS' => {:start => 17, :len => 1, :def => ' ' },
|
104
|
+
'MIX' => {:start => 17, :len => 1, :def => ' ' },
|
105
|
+
'MAP' => {:start => 17, :len => 1, :def => ' ' },
|
106
|
+
'SCO' => {:start => 17, :len => 1, :def => ' ' },
|
107
|
+
'REC' => {:start => 17, :len => 1, :def => ' ' },
|
108
|
+
'COM' => {:start => 17, :len => 1, :def => ' ' },
|
109
|
+
}
|
110
|
+
},
|
111
|
+
'TMat' => {
|
112
|
+
'008' => {
|
113
|
+
'VIS' => {:start => 33, :len => 1, :def => ' ' },
|
114
|
+
},
|
115
|
+
'006' => {
|
116
|
+
'VIS' => {:start => 16, :len => 1, :def => ' ' },
|
117
|
+
}
|
118
|
+
},
|
119
|
+
}
|
120
|
+
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module MARC
|
2
|
+
|
3
|
+
# A class that represents an individual MARC record. Every record
|
4
|
+
# is made up of a collection of MARC::Field objects.
|
5
|
+
|
6
|
+
class MapRecord < Record
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@leader[6] = 'e' if @leader[6,1] == ' '
|
11
|
+
@leader[7] = 'm' if @leader[7,1] == ' '
|
12
|
+
@record_type = 'MAP'
|
13
|
+
@bibliographic_level = @leader.get_blvl
|
14
|
+
self.extend MapType
|
15
|
+
self.inspect_fixed_fields
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_valid_type?
|
19
|
+
return false unless @leader[6,1].match(/[ef]{1}/)
|
20
|
+
return true
|
21
|
+
end
|
22
|
+
def is_valid_blvl?
|
23
|
+
return true if @leader[7,1].match(/[acdim]{1}/) and @leader[6,1].match('f')
|
24
|
+
return true if @leader[7,1].match(/[abcdims]{1}/) and @leader[6,1].match('e')
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
def self.new_from_record(record)
|
28
|
+
rec = MapRecord.new
|
29
|
+
record.instance_variables.each { | var |
|
30
|
+
rec.instance_variable_set(var, record.instance_variable_get(var))
|
31
|
+
}
|
32
|
+
return Exception.new("Incorrect type declaration in leader") unless rec.is_valid_type?
|
33
|
+
return Exception.new("Incorrect bibliographic declaration in leader") unless rec.is_valid_blvl?
|
34
|
+
return rec
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module MapType
|
2
|
+
include RecordType
|
3
|
+
public :is_govdoc?, :form, :has_index?
|
4
|
+
def cartographic_type(human_readable=false)
|
5
|
+
crtp_map = {'a'=>'Map', 'b'=>'Map series', 'c'=>'Map serial', 'd'=>'Globe', 'e'=>'Atlas',
|
6
|
+
'f'=>'Supplement', 'g'=>'Bound as part of another work', 'u'=>'Unknown', 'z'=>'Other'}
|
7
|
+
human_readable = crtp_map if human_readable
|
8
|
+
return self.field_parser({:match=>'MAP', :start=>25,:end=>1}, {:match=>/[ef]{1}/, :start=>8,:end=>1}, human_readable)
|
9
|
+
end
|
10
|
+
|
11
|
+
def relief(human_readable=false)
|
12
|
+
relief_map = {'a'=>'Contours', 'b'=>'Shading', 'c'=>'Grading and bathymetric tints',
|
13
|
+
'd'=>'Hachures', 'e'=>'Bathymetry, soundings', 'f'=>'Form lines', 'g'=>'Spot heights',
|
14
|
+
'h'=>'Color', 'i'=>'Pictorially', 'j'=>'Land forms', 'k'=>'Bathymetry, isolines',
|
15
|
+
'm'=>'Rock drawings', 'z'=>'Other'
|
16
|
+
}
|
17
|
+
contents = []
|
18
|
+
if self.record_type == 'MAP'
|
19
|
+
self['008'].value[18,4].split(//).each { | char |
|
20
|
+
next if char == " "
|
21
|
+
if human_readable
|
22
|
+
contents << relief_map[char]
|
23
|
+
else
|
24
|
+
contents << char
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
@fields.find_all {|f| ('006') === f.tag}.each { | fxd_fld |
|
29
|
+
next unless fxd_fld.value[0,1].match(/[ef]{1}/)
|
30
|
+
fxd_fld.value[1,4].split(//).each { | char |
|
31
|
+
next if char == " "
|
32
|
+
if human_readable
|
33
|
+
contents << relief_map[char]
|
34
|
+
else
|
35
|
+
contents << char
|
36
|
+
end
|
37
|
+
}
|
38
|
+
}
|
39
|
+
return false if contents.empty?
|
40
|
+
return contents
|
41
|
+
end
|
42
|
+
|
43
|
+
def projection(human_readable=false)
|
44
|
+
proj_map = {'Azimuthal'=>{'aa'=>'Aitoff','ab'=>'Gnomic','ac'=>"Lambert's equal area",
|
45
|
+
'ad'=>'Orthographic','ae'=>'Azithumal equidistant', 'af'=>'Stereographic',
|
46
|
+
'ag'=>'General vertical near-sided','am'=>'Modified stereographic for Alaska',
|
47
|
+
'an'=>'Chamberlin trimetric','ap'=>'Polar stereographic','au'=>'Unknown','az'=>'Other'},
|
48
|
+
'Cylindrical'=>{'ba'=>'Gall','bb'=>"Goode's homolographic",'bc'=>"Lambert's equal area",
|
49
|
+
'bd'=>'Mercator','be'=>'Miller','bf'=>'Mollweide','bg'=>'Sinusoidal',
|
50
|
+
'bh'=>'Transverse Mercator','bi'=>'Gauss-Kruger','bj'=>'Equirectangular',
|
51
|
+
'bo'=>'Oblique Mercator','br'=>'Robinson','bs'=>'Space oblique Mercator',
|
52
|
+
'bu'=>'Unknown','bz'=>'Other'
|
53
|
+
},
|
54
|
+
'Conic'=>{'ca'=>"Alber's equal area",'cb'=>'Bonne','cc'=>"Lambert's",'ce'=>'Equidistant conic',
|
55
|
+
'cp'=>'Polyconic','cu'=>'Unknown','cz'=>'Other'
|
56
|
+
},
|
57
|
+
'Other'=>{'da'=>'Armadillo','db'=>'Butterfly','dc'=>'Eckert','dd'=>"Goode's homolosine",
|
58
|
+
'de'=>"Miller's bipolar oblique conformal conic",'df'=>'Van Der Grinten',
|
59
|
+
'dg'=>'Dymaxion','dh'=>'Cordiform','dl'=>'Lambert conformal','zz'=>'Other'
|
60
|
+
}
|
61
|
+
}
|
62
|
+
if @record_type == "MAP"
|
63
|
+
unless self['008'].value[22,2] == ' '
|
64
|
+
if human_readable
|
65
|
+
proj_map.each_key { | general |
|
66
|
+
next unless proj_map[general].keys.index(self['008'].value[22,2])
|
67
|
+
return [general,proj_map[general][self['008'].value[22,2]]]
|
68
|
+
}
|
69
|
+
else
|
70
|
+
return self['008'].value[22,2]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@fields.find_all {|f| ('006') === f.tag}.each { | fxd_fld |
|
75
|
+
next unless fxd_fld.value[0,1].match(/[ef]{1}/)
|
76
|
+
unless fxd_fld.value[5,2] == ' '
|
77
|
+
if human_readable
|
78
|
+
proj_map.each_key { | general |
|
79
|
+
next unless proj_map[general].keys.index(fxd_fld.value[5,2])
|
80
|
+
return [general,proj_map[general][fxd_fld.value[5,2]]]
|
81
|
+
}
|
82
|
+
else
|
83
|
+
return fxd_fld.value[5,2]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
}
|
87
|
+
return false
|
88
|
+
end
|
89
|
+
|
90
|
+
def special_format(human_readable=false)
|
91
|
+
spfm_map = {'a'=>'Blueprint photocopy','b'=>'Other photocopy','c'=>'Negative photocopy',
|
92
|
+
'd'=>'Film negative','f'=>'Facsimile','g'=>'Relief model','h'=>'Rare (pre-1800)',
|
93
|
+
'e'=>'Manuscript','j'=>'Picture/post card','k'=>'Calendar','l'=>'Puzzle',
|
94
|
+
'm'=>'Braille, tactile','n'=>'Game','o'=>'Wall map','p'=>'Playing cards',
|
95
|
+
'q'=>'Loose-leaf','z'=>'Other'}
|
96
|
+
human_readable = spfm_map if human_readable
|
97
|
+
return self.field_parser({:match=>'MAP', :start=>33,:end=>2}, {:match=>/[ef]{1}/, :start=>16,:end=>2}, human_readable)
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module MARC
|
2
|
+
|
3
|
+
# A class that represents an individual MARC record. Every record
|
4
|
+
# is made up of a collection of MARC::Field objects.
|
5
|
+
|
6
|
+
class MixedRecord < Record
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@leader[6] = 'p' if @leader[6,1] == ' '
|
11
|
+
@leader[7] = 'c' if @leader[7,1] == ' '
|
12
|
+
@record_type = 'MIX'
|
13
|
+
@bibliographic_level = @leader.get_blvl
|
14
|
+
self.extend MixedType
|
15
|
+
self.inspect_fixed_fields
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_valid_type?
|
19
|
+
return false unless @leader[6,1].match('p')
|
20
|
+
return true
|
21
|
+
end
|
22
|
+
def is_valid_blvl?
|
23
|
+
return false unless @leader[7,1].match(/[cdi]{1}/)
|
24
|
+
return true
|
25
|
+
end
|
26
|
+
def self.new_from_record(record)
|
27
|
+
rec = MixedRecord.new
|
28
|
+
record.instance_variables.each { | var |
|
29
|
+
rec.instance_variable_set(var, record.instance_variable_get(var))
|
30
|
+
}
|
31
|
+
return Exception.new("Incorrect type declaration in leader") unless rec.is_valid_type?
|
32
|
+
return Exception.new("Incorrect bibliographic declaration in leader") unless rec.is_valid_blvl?
|
33
|
+
return rec
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module MARC
|
2
|
+
class Reader
|
3
|
+
# A static method for turning raw MARC data in transission
|
4
|
+
# format into a MARC::Record object.
|
5
|
+
def self.decode(marc, params={})
|
6
|
+
leader = Leader.new(marc[0..LEADER_LENGTH-1])
|
7
|
+
begin
|
8
|
+
record = case leader.get_type
|
9
|
+
when 'BKS' then MARC::BookRecord.new
|
10
|
+
when 'SER' then MARC::SerialRecord.new
|
11
|
+
when 'VIS' then MARC::VisualRecord.new
|
12
|
+
when 'MIX' then MARC::MixedRecord.new
|
13
|
+
when 'MAP' then MARC::MapRecord.new
|
14
|
+
when 'SCO' then MARC::ScoreRecord.new
|
15
|
+
when 'REC' then MARC::SoundRecord.new
|
16
|
+
when 'COM' then MARC::ComputerRecord.new
|
17
|
+
else MARC::Record.new
|
18
|
+
end
|
19
|
+
rescue ArgumentError
|
20
|
+
record = MARC::Record.new
|
21
|
+
end
|
22
|
+
record.leader = leader
|
23
|
+
|
24
|
+
# where the field data starts
|
25
|
+
base_address = record.leader[12..16].to_i
|
26
|
+
|
27
|
+
# get the byte offsets from the record directory
|
28
|
+
directory = marc[LEADER_LENGTH..base_address-1]
|
29
|
+
|
30
|
+
throw "invalid directory in record" if directory == nil
|
31
|
+
|
32
|
+
# the number of fields in the record corresponds to
|
33
|
+
# how many directory entries there are
|
34
|
+
num_fields = directory.length / DIRECTORY_ENTRY_LENGTH
|
35
|
+
|
36
|
+
# when operating in forgiving mode we just split on end of
|
37
|
+
# field instead of using calculated byte offsets from the
|
38
|
+
# directory
|
39
|
+
all_fields = marc[base_address..-1].split(END_OF_FIELD)
|
40
|
+
|
41
|
+
0.upto(num_fields-1) do |field_num|
|
42
|
+
|
43
|
+
# pull the directory entry for a field out
|
44
|
+
entry_start = field_num * DIRECTORY_ENTRY_LENGTH
|
45
|
+
entry_end = entry_start + DIRECTORY_ENTRY_LENGTH
|
46
|
+
entry = directory[entry_start..entry_end]
|
47
|
+
|
48
|
+
# extract the tag
|
49
|
+
tag = entry[0..2]
|
50
|
+
|
51
|
+
# get the actual field data
|
52
|
+
# if we were told to be forgiving we just use the
|
53
|
+
# next available chuck of field data that we
|
54
|
+
# split apart based on the END_OF_FIELD
|
55
|
+
field_data = ''
|
56
|
+
if params[:forgiving]
|
57
|
+
field_data = all_fields.shift()
|
58
|
+
|
59
|
+
# otherwise we actually use the byte offsets in
|
60
|
+
# directory to figure out what field data to extract
|
61
|
+
else
|
62
|
+
length = entry[3..6].to_i
|
63
|
+
offset = entry[7..11].to_i
|
64
|
+
field_start = base_address + offset
|
65
|
+
field_end = field_start + length - 1
|
66
|
+
field_data = marc[field_start..field_end]
|
67
|
+
end
|
68
|
+
|
69
|
+
# remove end of field
|
70
|
+
field_data.delete!(END_OF_FIELD)
|
71
|
+
|
72
|
+
# add a control field or data field
|
73
|
+
if tag < '010'
|
74
|
+
record.append(MARC::ControlField.new(tag,field_data))
|
75
|
+
else
|
76
|
+
field = MARC::DataField.new(tag)
|
77
|
+
|
78
|
+
# get all subfields
|
79
|
+
subfields = field_data.split(SUBFIELD_INDICATOR)
|
80
|
+
|
81
|
+
# must have at least 2 elements (indicators, and 1 subfield)
|
82
|
+
# TODO some sort of logging?
|
83
|
+
next if subfields.length() < 2
|
84
|
+
|
85
|
+
# get indicators
|
86
|
+
indicators = subfields.shift()
|
87
|
+
field.indicator1 = indicators[0,1]
|
88
|
+
field.indicator2 = indicators[1,1]
|
89
|
+
|
90
|
+
# add each subfield to the field
|
91
|
+
subfields.each() do |data|
|
92
|
+
subfield = MARC::Subfield.new(data[0,1],data[1..-1])
|
93
|
+
field.append(subfield)
|
94
|
+
end
|
95
|
+
|
96
|
+
# add the field to the record
|
97
|
+
record.append(field)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
return record
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module MARC
|
2
|
+
class Record
|
3
|
+
|
4
|
+
attr_reader :record_type, :bibliographic_level
|
5
|
+
|
6
|
+
# Creates a new MARC::Record using MARC::Leader
|
7
|
+
# to work with the leader, rather than a string
|
8
|
+
def initialize
|
9
|
+
@fields = []
|
10
|
+
@leader = Leader.new(' ' * 24)
|
11
|
+
end
|
12
|
+
|
13
|
+
def contains_type?(record_type)
|
14
|
+
type_map = {"BKS"=>/[at]{1}/, "COM"=>"m", "MAP"=>/[ef]{1}/,"MIX"=>"p", "SCO"=>/[cd]{1}/, "REC"=>/[ij]{1}/, "SER"=>"s", "VIS"=>/[gkor]{1}/}
|
15
|
+
matching_fields = []
|
16
|
+
@fields.find_all {|f| ('006') === f.tag}.each { | fxd_fld |
|
17
|
+
matching_fields << fxd_fld if fxd_fld.value[0,1].match(type_map[record_type])
|
18
|
+
|
19
|
+
}
|
20
|
+
return nil if matching_fields.empty?
|
21
|
+
return matching_fields
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.new_from_record(record)
|
25
|
+
leader = Leader.new(record.leader)
|
26
|
+
case leader.get_type
|
27
|
+
when 'BKS' then return MARC::BookRecord.new_from_record(record)
|
28
|
+
when 'SER' then return MARC::SerialRecord.new_from_record(record)
|
29
|
+
when 'VIS' then return MARC::VisualRecord.new_from_record(record)
|
30
|
+
when 'MIX' then return MARC::MixedRecord.new_from_record(record)
|
31
|
+
when 'MAP' then return MARC::MapRecord.new_from_record(record)
|
32
|
+
when 'SCO' then return MARC::ScoreRecord.new_from_record(record)
|
33
|
+
when 'REC' then return MARC::SoundRecord.new_from_record(record)
|
34
|
+
when 'COM' then return MARC::ComputerRecord.new_from_record(record)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_typed_record
|
39
|
+
return self.new_from_record(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
def is_archival?
|
43
|
+
return @leader.is_archival?
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def composition_form(human_readable=false)
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def publication_country
|
52
|
+
return self['008'].value[15,2] unless self['008'].value[15,2] == ' '
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_dates
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
def created_on
|
61
|
+
unless self['008'].value[0,6] == (' '*6)
|
62
|
+
return Date.parse(self['008'].value[0,2]+'-'+self['008'].value[2,2]+'-'+self['008'].value[4,2], false)
|
63
|
+
else
|
64
|
+
return Date.today
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def inspect_fixed_fields
|
69
|
+
type_map = {/[at]{1}/=>BookType,'m'=>ComputerType,/[ef]{1}/=>MapType,
|
70
|
+
'p'=>MixedType,/[cd]{1}/=>ScoreType,/[ij]{1}/=>SoundType,'s'=>SerialType,
|
71
|
+
/[gkor]{1}/=>VisualType}
|
72
|
+
@fields.find_all {|f| ('006') === f.tag}.each { | fxd_fld |
|
73
|
+
type_map.each_key { | key |
|
74
|
+
if fxd_fld.value[0,1].match(key)
|
75
|
+
self.extend type_map[key]
|
76
|
+
end
|
77
|
+
}
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def languages
|
82
|
+
languages = []
|
83
|
+
unless self['008'].value[35,3].empty?
|
84
|
+
languages << Locale::Info.get_language(self['008'].value[35,3])
|
85
|
+
end
|
86
|
+
oh_four_ones = @fields.find_all {|fld| fld.tag == "041"}
|
87
|
+
oh_four_ones.each do | oh_four_one |
|
88
|
+
langs = oh_four_one.find_all { |sub| sub.code == 'a'}
|
89
|
+
langs.each do | lang |
|
90
|
+
languages << Locale::Info.get_language(lang.value)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
languages
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|