enhanced_marc 0.1.5
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.
- 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
|