rmarc 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rmarc/constants.rb +4 -3
- data/lib/rmarc/marc_stream_reader.rb +40 -20
- data/lib/rmarc/marc_stream_writer.rb +13 -14
- data/lib/rmarc/marc_xml_reader.rb +53 -44
- data/lib/rmarc/marc_xml_writer.rb +53 -24
- data/lib/rmarc/model/control_field.rb +11 -6
- data/lib/rmarc/model/data_field.rb +24 -7
- data/lib/rmarc/model/directory.rb +8 -7
- data/lib/rmarc/model/leader.rb +11 -7
- data/lib/rmarc/model/record.rb +37 -10
- data/lib/rmarc/model/subfield.rb +13 -6
- data/lib/rmarc/model/variable_field.rb +9 -6
- data/test/test_model.rb +19 -6
- data/test/test_reader.rb +12 -13
- data/test/test_writer.rb +4 -3
- metadata +3 -3
data/lib/rmarc/constants.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: constants.rb,v 1.3 2005/12/09 15:26:03 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,13 +18,13 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
module RMARC
|
22
23
|
|
23
24
|
class Constants
|
24
25
|
|
25
26
|
def Constants.VERSION
|
26
|
-
return "1.
|
27
|
+
return "0.1.2"
|
27
28
|
end
|
28
29
|
|
29
30
|
def Constants.RT
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: marc_stream_reader.rb,v 1.5 2005/12/11 15:33:22 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,30 +18,41 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
module RMARC
|
22
23
|
|
23
|
-
#
|
24
|
+
# This class provides an iterator over a collection of MARC records in ISO 2709 format.
|
24
25
|
#
|
25
26
|
# Example usage:
|
26
27
|
#
|
27
|
-
#
|
28
|
-
# reader
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
28
|
+
# reader = RMARC::MarcStreamReader.new("file.mrc")
|
29
|
+
# while reader.has_next
|
30
|
+
# record = reader.next()
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# You can also pass a file object:
|
34
|
+
#
|
35
|
+
# input = File.new("file.mrc")
|
36
|
+
# reader = RMARC::MarcStreamReader.new(input)
|
37
|
+
# while reader.has_next
|
38
|
+
# record = reader.next()
|
39
|
+
# end
|
40
|
+
# input.close
|
41
|
+
#
|
42
|
+
# Or any other IO subclass.
|
43
|
+
|
32
44
|
class MarcStreamReader
|
33
45
|
|
34
|
-
|
46
|
+
private
|
35
47
|
|
36
48
|
def parse_data_field(entry)
|
37
49
|
msg = "Unexpected EOF while reading field with tag #{entry.tag}"
|
38
50
|
|
39
|
-
ind1 =
|
51
|
+
ind1 = @input.read(1)
|
40
52
|
|
41
53
|
raise msg if ind1 == nil
|
42
54
|
|
43
|
-
ind2 =
|
55
|
+
ind2 = @input.read(1)
|
44
56
|
|
45
57
|
raise msg if ind2 == nil
|
46
58
|
|
@@ -51,12 +63,12 @@ module RMARC
|
|
51
63
|
i = 2
|
52
64
|
|
53
65
|
while i < entry.length
|
54
|
-
s =
|
66
|
+
s = @input.read(1)
|
55
67
|
if s == nil
|
56
68
|
raise msg
|
57
69
|
elsif s == Constants.US
|
58
70
|
field.add(Subfield.new(code, data)) if code != nil
|
59
|
-
code =
|
71
|
+
code = @input.read(1)
|
60
72
|
i += 1
|
61
73
|
data = ""
|
62
74
|
elsif s == Constants.FT
|
@@ -69,9 +81,11 @@ module RMARC
|
|
69
81
|
return field
|
70
82
|
end
|
71
83
|
|
84
|
+
public
|
85
|
+
|
72
86
|
# Returns the next record in the iteration.
|
73
87
|
def next
|
74
|
-
ldr =
|
88
|
+
ldr = @input.read(24)
|
75
89
|
|
76
90
|
raise "Unexpected EOF while reading record label" if ldr == nil
|
77
91
|
|
@@ -83,18 +97,18 @@ module RMARC
|
|
83
97
|
|
84
98
|
raise "Invalid directory" if length % 12 != 0
|
85
99
|
|
86
|
-
dir =
|
100
|
+
dir = @input.read(length)
|
87
101
|
|
88
102
|
entries = length / 12
|
89
103
|
|
90
|
-
raise "Expected field terminator" if
|
104
|
+
raise "Expected field terminator" if @input.read(1) != Constants.FT
|
91
105
|
|
92
106
|
start = 0
|
93
107
|
|
94
108
|
entries.times do
|
95
109
|
entry = Directory.new(dir[start, 3], dir[start += 3, 4], dir[start += 4, 5])
|
96
110
|
if (entry.tag.to_i < 10)
|
97
|
-
data =
|
111
|
+
data = @input.read(entry.length)
|
98
112
|
|
99
113
|
raise "Unexpected EOF while reading field with tag #{entry.tag}" if data == nil
|
100
114
|
|
@@ -105,14 +119,14 @@ module RMARC
|
|
105
119
|
start += 5
|
106
120
|
end
|
107
121
|
|
108
|
-
raise "Expected record terminator" if
|
122
|
+
raise "Expected record terminator" if @input.read(1) != Constants.RT
|
109
123
|
|
110
124
|
return record
|
111
125
|
end
|
112
126
|
|
113
127
|
# Returns true if the iteration has more records, false otherwise.
|
114
128
|
def has_next
|
115
|
-
if
|
129
|
+
if @input.eof == false
|
116
130
|
return true
|
117
131
|
else
|
118
132
|
return false
|
@@ -121,7 +135,13 @@ module RMARC
|
|
121
135
|
|
122
136
|
# Default constructor
|
123
137
|
def initialize(input)
|
124
|
-
|
138
|
+
if input.class == String
|
139
|
+
@input = File.new(input)
|
140
|
+
elsif input.class == File
|
141
|
+
@input = input
|
142
|
+
else
|
143
|
+
throw "Unable to read from path or file"
|
144
|
+
end
|
125
145
|
end
|
126
146
|
end
|
127
147
|
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: marc_stream_writer.rb,v 1.5 2005/12/11 15:33:22 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,28 +18,26 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
#
|
21
|
+
# ++
|
21
22
|
module RMARC
|
22
23
|
|
23
24
|
# Class for writing MARC record objects in ISO 2709 format.
|
24
25
|
#
|
25
|
-
# The following example reads a file with
|
26
|
+
# The following example reads a file with MARC XML records
|
26
27
|
# and outputs the record set in ISO 2709 format:
|
27
28
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
|
29
|
+
# writer = RMARC::MarcStreamWriter.new(STDOUT)
|
30
|
+
# reader = RMARC::MarcXmlReader.new("file.xml")
|
31
|
+
# while reader.has_next
|
32
|
+
# record = reader.next()
|
33
|
+
# writer.write_record(record)
|
34
|
+
# end
|
35
|
+
|
35
36
|
class MarcStreamWriter
|
36
37
|
|
37
|
-
$output = nil
|
38
|
-
|
39
38
|
# Default constructor.
|
40
39
|
def initialize(output)
|
41
|
-
|
40
|
+
@output = output
|
42
41
|
end
|
43
42
|
|
44
43
|
# Writes a single record to the given output stream.
|
@@ -66,7 +65,7 @@ module RMARC
|
|
66
65
|
leader.base_address = 24 + dir.length
|
67
66
|
leader.record_length = leader.base_address + data.length + 1
|
68
67
|
|
69
|
-
|
68
|
+
@output.write(leader.to_s << dir << data << Constants.RT)
|
70
69
|
end
|
71
70
|
end
|
72
71
|
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: marc_xml_reader.rb,v 1.5 2005/12/11 15:33:22 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,7 +18,7 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
require 'rexml/document'
|
22
23
|
require 'thread'
|
23
24
|
|
@@ -25,38 +26,32 @@ module RMARC
|
|
25
26
|
|
26
27
|
class RecordStack < SizedQueue
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
attr_accessor :has_next
|
30
|
+
|
30
31
|
end
|
31
32
|
|
32
33
|
class Listener
|
33
34
|
|
34
|
-
$record = nil
|
35
|
-
$queue = nil
|
36
|
-
$field = nil
|
37
|
-
$subfield = nil
|
38
|
-
$data = nil
|
39
|
-
|
40
35
|
def tag_start(name, attrs)
|
41
36
|
re = /(\w+):(\w+)/
|
42
37
|
md = re.match(name)
|
43
38
|
name = $2 if ($2 != nil)
|
44
39
|
case name
|
45
40
|
when "collection"
|
46
|
-
|
41
|
+
@queue.has_next = true
|
47
42
|
when "record"
|
48
|
-
|
43
|
+
@record = Record.new
|
49
44
|
when "controlfield"
|
50
|
-
|
45
|
+
@field = ControlField.new(attrs["tag"])
|
51
46
|
when "datafield"
|
52
|
-
|
47
|
+
@field = DataField.new(attrs["tag"], attrs["ind1"], attrs["ind2"])
|
53
48
|
when "subfield"
|
54
|
-
|
49
|
+
@subfield = Subfield.new(attrs["code"])
|
55
50
|
end
|
56
51
|
end
|
57
52
|
|
58
53
|
def text(text)
|
59
|
-
|
54
|
+
@data = text
|
60
55
|
end
|
61
56
|
|
62
57
|
def tag_end(name)
|
@@ -65,23 +60,23 @@ module RMARC
|
|
65
60
|
name = $2 if ($2 != nil)
|
66
61
|
case name
|
67
62
|
when "collection"
|
68
|
-
|
63
|
+
@queue.has_next = false
|
69
64
|
when "record"
|
70
|
-
|
65
|
+
@queue.push(@record)
|
71
66
|
when "leader"
|
72
|
-
leader = Leader.new(
|
73
|
-
|
74
|
-
|
67
|
+
leader = Leader.new(@data)
|
68
|
+
@data = ""
|
69
|
+
@record.leader = leader
|
75
70
|
when "controlfield"
|
76
|
-
|
77
|
-
|
78
|
-
|
71
|
+
@field.data = @data
|
72
|
+
@data = ""
|
73
|
+
@record.add(@field)
|
79
74
|
when "datafield"
|
80
|
-
|
75
|
+
@record.add(@field)
|
81
76
|
when "subfield"
|
82
|
-
|
83
|
-
|
84
|
-
|
77
|
+
@subfield.data = @data
|
78
|
+
@data = ""
|
79
|
+
@field.add(@subfield)
|
85
80
|
end
|
86
81
|
end
|
87
82
|
|
@@ -89,38 +84,52 @@ module RMARC
|
|
89
84
|
end
|
90
85
|
|
91
86
|
def initialize(queue)
|
92
|
-
|
87
|
+
@queue = queue
|
93
88
|
end
|
94
89
|
|
95
90
|
end
|
96
91
|
|
97
|
-
#
|
92
|
+
# This class provides an iterator over a collection of MARC XML records.
|
98
93
|
#
|
99
94
|
# Example usage:
|
100
95
|
#
|
101
|
-
#
|
102
|
-
# reader
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
96
|
+
# reader = RMARC::MarcXmlReader.new("file.xml")
|
97
|
+
# while reader.has_next
|
98
|
+
# record = reader.next()
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# You can also pass a file object:
|
102
|
+
#
|
103
|
+
# input = File.new("file.mrc")
|
104
|
+
# reader = RMARC::MarcXmlReader.new(input)
|
105
|
+
# while reader.has_next
|
106
|
+
# record = reader.next()
|
107
|
+
# end
|
108
|
+
# input.close
|
109
|
+
#
|
110
|
+
# Or any other IO subclass.
|
111
|
+
|
106
112
|
class MarcXmlReader
|
107
113
|
|
108
|
-
$queue = nil
|
109
|
-
$input = nil
|
110
|
-
|
111
114
|
# Default constructor
|
112
115
|
def initialize(input)
|
113
|
-
|
114
|
-
|
116
|
+
if input.class == String
|
117
|
+
@input = File.new(input)
|
118
|
+
elsif input.class == File
|
119
|
+
@input = input
|
120
|
+
else
|
121
|
+
throw "Unable to read from path or file"
|
122
|
+
end
|
123
|
+
@queue = RecordStack.new(1)
|
115
124
|
Thread.new do
|
116
|
-
producer = Listener.new(
|
117
|
-
REXML::Document.parse_stream(
|
125
|
+
producer = Listener.new(@queue)
|
126
|
+
REXML::Document.parse_stream(@input, producer)
|
118
127
|
end
|
119
128
|
end
|
120
129
|
|
121
130
|
# Returns true if the iteration has more records, false otherwise.
|
122
131
|
def has_next
|
123
|
-
if (
|
132
|
+
if (@queue.has_next == false && @queue.empty?)
|
124
133
|
return false
|
125
134
|
else
|
126
135
|
return true
|
@@ -129,7 +138,7 @@ module RMARC
|
|
129
138
|
|
130
139
|
# Returns the next record in the iteration.
|
131
140
|
def next
|
132
|
-
obj =
|
141
|
+
obj = @queue.pop
|
133
142
|
return obj
|
134
143
|
end
|
135
144
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: marc_xml_writer.rb,v 1.5 2005/12/11 15:33:22 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,39 +18,65 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
require 'rexml/document'
|
22
23
|
|
23
24
|
module RMARC
|
24
|
-
|
25
|
+
|
25
26
|
# Class for writing MARC record objects in MARC XML format.
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
27
|
+
#
|
28
|
+
# The following example reads a file with MARC records
|
29
|
+
# and outputs the record set in MARC XML format:
|
30
|
+
#
|
31
|
+
# writer = RMARC::MarcXmlWriter.new(STDOUT)
|
32
|
+
# reader = RMARC::MarcStreamReader.new("file.mrc")
|
33
|
+
# writer.start_document
|
34
|
+
# while reader.has_next
|
35
|
+
# record = reader.next()
|
36
|
+
# writer.write_record(record)
|
37
|
+
# end
|
38
|
+
# writer.end_document
|
39
|
+
#
|
40
|
+
# See: http://www.loc.gov/standards/marcxml for more information about MARC XML.
|
41
|
+
|
36
42
|
class MarcXmlWriter
|
37
43
|
|
38
|
-
$output = nil
|
39
|
-
|
40
44
|
# Default constructor.
|
41
45
|
def initialize(output)
|
42
|
-
|
46
|
+
@output = output
|
43
47
|
end
|
44
48
|
|
45
|
-
# Writes the XML declaration and the collection start tag
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
# Writes the XML declaration and the collection start tag:
|
50
|
+
#
|
51
|
+
# <?xml version='1.0' encoding='UTF-8'?>
|
52
|
+
# <collection xmlns="http://www.loc.gov/MARC21/slim">
|
53
|
+
#
|
54
|
+
# The default encoding is UTF-8.
|
55
|
+
def start_document(encoding = nil)
|
56
|
+
decl = REXML::XMLDecl.new
|
57
|
+
if encoding
|
58
|
+
decl.encoding = encoding
|
59
|
+
else
|
60
|
+
decl.encoding = "UTF-8"
|
61
|
+
end
|
62
|
+
@output.write(decl)
|
63
|
+
@output.write("\n<collection xmlns=\"http://www.loc.gov/MARC21/slim\">")
|
49
64
|
end
|
50
65
|
|
51
|
-
# Writes a single record element
|
66
|
+
# Writes a single record element:
|
67
|
+
#
|
68
|
+
# <record>
|
69
|
+
# <leader>00714cam a2200205 a 4500</leader>
|
70
|
+
# <controlfield tag='001'>12883376</controlfield>
|
71
|
+
# ...
|
72
|
+
# <datafield tag='245' ind1='1' ind2='0'>
|
73
|
+
# <subfield code='a'>Summerland /</subfield>
|
74
|
+
# <subfield code='c'>Michael Chabon.</subfield>
|
75
|
+
# </datafield>
|
76
|
+
# ...
|
77
|
+
# </record>
|
52
78
|
def write_record(record)
|
79
|
+
@output.write("\n ")
|
53
80
|
rec = REXML::Element.new('record')
|
54
81
|
ldr = REXML::Element.new('leader')
|
55
82
|
ldr.add_text(record.leader.to_s)
|
@@ -75,12 +102,14 @@ module RMARC
|
|
75
102
|
rec.add_element(fld)
|
76
103
|
end
|
77
104
|
}
|
78
|
-
rec.write(
|
105
|
+
rec.write(@output, 1)
|
79
106
|
end
|
80
107
|
|
81
|
-
# Writes the collection end tag
|
108
|
+
# Writes the collection end tag:
|
109
|
+
#
|
110
|
+
# </collection>
|
82
111
|
def end_document
|
83
|
-
|
112
|
+
@output.write("\n</collection>")
|
84
113
|
end
|
85
114
|
|
86
115
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: control_field.rb,v 1.4 2005/12/09 15:25:52 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,16 +18,16 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
require 'rmarc/model/variable_field'
|
22
23
|
|
23
24
|
module RMARC
|
24
25
|
|
25
|
-
#
|
26
|
+
# This class represents a control field in a MARC record.
|
27
|
+
|
26
28
|
class ControlField < VariableField
|
27
|
-
|
28
|
-
|
29
|
-
attr_writer :data
|
29
|
+
|
30
|
+
attr_accessor :data
|
30
31
|
|
31
32
|
def initialize(tag, data = nil)
|
32
33
|
super(tag)
|
@@ -34,6 +35,10 @@ module RMARC
|
|
34
35
|
end
|
35
36
|
|
36
37
|
# Returns a string representaiton for a conctrol field.
|
38
|
+
#
|
39
|
+
# Example:
|
40
|
+
#
|
41
|
+
# 001 11939876
|
37
42
|
def to_s
|
38
43
|
super + "#@data"
|
39
44
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: data_field.rb,v 1.4 2005/12/09 15:25:52 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,19 +18,31 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
require 'rmarc/model/variable_field'
|
22
23
|
|
23
24
|
module RMARC
|
24
25
|
|
25
|
-
#
|
26
|
-
#
|
26
|
+
# This class represents a data field in a MARC record.
|
27
|
+
#
|
28
|
+
# The module Enumerable is included to enable searching within subfields using each.
|
29
|
+
#
|
30
|
+
# To iterate over all subfields:
|
31
|
+
#
|
32
|
+
# field.each { |s| print s }
|
33
|
+
#
|
34
|
+
# To retrieve subfield with code 'a':
|
35
|
+
#
|
36
|
+
# field.find {|s| s.code == 'a'}
|
37
|
+
#
|
38
|
+
# To retrieve subfields with code 'a' through 'c':
|
39
|
+
#
|
40
|
+
# field.find_all {|s| ('a'..'c' === s.code)}
|
41
|
+
|
27
42
|
class DataField < VariableField
|
28
43
|
include Enumerable
|
29
44
|
|
30
|
-
|
31
|
-
|
32
|
-
attr_writer :ind1, :ind2, :subfields
|
45
|
+
attr_accessor :ind1, :ind2, :subfields
|
33
46
|
|
34
47
|
def initialize(tag, ind1, ind2)
|
35
48
|
super(tag)
|
@@ -57,6 +70,10 @@ module RMARC
|
|
57
70
|
end
|
58
71
|
|
59
72
|
# Returns a string representation of the data field.
|
73
|
+
#
|
74
|
+
# Example:
|
75
|
+
#
|
76
|
+
# 100 1 $aChabon, Michael.
|
60
77
|
def to_s
|
61
78
|
a = ""
|
62
79
|
a << super << @ind1 << @ind2
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: directory.rb,v 1.4 2005/12/09 15:25:52 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,15 +18,15 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
module RMARC
|
22
23
|
|
23
|
-
#
|
24
|
+
# This class represents a directory in a MARC record.
|
25
|
+
|
24
26
|
class Directory
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
|
28
|
+
attr_accessor :tag, :length, :start
|
29
|
+
|
29
30
|
def initialize(tag, length, start)
|
30
31
|
@tag = tag
|
31
32
|
@length = length.to_i
|
data/lib/rmarc/model/leader.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: leader.rb,v 1.5 2005/12/09 15:25:52 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,15 +18,14 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
module RMARC
|
22
23
|
|
23
|
-
#
|
24
|
+
# This class represents a leader or record label in a MARC record.
|
25
|
+
|
24
26
|
class Leader
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
attr_writer :record_length, :record_status, :record_type, :impl_defined1, :char_coding, :indicator_count, :subfield_code_length, :base_address, :impl_defined2, :entry_map
|
28
|
+
attr_accessor :record_length, :record_status, :record_type, :impl_defined1, :char_coding, :indicator_count, :subfield_code_length, :base_address, :impl_defined2, :entry_map
|
29
29
|
|
30
30
|
def initialize(ldr = nil)
|
31
31
|
if (ldr == nil)
|
@@ -53,7 +53,11 @@ module RMARC
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
# Returns a string representation for a
|
56
|
+
# Returns a string representation for a leader.
|
57
|
+
#
|
58
|
+
# Example:
|
59
|
+
#
|
60
|
+
# 00714cam a2200205 a 4500
|
57
61
|
def to_s
|
58
62
|
"%05d" % @record_length +
|
59
63
|
"#@record_status#@record_type#@impl_defined1#@char_coding" +
|
data/lib/rmarc/model/record.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: record.rb,v 1.5 2005/12/11 15:32:37 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,18 +18,25 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
module RMARC
|
22
23
|
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# using each.
|
24
|
+
# This class represents a MARC record.
|
25
|
+
#
|
26
|
+
# The module Enumerable is included to enable searching within variable fields using each.
|
27
|
+
#
|
28
|
+
# To iterate over all fields:
|
29
|
+
#
|
30
|
+
# record.each { |f| print f }
|
31
|
+
#
|
32
|
+
# To retrieve the data field for tag 245:
|
33
|
+
#
|
34
|
+
# field = record.find {|f| f.tag == '245'}
|
35
|
+
|
26
36
|
class Record
|
27
37
|
include Enumerable
|
28
38
|
|
29
|
-
|
30
|
-
|
31
|
-
attr_writer :leader, :fields
|
39
|
+
attr_accessor :leader, :fields
|
32
40
|
|
33
41
|
def initialize(leader = nil)
|
34
42
|
@leader = leader
|
@@ -45,8 +53,7 @@ module RMARC
|
|
45
53
|
@fields.delete(fld)
|
46
54
|
end
|
47
55
|
|
48
|
-
# Implements Enumarable.each to provide an iterator over all
|
49
|
-
# variable fields.
|
56
|
+
# Implements Enumarable.each to provide an iterator over all variable fields.
|
50
57
|
def each
|
51
58
|
for field in @fields
|
52
59
|
yield field
|
@@ -54,6 +61,26 @@ module RMARC
|
|
54
61
|
end
|
55
62
|
|
56
63
|
# Returns a string representation of the record.
|
64
|
+
#
|
65
|
+
# Example:
|
66
|
+
#
|
67
|
+
# Leader: 00714cam a2200205 a 4500
|
68
|
+
# 001 12883376
|
69
|
+
# 005 20030616111422.0
|
70
|
+
# 008 020805s2002 nyu j 000 1 eng
|
71
|
+
# 020 $a0786808772
|
72
|
+
# 020 $a0786816155 (pbk.)
|
73
|
+
# 040 $aDLC$cDLC$dDLC
|
74
|
+
# 100 1 $aChabon, Michael.
|
75
|
+
# 245 10$aSummerland /$cMichael Chabon.
|
76
|
+
# 250 $a1st ed.
|
77
|
+
# 260 $aNew York :$bMiramax Books/Hyperion Books for Children,$cc2002.
|
78
|
+
# 300 $a500 p. ;$c22 cm.
|
79
|
+
# 650 1$aFantasy.
|
80
|
+
# 650 1$aBaseball$vFiction.
|
81
|
+
# 650 1$aMagic$vFiction.
|
82
|
+
#
|
83
|
+
# Use RMARC::MarcStreamWriter to serialize records to ISO 2709 format.
|
57
84
|
def to_s
|
58
85
|
a = "Leader: #{@leader.to_s}\n"
|
59
86
|
@fields.each { |f| a << "#{f.to_s}\n" }
|
data/lib/rmarc/model/subfield.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: subfield.rb,v 1.4 2005/12/09 15:25:52 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,20 +18,26 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
module RMARC
|
22
23
|
|
23
|
-
#
|
24
|
+
# This class represents a subfield in a MARC record.
|
25
|
+
|
24
26
|
class Subfield
|
25
|
-
|
26
|
-
|
27
|
-
attr_writer :code, :data
|
27
|
+
|
28
|
+
attr_accessor :code, :data
|
28
29
|
|
30
|
+
# Default constructor
|
29
31
|
def initialize(code, data = nil)
|
30
32
|
@code = code
|
31
33
|
@data = data
|
32
34
|
end
|
33
35
|
|
36
|
+
# Returns a string representation for a subfield.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
#
|
40
|
+
# $aChabon, Michael.
|
34
41
|
def to_s
|
35
42
|
"$#@code#@data"
|
36
43
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: variable_field.rb,v 1.4 2005/12/09 15:25:52 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,19 +18,21 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
module RMARC
|
22
23
|
|
23
|
-
#
|
24
|
+
# This class represents a variable field in a MARC record.
|
25
|
+
|
24
26
|
class VariableField
|
25
|
-
|
26
|
-
|
27
|
-
attr_writer :tag
|
27
|
+
|
28
|
+
attr_accessor :tag
|
28
29
|
|
30
|
+
# Default constructor
|
29
31
|
def initialize(tag)
|
30
32
|
@tag = tag
|
31
33
|
end
|
32
34
|
|
35
|
+
# Returns a string representation for the tag value.
|
33
36
|
def to_s
|
34
37
|
"#@tag "
|
35
38
|
end
|
data/test/test_model.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: test_model.rb,v 1.3 2005/12/10 16:27:52 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,7 +18,7 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
$: << File.dirname(__FILE__) + "/.." << File.dirname(__FILE__) + "/../lib"
|
22
23
|
|
23
24
|
require 'test/unit'
|
@@ -38,17 +39,26 @@ class TestModel < Test::Unit::TestCase
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def test_data_field
|
41
|
-
field = RMARC::DataField.new("245", "1", "0")
|
42
|
+
field = RMARC::DataField.new("245", "1", "0")
|
42
43
|
assert_equal("245", field.tag)
|
43
44
|
assert_equal("1", field.ind1)
|
44
45
|
assert_equal("0", field.ind2)
|
45
46
|
assert_equal(0, field.subfields.length)
|
47
|
+
|
46
48
|
subfield = RMARC::Subfield.new("a", "Summerland")
|
47
49
|
field.add(subfield)
|
48
50
|
assert_equal(1, field.subfields.length)
|
51
|
+
|
49
52
|
subfield = RMARC::Subfield.new("c", "Michael Chabon")
|
50
53
|
field.add(subfield)
|
51
54
|
assert_equal(2, field.subfields.length)
|
55
|
+
|
56
|
+
author = field.find {|s| s.code == 'c'}
|
57
|
+
assert_equal("Michael Chabon", author.data)
|
58
|
+
|
59
|
+
all = field.find_all {|s| ('a'..'e' === s.code)}
|
60
|
+
assert_equal(2, all.length)
|
61
|
+
|
52
62
|
field.remove(subfield)
|
53
63
|
assert_equal(1, field.subfields.length)
|
54
64
|
assert_equal("a", field.subfields.last.code)
|
@@ -68,11 +78,14 @@ class TestModel < Test::Unit::TestCase
|
|
68
78
|
field = RMARC::ControlField.new("001", "12883376")
|
69
79
|
record.add(field)
|
70
80
|
assert_equal(1, record.fields.length)
|
81
|
+
|
71
82
|
field = RMARC::DataField.new("245", "1", "0")
|
72
83
|
record.add(field)
|
73
|
-
|
74
|
-
|
75
|
-
|
84
|
+
df = record.find {|f| f.tag == '245'}
|
85
|
+
assert_equal('245', df.tag)
|
86
|
+
|
87
|
+
record.remove(field)
|
88
|
+
assert_equal('001', record.fields.last.tag)
|
76
89
|
end
|
77
90
|
|
78
91
|
end
|
data/test/test_reader.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: test_reader.rb,v 1.3 2005/12/09 15:30:46 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,32 +18,30 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
$: << File.dirname(__FILE__) + "/.." << File.dirname(__FILE__) + "/../lib"
|
22
23
|
|
23
24
|
require 'test/unit'
|
24
25
|
require 'rmarc'
|
25
26
|
|
26
|
-
class
|
27
|
+
class TestReader < Test::Unit::TestCase
|
27
28
|
|
28
29
|
def test_parse_marc
|
29
30
|
assert_nothing_raised() {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
31
|
+
reader = RMARC::MarcStreamReader.new("test/chabon.mrc")
|
32
|
+
while reader.has_next
|
33
|
+
record = reader.next()
|
34
|
+
puts record.to_s
|
35
35
|
end
|
36
36
|
}
|
37
37
|
end
|
38
38
|
|
39
39
|
def test_parse_marc_xml
|
40
40
|
assert_nothing_raised() {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
41
|
+
reader = RMARC::MarcXmlReader.new("test/chabon.xml")
|
42
|
+
while reader.has_next
|
43
|
+
record = reader.next()
|
44
|
+
puts record.to_s
|
46
45
|
end
|
47
46
|
}
|
48
47
|
end
|
data/test/test_writer.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# $Id: test_writer.rb,v 1.3 2005/12/09 15:30:46 bpeters Exp $
|
2
3
|
#
|
3
4
|
# Copyright (c) 2005 Bas Peters
|
4
5
|
#
|
@@ -17,13 +18,13 @@
|
|
17
18
|
# You should have received a copy of the GNU Lesser General Public
|
18
19
|
# License along with RMARC; if not, write to the Free Software
|
19
20
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
-
|
21
|
+
#++
|
21
22
|
$: << File.dirname(__FILE__) + "/.." << File.dirname(__FILE__) + "/../lib"
|
22
23
|
|
23
24
|
require 'test/unit'
|
24
25
|
require 'rmarc'
|
25
26
|
|
26
|
-
class
|
27
|
+
class TestWriter < Test::Unit::TestCase
|
27
28
|
|
28
29
|
def test_write_marc
|
29
30
|
assert_nothing_raised() {
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rmarc
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-12-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2005-12-13
|
8
8
|
summary: RMARC is a library for working with MARC and MARC XML data in Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -15,7 +15,7 @@ description:
|
|
15
15
|
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
18
|
-
has_rdoc:
|
18
|
+
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
21
|
-
|