rwdgutenberg 0.12 → 0.13
Sign up to get free protection for your applications and to get access to all the features.
- data/code/01rwdcore/01rwdcore.rb +6 -6
- data/code/01rwdcore/02helptexthashbegin.rb +14 -2
- data/code/01rwdcore/03helptexthash.rb +18 -20
- data/code/01rwdcore/jumplinkcommand.rb +14 -4
- data/code/01rwdcore/openhelpwindow.rb +7 -0
- data/code/01rwdcore/runhelpabout.rb +6 -1
- data/code/01rwdcore/runtab.rb +15 -0
- data/code/01rwdcore/selectiontab.rb +2 -0
- data/code/01rwdcore/setuphelpaboutoptions.rb +2 -0
- data/code/01rwdcore/setuptinkerdocuments.rb +1 -0
- data/code/01rwdcore/test_cases.rb +100 -51
- data/code/01rwdcore/test_harness.rb +8 -1
- data/code/01rwdcore/uploadreturns.rb +3 -0
- data/code/dd0viewphoto/dd0viewphoto.rb +2 -0
- data/code/superant.com.gutenberg/0uninstallapplet.rb +2 -0
- data/code/superant.com.gutenberg/changegutenbergname.rb +0 -0
- data/code/superant.com.gutenberg/clearbookscreendisplay.rb +0 -0
- data/code/superant.com.gutenberg/cleargutenbergfiles.rb +0 -0
- data/code/superant.com.gutenberg/cleargutrecordfiles.rb +0 -0
- data/code/superant.com.gutenberg/copyfilename.rb +0 -0
- data/code/superant.com.gutenberg/createnewnote.rb +1 -1
- data/code/superant.com.gutenberg/deletegutenbergrecord.rb +0 -0
- data/code/superant.com.gutenberg/gutenbergcreatefile.rb +0 -0
- data/code/superant.com.gutenberg/helptexthashload.rb +0 -0
- data/code/superant.com.gutenberg/listnamerecord.rb +0 -0
- data/code/superant.com.gutenberg/listtextfilesgutenberg.rb +0 -0
- data/code/superant.com.gutenberg/loadbookrecord.rb +0 -0
- data/code/superant.com.gutenberg/loadconfigurationrecord.rb +0 -0
- data/code/superant.com.gutenberg/loadconfigurationvariables.rb +0 -0
- data/code/superant.com.gutenberg/openhelpwindow.rb +41 -0
- data/code/superant.com.gutenberg/runbackwindow.rb +0 -0
- data/code/superant.com.gutenberg/rungutenbergwindow.rb +0 -0
- data/code/superant.com.gutenberg/rwdgutenbergbackward.rb +0 -0
- data/code/superant.com.gutenberg/rwdtinkerversion.rb +0 -0
- data/code/superant.com.gutenberg/saveconfigurationrecord.rb +0 -0
- data/code/superant.com.gutenberg/savegutenbergrecord.rb +0 -0
- data/code/superant.com.library/marcsearch.rb +30 -0
- data/code/superant.com.rwdtinkerbackwindow/changelocale.rb +84 -0
- data/code/superant.com.rwdtinkerbackwindow/initiateapplets.rb +30 -102
- data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +2 -0
- data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +2 -0
- data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +3 -1
- data/code/superant.com.rwdtinkerbackwindow/listzips.rb +4 -0
- data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +3 -1
- data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +3 -1
- data/code/superant.com.rwdtinkerbackwindow/showlocaleoptions.rb +9 -0
- data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +1 -0
- data/code/superant.com.rwdtinkerbackwindow/viewlogfile.rb +8 -5
- data/code/zz0applicationend/zz0end.rb +2 -1
- data/configuration/rwdtinker.dist +3 -2
- data/configuration/rwdwgutenberg.dist +3 -3
- data/configuration/tinkerwin2variables.dist +4 -8
- data/gui/tinkerbackwindows/superant.com.backgutenberg/30booklistutilities.rwd +1 -1
- data/gui/tinkerbackwindows/superant.com.backgutenberg/40marctab.rwd +26 -0
- data/gui/tinkerbackwindows/superant.com.backgutenberg/67viewconfiguration.rwd +1 -1
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +1 -1
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/80localechanger.rwd +17 -0
- data/init.rb +53 -156
- data/installed/rwdwgutenberg.inf +0 -1
- data/lang/en/rwdcore/en.po +197 -0
- data/lang/es/rwdcore/es.po +184 -0
- data/lang/fr/rwdcore/fr.po +169 -0
- data/lang/hi/rwdcore/hi.po +173 -0
- data/lang/ja/rwdcore/ja.po +171 -0
- data/lang/nl/rwdcore/nl.po +169 -0
- data/lib/marc.rb +38 -0
- data/lib/marc/constants.rb +14 -0
- data/lib/marc/controlfield.rb +47 -0
- data/lib/marc/datafield.rb +163 -0
- data/lib/marc/dublincore.rb +79 -0
- data/lib/marc/exception.rb +9 -0
- data/lib/marc/reader.rb +186 -0
- data/lib/marc/record.rb +147 -0
- data/lib/marc/subfield.rb +31 -0
- data/lib/marc/writer.rb +87 -0
- data/lib/marc/xmlreader.rb +103 -0
- data/lib/marc/xmlwriter.rb +155 -0
- data/lib/rwdtinker/rwdcodedir.rb +56 -0
- data/lib/rwdtinker/rwdguidir.rb +57 -0
- data/lib/rwdtinker/rwdlangdir.rb +60 -0
- data/lib/rwdtinker/rwdtinkertools.rb +2 -1
- data/lib/zip/ioextras.rb +43 -2
- data/lib/zip/stdrubyext.rb +5 -5
- data/lib/zip/tempfile_bugfixed.rb +2 -2
- data/lib/zip/zip.rb +618 -149
- data/lib/zip/zipfilesystem.rb +59 -8
- data/lib/zip/ziprequire.rb +32 -3
- data/lib/zmarc.rb +140 -0
- data/lib/zoom.so +0 -0
- data/rwd_files/HowTo_Gutenberg.txt +8 -1
- data/rwd_files/HowTo_Tinker.txt +29 -6
- data/rwd_files/Tinkerhelptexthash.txt +84 -0
- data/rwd_files/log/rwdtinker.log +0 -2080
- data/rwd_files/rwdapplications.html +23 -1
- data/rwd_files/rwdgutenberghelpfiles.txt +11 -4
- data/rwdconfig.dist +4 -2
- data/tests/makedist-rwdwgutenberg.rb +1 -1
- data/tests/makedist.rb +1 -1
- data/zips/rwdwfoldeditor-0.07.zip +0 -0
- data/zips/{rwdwgutenberg-0.12.zip → rwdwgutenberg-0.13.zip} +0 -0
- data/zips/rwdwhypernote-0.16.zip +0 -0
- data/zips/rwdwmovies-0.98.zip +0 -0
- data/zips/tinkerbellw-0.04.zip +0 -0
- data/zips/{wrubyslippers-1.07.zip → wrubyslippers-1.08.zip} +0 -0
- metadata +39 -14
- data/code/01rwdcore/04helptextend.rb +0 -6
- data/code/superant.com.gutenberg/openhelpwindowgutenberg.rb +0 -35
- data/code/superant.com.rwdtinkerbackwindow/helptexthashtinkerwin2.rb +0 -61
- data/lang/en/rwdcore/languagefile.rb +0 -59
- data/lang/es/rwdcore/languagefile-es.rb +0 -63
- data/lang/fr/rwdcore/languagefile.rb +0 -65
- data/lang/jp/rwdcore/languagefile.rb +0 -73
- data/lang/nl/rwdcore/languagefile.rb +0 -76
- data/rwdgutenberg.rb +0 -1
- data/zips/rwdwfoldeditor-0.05.zip +0 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
module MARC
|
2
|
+
|
3
|
+
# A class for mapping MARC records to Dublin Core
|
4
|
+
|
5
|
+
class DublinCore
|
6
|
+
|
7
|
+
def self.map(record)
|
8
|
+
dc_hash = Hash.new
|
9
|
+
dc_hash['title'] = get_field_value(record['245']['a'])
|
10
|
+
|
11
|
+
# Creator
|
12
|
+
[100, 110, 111, 700, 710, 711, 720].each do |field|
|
13
|
+
dc_hash['creator'] ||= []
|
14
|
+
dc_hash['creator'] << get_field_value(record[field.to_s])
|
15
|
+
end
|
16
|
+
|
17
|
+
# Subject
|
18
|
+
[600, 610, 611, 630, 650, 653].each do |field|
|
19
|
+
dc_hash['subject'] ||= []
|
20
|
+
dc_hash['subject'] << get_field_value(record[field.to_s])
|
21
|
+
end
|
22
|
+
|
23
|
+
# Description
|
24
|
+
[500..599].each do |field|
|
25
|
+
next if [506, 530, 540, 546].include?(field)
|
26
|
+
dc_hash['description'] ||= []
|
27
|
+
dc_hash['description'] << get_field_value(record[field.to_s])
|
28
|
+
end
|
29
|
+
|
30
|
+
dc_hash['publisher'] = get_field_value(record['260']['a']['b']) rescue nil
|
31
|
+
dc_hash['date'] = get_field_value(record['260']['c']) rescue nil
|
32
|
+
dc_hash['type'] = get_field_value(record['655'])
|
33
|
+
dc_hash['format'] = get_field_value(record['856']['q']) rescue nil
|
34
|
+
dc_hash['identifier'] = get_field_value(record['856']['u']) rescue nil
|
35
|
+
dc_hash['source'] = get_field_value(record['786']['o']['t']) rescue nil
|
36
|
+
dc_hash['language'] = get_field_value(record['546'])
|
37
|
+
|
38
|
+
dc_hash['relation'] = []
|
39
|
+
dc_hash['relation'] << get_field_value(record['530'])
|
40
|
+
[760..787].each do |field|
|
41
|
+
dc_hash['relation'] << get_field_value(record[field.to_s]['o']['t']) rescue nil
|
42
|
+
end
|
43
|
+
|
44
|
+
[651, 752].each do |field|
|
45
|
+
dc_hash['coverage'] ||= []
|
46
|
+
dc_hash['coverage'] << get_field_value(record[field.to_s])
|
47
|
+
end
|
48
|
+
|
49
|
+
[506, 540].each do |field|
|
50
|
+
dc_hash['rights'] ||= []
|
51
|
+
dc_hash['rights'] << get_field_value(record[field.to_s])
|
52
|
+
end
|
53
|
+
|
54
|
+
dc_hash.keys.each do |key|
|
55
|
+
dc_hash[key].flatten! if dc_hash[key].respond_to?(:flatten!)
|
56
|
+
dc_hash[key].compact! if dc_hash[key].respond_to?(:compact!)
|
57
|
+
end
|
58
|
+
|
59
|
+
dc_hash
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.get_field_value(field)
|
63
|
+
return if field.nil?
|
64
|
+
|
65
|
+
if !field.kind_of?(String) && field.respond_to?(:each)
|
66
|
+
values = []
|
67
|
+
field.each do |element|
|
68
|
+
values << get_field_value(element)
|
69
|
+
end
|
70
|
+
values
|
71
|
+
else
|
72
|
+
return field if field.kind_of?(String)
|
73
|
+
return field.value if field.respond_to?(:value)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
data/lib/marc/reader.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
module MARC
|
2
|
+
|
3
|
+
class Reader
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
# The constructor which you may pass either a path
|
7
|
+
#
|
8
|
+
# reader = MARC::Reader.new('marc.dat')
|
9
|
+
#
|
10
|
+
# or, if it's more convenient a File object:
|
11
|
+
#
|
12
|
+
# fh = File.new('marc.dat')
|
13
|
+
# reader = MARC::Reader.new(fh)
|
14
|
+
#
|
15
|
+
# or really any object that responds to read(n)
|
16
|
+
#
|
17
|
+
# # marc is a string with a bunch of records in it
|
18
|
+
# reader = MARC::Reader.new(StringIO.new(reader))
|
19
|
+
|
20
|
+
def initialize(file)
|
21
|
+
if file.class == String:
|
22
|
+
@handle = File.new(file)
|
23
|
+
elsif file.respond_to?("read", 5)
|
24
|
+
@handle = file
|
25
|
+
else
|
26
|
+
throw "must pass in path or file"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# to support iteration:
|
31
|
+
# for record in reader
|
32
|
+
# print record
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# and even searching:
|
36
|
+
# record.find { |f| f['245'] =~ /Huckleberry/ }
|
37
|
+
|
38
|
+
def each
|
39
|
+
# while there is data left in the file
|
40
|
+
while rec_length_s = @handle.read(5)
|
41
|
+
# make sure the record length looks like an integer
|
42
|
+
rec_length_i = rec_length_s.to_i
|
43
|
+
if rec_length_i == 0:
|
44
|
+
raise MARC::Exception.new("invalid record length: #{rec_length_s}")
|
45
|
+
end
|
46
|
+
|
47
|
+
# get the raw MARC21 for a record back from the file
|
48
|
+
# using the record length
|
49
|
+
raw = rec_length_s + @handle.read(rec_length_i-5)
|
50
|
+
|
51
|
+
|
52
|
+
# create a record from the data and return it
|
53
|
+
#record = MARC::Record.new_from_marc(raw)
|
54
|
+
record = MARC::Reader.decode(raw)
|
55
|
+
yield record
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# A static method for turning raw MARC data in transission
|
61
|
+
# format into a MARC::Record object.
|
62
|
+
|
63
|
+
def self.decode(marc, params={})
|
64
|
+
record = Record.new()
|
65
|
+
record.leader = marc[0..LEADER_LENGTH-1]
|
66
|
+
|
67
|
+
# where the field data starts
|
68
|
+
base_address = record.leader[12..16].to_i
|
69
|
+
|
70
|
+
# get the byte offsets from the record directory
|
71
|
+
directory = marc[LEADER_LENGTH..base_address-1]
|
72
|
+
|
73
|
+
throw "invalid directory in record" if directory == nil
|
74
|
+
|
75
|
+
# the number of fields in the record corresponds to
|
76
|
+
# how many directory entries there are
|
77
|
+
num_fields = directory.length / DIRECTORY_ENTRY_LENGTH
|
78
|
+
|
79
|
+
# when operating in forgiving mode we just split on end of
|
80
|
+
# field instead of using calculated byte offsets from the
|
81
|
+
# directory
|
82
|
+
all_fields = marc[base_address..-1].split(END_OF_FIELD)
|
83
|
+
|
84
|
+
0.upto(num_fields-1) do |field_num|
|
85
|
+
|
86
|
+
# pull the directory entry for a field out
|
87
|
+
entry_start = field_num * DIRECTORY_ENTRY_LENGTH
|
88
|
+
entry_end = entry_start + DIRECTORY_ENTRY_LENGTH
|
89
|
+
entry = directory[entry_start..entry_end]
|
90
|
+
|
91
|
+
# extract the tag
|
92
|
+
tag = entry[0..2]
|
93
|
+
|
94
|
+
# get the actual field data
|
95
|
+
# if we were told to be forgiving we just use the
|
96
|
+
# next available chuck of field data that we
|
97
|
+
# split apart based on the END_OF_FIELD
|
98
|
+
field_data = ''
|
99
|
+
if params[:forgiving]
|
100
|
+
field_data = all_fields.shift()
|
101
|
+
|
102
|
+
# otherwise we actually use the byte offsets in
|
103
|
+
# directory to figure out what field data to extract
|
104
|
+
else
|
105
|
+
length = entry[3..6].to_i
|
106
|
+
offset = entry[7..11].to_i
|
107
|
+
field_start = base_address + offset
|
108
|
+
field_end = field_start + length - 1
|
109
|
+
field_data = marc[field_start..field_end]
|
110
|
+
end
|
111
|
+
|
112
|
+
# remove end of field
|
113
|
+
field_data.delete!(END_OF_FIELD)
|
114
|
+
|
115
|
+
# add a control field or data field
|
116
|
+
if tag < '010'
|
117
|
+
record.append(MARC::ControlField.new(tag,field_data))
|
118
|
+
else
|
119
|
+
field = MARC::DataField.new(tag)
|
120
|
+
|
121
|
+
# get all subfields
|
122
|
+
subfields = field_data.split(SUBFIELD_INDICATOR)
|
123
|
+
|
124
|
+
# must have at least 2 elements (indicators, and 1 subfield)
|
125
|
+
# TODO some sort of logging?
|
126
|
+
next if subfields.length() < 2
|
127
|
+
|
128
|
+
# get indicators
|
129
|
+
indicators = subfields.shift()
|
130
|
+
field.indicator1 = indicators[0,1]
|
131
|
+
field.indicator2 = indicators[1,1]
|
132
|
+
|
133
|
+
# add each subfield to the field
|
134
|
+
subfields.each() do |data|
|
135
|
+
subfield = MARC::Subfield.new(data[0,1],data[1..-1])
|
136
|
+
field.append(subfield)
|
137
|
+
end
|
138
|
+
|
139
|
+
# add the field to the record
|
140
|
+
record.append(field)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
return record
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
# Like Reader ForgivingReader lets you read in a batch of MARC21 records
|
150
|
+
# but it does not use record lengths and field byte offets found in the
|
151
|
+
# leader and directory. It is not unusual to run across MARC records
|
152
|
+
# which have had their offsets calcualted wrong. In situations like this
|
153
|
+
# the vanilla Reader may fail, and you can try to use ForgivingReader.
|
154
|
+
|
155
|
+
# The one downside to this is that ForgivingReader will assume that the
|
156
|
+
# order of the fields in the directory is the same as the order of fields
|
157
|
+
# in the field data. Hopefully this will be the case, but it is not
|
158
|
+
# 100% guranteed which is why the normal behavior of Reader is encouraged.
|
159
|
+
|
160
|
+
class ForgivingReader
|
161
|
+
include Enumerable
|
162
|
+
|
163
|
+
def initialize(file)
|
164
|
+
if file.class == String
|
165
|
+
@handle = File.new(file)
|
166
|
+
elsif file.respond_to?("read", 5)
|
167
|
+
@handle = file
|
168
|
+
else
|
169
|
+
throw "must pass in path or File object"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
def each
|
175
|
+
@handle.each_line(END_OF_RECORD) do |raw|
|
176
|
+
begin
|
177
|
+
record = MARC::Reader.decode(raw, :forgiving => true)
|
178
|
+
yield record
|
179
|
+
rescue StandardError => e
|
180
|
+
# caught exception just keep barrelling along
|
181
|
+
# TODO add logging
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
data/lib/marc/record.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
module MARC
|
2
|
+
|
3
|
+
# A class that represents an individual MARC record. Every record
|
4
|
+
# is made up of a collection of MARC::DataField objects.
|
5
|
+
#
|
6
|
+
# MARC::Record mixes in Enumerable to enable access to constituent
|
7
|
+
# DataFields. For example, to return a list of all subject DataFields:
|
8
|
+
#
|
9
|
+
# record.find_all {|field| field.tag =~ /^6../}
|
10
|
+
#
|
11
|
+
# The accessor 'fields' is also an Array of MARC::DataField objects which
|
12
|
+
# the client can access or modifyi if neccesary.
|
13
|
+
#
|
14
|
+
# record.fields.delete(field)
|
15
|
+
#
|
16
|
+
# Other accessor attribute: 'leader' for record leader as String
|
17
|
+
|
18
|
+
class Record
|
19
|
+
include Enumerable
|
20
|
+
|
21
|
+
# the record fields
|
22
|
+
attr_accessor :fields
|
23
|
+
|
24
|
+
# the record leader
|
25
|
+
attr_accessor :leader
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@fields = []
|
29
|
+
# leader is 24 bytes
|
30
|
+
@leader = ' ' * 24
|
31
|
+
# leader defaults:
|
32
|
+
# http://www.loc.gov/marc/bibliographic/ecbdldrd.html
|
33
|
+
@leader[10..11] = '22'
|
34
|
+
@leader[20..23] = '4500'
|
35
|
+
end
|
36
|
+
|
37
|
+
# add a field to the record
|
38
|
+
# record.append(MARC::DataField.new( '100', '2', '0', ['a', 'Fred']))
|
39
|
+
|
40
|
+
def append(field)
|
41
|
+
@fields.push(field)
|
42
|
+
end
|
43
|
+
|
44
|
+
# alias to append
|
45
|
+
|
46
|
+
def <<(field)
|
47
|
+
append(field)
|
48
|
+
end
|
49
|
+
|
50
|
+
# each() is here to support iterating and searching since MARC::Record
|
51
|
+
# mixes in Enumberable
|
52
|
+
#
|
53
|
+
# iterating through the fields in a record:
|
54
|
+
# record.each { |f| print f }
|
55
|
+
#
|
56
|
+
# getting the 245
|
57
|
+
# title = record.find {|f| f.tag == '245'}
|
58
|
+
#
|
59
|
+
# getting all subjects
|
60
|
+
# subjects = record.find_all {|f| ('600'..'699') === f.tag}
|
61
|
+
|
62
|
+
def each
|
63
|
+
for field in @fields
|
64
|
+
yield field
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# You can lookup fields using this shorthand:
|
69
|
+
# title = record['245']
|
70
|
+
|
71
|
+
def [](tag)
|
72
|
+
return self.find {|f| f.tag == tag}
|
73
|
+
end
|
74
|
+
|
75
|
+
# Factory method for creating a MARC::Record from MARC21 in
|
76
|
+
# transmission format.
|
77
|
+
#
|
78
|
+
# record = MARC::Record.new_from_marc(marc21)
|
79
|
+
#
|
80
|
+
# in cases where you might be working with somewhat flawed
|
81
|
+
# MARC data you may want to use the :forgiving parameter which
|
82
|
+
# will bypass using field byte offsets and simply look for the
|
83
|
+
# end of field byte to figure out the end of fields.
|
84
|
+
#
|
85
|
+
# record = MARC::Record.new_from_marc(marc21, :forgiving => true)
|
86
|
+
|
87
|
+
def self.new_from_marc(raw, params={})
|
88
|
+
return MARC::Reader.decode(raw, params)
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# Returns a record in MARC21 transmission format (ANSI Z39.2).
|
93
|
+
# Really this is just a wrapper around MARC::MARC21::encode
|
94
|
+
#
|
95
|
+
# marc = record.to_marc()
|
96
|
+
|
97
|
+
def to_marc
|
98
|
+
return MARC::Writer.encode(self)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Handy method for returning the MARCXML serialization for a
|
102
|
+
# MARC::Record object. You'll get back a REXML::Document object.
|
103
|
+
# Really this is just a wrapper around MARC::XMLWriter::encode
|
104
|
+
#
|
105
|
+
# xml_doc = record.to_xml()
|
106
|
+
|
107
|
+
def to_xml
|
108
|
+
return MARC::XMLWriter.encode(self, :include_namespace => true)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Handy method for returning a hash mapping this records values
|
112
|
+
# to the Dublin Core.
|
113
|
+
#
|
114
|
+
# dc = record.to_dublin_core()
|
115
|
+
# print dc['title']
|
116
|
+
|
117
|
+
def to_dublin_core
|
118
|
+
return MARC::DublinCore.map(self)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns a string version of the record, suitable for printing
|
122
|
+
|
123
|
+
def to_s
|
124
|
+
str = "LEADER #{leader}\n"
|
125
|
+
for field in fields:
|
126
|
+
str += field.to_s() + "\n"
|
127
|
+
end
|
128
|
+
return str
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
# For testing if two records can be considered equal.
|
133
|
+
|
134
|
+
def ==(other)
|
135
|
+
return self.to_s == other.to_s
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
# Handy for using a record in a regex:
|
140
|
+
# if record =~ /Gravity's Rainbow/ then print "Slothrop" end
|
141
|
+
|
142
|
+
def =~(regex)
|
143
|
+
return self.to_s =~ regex
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module MARC
|
2
|
+
|
3
|
+
# A class that represents an individual subfield within a DataField.
|
4
|
+
# Accessor attributes include: code (letter subfield code) and value
|
5
|
+
# (the content of the subfield). Both can be empty string, but should
|
6
|
+
# not be set to nil.
|
7
|
+
|
8
|
+
class Subfield
|
9
|
+
attr_accessor :code, :value
|
10
|
+
|
11
|
+
def initialize(code='' ,value='')
|
12
|
+
# can't allow code of value to be nil
|
13
|
+
# or else it'll screw us up later on
|
14
|
+
@code = code == nil ? '' : code
|
15
|
+
@value = value == nil ? '' : value
|
16
|
+
end
|
17
|
+
|
18
|
+
def ==(other)
|
19
|
+
if @code != other.code
|
20
|
+
return false
|
21
|
+
elsif @value != other.value
|
22
|
+
return false
|
23
|
+
end
|
24
|
+
return true
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
return "$#{code} #{value} "
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|