marcspec 0.2.1

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.
Files changed (37) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +59 -0
  5. data/Rakefile +58 -0
  6. data/VERSION +1 -0
  7. data/lib/marcspec/customspec.rb +97 -0
  8. data/lib/marcspec/kvmap.rb +79 -0
  9. data/lib/marcspec/map.rb +67 -0
  10. data/lib/marcspec/marcfieldspec.rb +205 -0
  11. data/lib/marcspec/multivaluemap.rb +62 -0
  12. data/lib/marcspec/solrfieldspec.rb +123 -0
  13. data/lib/marcspec/specset.rb +58 -0
  14. data/lib/marcspec.rb +11 -0
  15. data/lib/orig.rb +288 -0
  16. data/spec/data/batch.dat +1 -0
  17. data/spec/data/one.dat +1 -0
  18. data/spec/data/umich/translation_maps/area_map.properties +1039 -0
  19. data/spec/data/umich/translation_maps/availability_map_ht.properties +9 -0
  20. data/spec/data/umich/translation_maps/availability_map_umich.properties +6 -0
  21. data/spec/data/umich/translation_maps/callnumber_map.properties +21 -0
  22. data/spec/data/umich/translation_maps/callnumber_subject_map.properties +214 -0
  23. data/spec/data/umich/translation_maps/country_map.properties +320 -0
  24. data/spec/data/umich/translation_maps/format_map.properties +47 -0
  25. data/spec/data/umich/translation_maps/format_map_umich.properties +35 -0
  26. data/spec/data/umich/translation_maps/ht_namespace_map.properties +10 -0
  27. data/spec/data/umich/translation_maps/institution_map.properties +11 -0
  28. data/spec/data/umich/translation_maps/language_map.properties +489 -0
  29. data/spec/data/umich/translation_maps/library_map.properties +48 -0
  30. data/spec/data/umich/translation_maps/location_map.properties +345 -0
  31. data/spec/data/umich/umich_index.properties +130 -0
  32. data/spec/maps_spec.rb +91 -0
  33. data/spec/marcfieldspecs_spec.rb +109 -0
  34. data/spec/marcspec_spec.rb +10 -0
  35. data/spec/solrfieldspec_spec.rb +177 -0
  36. data/spec/spec_helper.rb +16 -0
  37. metadata +166 -0
@@ -0,0 +1,123 @@
1
+ require 'stringio'
2
+ module MARCSpec
3
+ class SolrFieldSpec
4
+ attr_accessor :solrField, :first, :map, :noMapKeyDefault, :marcfieldspecs, :default
5
+
6
+ def initialize(opts)
7
+ @solrField = opts[:solrField]
8
+ @first = opts[:firstOnly] || false
9
+ @default = opts[:default] || nil
10
+ @map = opts[:map] || nil
11
+ @noMapKeyDefault = opts[:noMapKeyDefault] || nil
12
+ @marcfieldspecs = []
13
+ end
14
+
15
+ def << tagspec
16
+ @marcfieldspecs << tagspec
17
+ end
18
+
19
+
20
+ def raw_marc_values r
21
+ vals = []
22
+ @marcfieldspecs.each do |ts|
23
+ vals.concat ts.marc_values(r)
24
+ end
25
+ return vals
26
+ end
27
+
28
+ def marc_values r
29
+ vals = raw_marc_values r
30
+ unless vals.is_a? Array
31
+ vals = [vals]
32
+ end
33
+
34
+ if @first
35
+ vals = [vals.compact.first].compact
36
+ end
37
+
38
+ # If we got nothing, just return either nothing or the defualt,
39
+ # if there is one. Don't screw around with mapping.
40
+ if vals.size == 0
41
+ if @default.nil? # unless there's a default value, just return nothing
42
+ return []
43
+ else
44
+ return [@default]
45
+ end
46
+ end
47
+
48
+ # If we've got a map, map it.
49
+
50
+ if (@map)
51
+ vals.map! {|v| @map[v, @noMapKeyDefault]}
52
+ end
53
+
54
+ # Flatten it all out
55
+
56
+ vals.flatten!
57
+ vals.uniq!
58
+ vals.compact!
59
+ return vals
60
+ end
61
+
62
+
63
+ def == other
64
+ return ((other.solrField == self.solrField) and
65
+ (other.first == self.first) and
66
+ (other.map == self.map) and
67
+ (other.noMapKeyDefault == self.noMapKeyDefault) and
68
+ (other.marcfieldspecs == self.marcfieldspecs))
69
+ end
70
+
71
+ def self.fromPPString str
72
+ return self.fromHash eval(str)
73
+ end
74
+
75
+ def self.fromHash h
76
+ sfs = self.new(h)
77
+ h[:specs].each do |s|
78
+ if s.size < 3
79
+ sfs << MARCSpec::ControlFieldSpec.new(*s)
80
+ else
81
+ sfs << MARCSpec::VariableFieldSpec.new(s[0], s[3], s[4])
82
+ end
83
+ end
84
+ return sfs
85
+ end
86
+
87
+ def pretty_print pp
88
+ pp.pp eval(self.asPPString)
89
+ end
90
+
91
+ def asPPString
92
+ s = StringIO.new
93
+ s.print "{\n :solrField=> "
94
+ PP.singleline_pp(@solrField, s)
95
+ s.print(",\n ")
96
+ s.print ":firstOnly => true,\n " if @first
97
+ if @default
98
+ s.print(":default => ")
99
+ PP.singleline_pp(@default, s)
100
+ s.print(",\n ")
101
+ end
102
+ if @map
103
+ s.print(":mapname => ")
104
+ PP.singleline_pp(@map.mapname, s)
105
+ s.print(",\n ")
106
+ end
107
+ if @noMapKeyDefault
108
+ s.print(":noMapKeyDefault => ")
109
+ PP.singleline_pp(@noMapKeyDefault, s)
110
+ s.print(",\n ")
111
+ end
112
+ s.print(":specs => [\n")
113
+ @marcfieldspecs.each do |ts|
114
+ s.print ' '
115
+ PP.singleline_pp(ts, s)
116
+ s.print(",\n")
117
+ end
118
+ s.print " ]\n}"
119
+ return s.string
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,58 @@
1
+ require 'jruby_streaming_update_solr_server'
2
+ module MARCSpec
3
+ class SpecSet
4
+ attr_accessor :tmaps, :solrfieldspecs
5
+
6
+ def initialize
7
+ @tmaps = {}
8
+ @solrfieldspecs = []
9
+ end
10
+
11
+ def map name
12
+ return self.tmaps[name]
13
+ end
14
+
15
+ def loadMapsFromDir dir
16
+ unless File.exist? dir
17
+ raise ArgumentError, "Cannot load maps from #{dir}: does not exist"
18
+ end
19
+ Dir.glob("#{dir}/*.rb").each do |tmapfile|
20
+ self.add_map(MARCSpec::Map.fromFile(tmapfile))
21
+ end
22
+ end
23
+
24
+ def add_map map
25
+ self.tmaps[map.mapname] = map
26
+ end
27
+
28
+ def add_spec solrfieldspec
29
+ self.solrfieldspecs << solrfieldspec
30
+ end
31
+
32
+ alias_method :<<, :add_spec
33
+
34
+ def each
35
+ @solrfieldspecs.each do |fs|
36
+ yield fs
37
+ end
38
+ end
39
+
40
+ def fill_hashlike_from_marc r, hashlike
41
+ @solrfieldspecs.each do |sfs|
42
+ hashlike[sfs.solrField] = sfs.marc_values(r)
43
+ end
44
+ end
45
+
46
+ def doc_from_marc r
47
+ doc = SolrInputDocument.new
48
+ fill_hashlike_from_marc r, doc
49
+ return doc
50
+ end
51
+
52
+ def hash_from_marc r
53
+ h = {}
54
+ fill_hashlike_from_marc r, h
55
+ return h
56
+ end
57
+ end
58
+ end
data/lib/marcspec.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'logger'
2
+
3
+ $LOG = Logger.new(STDOUT)
4
+ $LOG.level = Logger::WARN
5
+
6
+ require "marcspec/customspec"
7
+ require "marcspec/solrfieldspec"
8
+ require "marcspec/kvmap"
9
+ require "marcspec/multivaluemap"
10
+ require "marcspec/specset"
11
+ require "marcspec/marcfieldspec"
data/lib/orig.rb ADDED
@@ -0,0 +1,288 @@
1
+ require 'set'
2
+ require 'pp'
3
+ require 'logger'
4
+
5
+ $LOG ||= Logger.new(STDERR)
6
+
7
+ module MARCSpec
8
+
9
+ class MapSpec
10
+ attr_accessor :map, :type, :default
11
+
12
+ def initialize(type, map, default=nil)
13
+ @type = type
14
+ @default = default
15
+ @map = map
16
+ end
17
+
18
+ def [] key
19
+ if (@type == :kv)
20
+ if @map.has_key? key
21
+ return @map[key]
22
+ else
23
+ return @default
24
+ end
25
+ end
26
+
27
+ # For a pattern, we find all that match.
28
+
29
+ if (@type == :pattern)
30
+ rv = []
31
+ @map.each do |pv|
32
+ pat = pv[0]
33
+ val = pv[1]
34
+ # puts "Trying pattern #{pat} against #{key}"
35
+ if pat.match(key)
36
+ rv << val
37
+ # puts "Matched: adding #{val}"
38
+ end
39
+ end
40
+ rv.uniq!
41
+ if rv.size > 0
42
+ return rv
43
+ else
44
+ return @default
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ class CustomSpec
51
+ def initialize(proc, args)
52
+ @proc = proc
53
+ @args = args
54
+ end
55
+
56
+ def marc_values_hash fieldnames, r
57
+ a = @proc(r, args)
58
+ rv = {}
59
+ fieldnames.each_with_index do |fn, i|
60
+ rv[fn] = a[i]
61
+ end
62
+ return rv
63
+ end
64
+ end
65
+
66
+
67
+ class TagSpec
68
+ attr_accessor :tag, :codes, :joiner, :parent, :ind1, :ind2, :range, :is_control
69
+
70
+ def initialize(tag, codes=nil)
71
+ @codes = Set.new
72
+ @tag = tag
73
+ @joiner = ' '
74
+ @substr = nil
75
+ tagint = tag.to_i
76
+ @is_control = (tagint != 0 and tagint < 10)
77
+ if (codes)
78
+ self.codes = codes
79
+ end
80
+ end
81
+
82
+ def range= newrange
83
+ if newrange =~ /\s*(\d+)-(\d+)/
84
+ start = $1.to_i
85
+ last = $2.to_i
86
+ @range = start..last
87
+ else
88
+ se = newrange.to_i
89
+ @range = se..se
90
+ end
91
+ end
92
+
93
+ def codes= newcodes
94
+ if newcodes.is_a? Range
95
+ @codes = newcodes.to_a
96
+ elsif newcodes !~ /\S/
97
+ @codes = nil
98
+ # Otherwise, just split into individual characters
99
+ else
100
+ @codes = newcodes.split(//)
101
+ end
102
+ end
103
+
104
+ def marc_values r
105
+ if @is_control
106
+ vals = r.find_by_tag(@tag).map {|f| f.value}
107
+ # puts "Start with #{vals.join(', ')}"
108
+ if @range
109
+ vals.map! {|v| v[@range]}
110
+ end
111
+ # puts "End with #{vals.join(', ')}"
112
+
113
+ else
114
+ fields = r.find_by_tag(@tag)
115
+ vals = []
116
+ fields.each do |f|
117
+ subvals = f.sub_values(@codes)
118
+ vals << subvals.join(@joiner) if subvals.size > 0
119
+ end
120
+ end
121
+ # puts vals.join(', ')
122
+ return vals
123
+ end
124
+
125
+ end
126
+
127
+ class FieldSpec
128
+ attr_accessor :field, :first, :map, :tagspecs
129
+
130
+ def initialize(opts)
131
+ @field = opts[:field]
132
+ @first = opts[:first] || false
133
+ @map = opts[:map] || nil
134
+ @tagspecs = []
135
+ end
136
+
137
+ def << tagspec
138
+ tagspec.parent = self
139
+ @tagspecs << tagspec
140
+ end
141
+
142
+ def marc_values r
143
+ vals = []
144
+ # puts "Tagspecs has #{@tagspecs.size} items"
145
+ @tagspecs.each do |ts|
146
+ vals.concat ts.marc_values(r)
147
+ # puts vals.join(', ')
148
+ break if @first and vals.size > 0
149
+ end
150
+
151
+ if (@map)
152
+ vals.map! {|v| @map[v]}
153
+ # vals.each do |v|
154
+ # puts "Map: #{v} => #{@map[v].to_s}"
155
+ # end
156
+ end
157
+ vals.flatten!
158
+ vals.uniq!
159
+ vals.compact!
160
+ return vals
161
+ end
162
+
163
+ end
164
+
165
+
166
+ class SpecSet
167
+ attr_accessor :tmaps, :fieldspecs
168
+ def initialize(*args)
169
+ tmapdir = args.pop!
170
+ unless File.directory? tmapdir
171
+ $LOG.error "Directory #{tmapdir} not found"
172
+ raise LoadError, "Directory #{tmapdir} not found"
173
+ end
174
+
175
+ @tmaps = {}
176
+ Dir.glob(tmapdir + '/*.rb') do |fn|
177
+ basename = File.basename(fn).sub(/\.rb$/, '')
178
+ $LOG.info "Loading translation map #{basename}"
179
+
180
+ begin
181
+ rawmap = eval(File.open(fn).read)
182
+ @tmaps[basename] = MapSpec.new(rawmap[:type], rawmap[:map], rawmap[:default])
183
+ rescue SyntaxError
184
+ $LOG.error "Error processing translation map file #{fn}: #{$!}"
185
+ raise SyntaxError, $!
186
+ end
187
+
188
+ end
189
+
190
+ @fieldspecs = []
191
+
192
+ # Get the index files
193
+ args.each do |indexfile|
194
+ begin
195
+ unless File.exists? indexfile
196
+ $LOG.error "File #{indexfile} does not exist"
197
+ raise LoadError, "File #{indexfile} does not exist"
198
+ end
199
+ $LOG.info "Loading index file #{indexfile}"
200
+ rawindex = eval(File.open(indexfile).read)
201
+ rawindex.each do |entry|
202
+ fs = FieldSpec.new(:field => entry[:solrField], :first=>entry[:firstOnly])
203
+ mapname = entry[:map]
204
+ if mapname
205
+ if @tmaps.has_key? mapname
206
+ fs.map = @tmaps[mapname]
207
+ else
208
+ $LOG.error "Can't find map #{mapname}"
209
+ end
210
+ end
211
+ entry[:specs].each do |entryts|
212
+
213
+ # A one- or two-element entry is a control field
214
+ # A three element entry (tag, ind1, ind2) is all subs of a field (need to implement)
215
+ # A four element field is tag, ind1, ind2, subs
216
+ # A five element field is tag, ind1, ind2, subs, joiner
217
+
218
+
219
+ tag = entryts[0]
220
+
221
+ # Is tag the symbol :custom? Then make it a custom item
222
+
223
+ if tag == :custom
224
+ ts = CustomSpec.new(entryts[1], entryts[2..-1])
225
+ fs << ts
226
+ next
227
+ end
228
+
229
+ # If it's not custom, the solrField better be a scale
230
+ if entry[:solrField].is_a? Array
231
+ # log an error and bail out
232
+ end
233
+
234
+ # Otherwise, it's a tag spec
235
+ if tag.is_a? Fixnum
236
+ tag = '%03d' % tag
237
+ end
238
+
239
+
240
+ ts = TagSpec.new(tag)
241
+ if entryts.size < 3
242
+ ts.is_control = true
243
+ ts.range = entryts[1] if entryts[1]
244
+ else
245
+ ts.ind1 = entryts[1]
246
+ ts.ind2 = entryts[2]
247
+ ts.codes = entryts[3]
248
+ ts.joiner = entryts[4] if entryts[4]
249
+ end
250
+ fs << ts
251
+ end
252
+ self << fs
253
+ end
254
+ rescue SyntaxError
255
+ $LOG.error "Error processing index file #{indexfile}: #{$!}"
256
+ raise SyntaxError
257
+ end
258
+ end
259
+ end
260
+
261
+ def each
262
+ @fieldspecs.each do |fs|
263
+ yield fs
264
+ end
265
+ end
266
+
267
+ def << fieldspec
268
+ @fieldspecs << fieldspec
269
+ end
270
+
271
+ def doc_from_marc r
272
+ doc = SolrInputDocument.new
273
+ @fieldspecs.each do |fs|
274
+ doc[fs.field] = fs.marc_values(r)
275
+ end
276
+ return doc
277
+ end
278
+
279
+ def hash_from_marc r
280
+ h = {}
281
+ @fieldspecs.each do |fs|
282
+ h[fs.field] = fs.marc_values(r)
283
+ end
284
+ return h
285
+ end
286
+
287
+ end
288
+ end
@@ -0,0 +1 @@
1
+ 00755cam 22002414a 4500001001300000003000600013005001700019008004100036010001700077020004300094040001800137042000800155050002600163082001700189100003100206245005400237260004200291300007200333500003300405650003700438630002500475630001300500fol05731351 IMchF20000613133448.0000107s2000 nyua 001 0 eng  a 00020737  a0471383147 (paper/cd-rom : alk. paper) aDLCcDLCdDLC apcc00aQA76.73.P22bM33 200000a005.13/32211 aMartinsson, Tobias,d1976-10aActivePerl with ASP and ADO /cTobias Martinsson. aNew York :bJohn Wiley & Sons,c2000. axxi, 289 p. :bill. ;c23 cm. +e1 computer laser disc (4 3/4 in.) a"Wiley Computer Publishing." 0aPerl (Computer program language)00aActive server pages.00aActiveX.00647pam 2200241 a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001800109042000800127050002600135082001500161100002600176245006700202260003800269263000900307300001100316650003700327650002500364700001600389fol05754809 IMchF20000601115601.0000203s2000 mau 001 0 eng  a 00022023  a1565926994 aDLCcDLCdDLC apcc00aQA76.73.P22bD47 200000a005.742211 aDescartes, Alligator.10aProgramming the Perl DBI /cAlligator Descartes and Tim Bunce. aCmabridge, MA :bO'Reilly,c2000. a1111 ap. cm. 0aPerl (Computer program language) 0aDatabase management.1 aBunce, Tim.00605cam 22002054a 4500001001300000003000600013005001700019008004100036010001700077040001800094042000800112050002700120082001700147100002100164245005500185260004500240300002600285504005100311650003700362fol05843555 IMchF20000525142739.0000318s1999 cau b 001 0 eng  a 00501349  aDLCcDLCdDLC apcc00aQA76.73.P22bB763 199900a005.13/32211 aBrown, Martin C.10aPerl :bprogrammer's reference /cMartin C. Brown. aBerkeley :bOsborne/McGraw-Hill,cc1999. axix, 380 p. ;c22 cm. aIncludes bibliographical references and index. 0aPerl (Computer program language)00579cam 22002054a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001800109042000800127050002700135082001700162100002100179245005500200260004500255300003600300650003700336fol05843579 IMchF20000525142716.0000318s1999 caua 001 0 eng  a 00502116  a0072120002 aDLCcDLCdDLC apcc00aQA76.73.P22bB762 199900a005.13/32211 aBrown, Martin C.10aPerl :bthe complete reference /cMartin C. Brown. aBerkeley :bOsborne/McGraw-Hill,cc1999. axxxv, 1179 p. :bill. ;c24 cm. 0aPerl (Computer program language)00801nam 22002778a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001300109042000800122050002600130082001800156100002000174245008800194250003200282260004100314263000900355300001100364650003700375650003600412650002600448700002500474700002400499fol05848297 IMchF20000524125727.0000518s2000 mau 001 0 eng  a 00041664  a1565924193 aDLCcDLC apcc00aQA76.73.P22bG84 200000a005.2/7622211 aGuelich, Scott.10aCGI programming with Perl /cScott Guelich, Shishir Gundavaram & Gunther Birznieks. a2nd ed., expanded & updated aCambridge, Mass. :bO'Reilly,c2000. a0006 ap. cm. 0aPerl (Computer program language) 0aCGI (Computer network protocol) 0aInternet programming.1 aGundavaram, Shishir.1 aBirznieks, Gunther.00665nam 22002298a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001300109042000800122050002700130082001700157111005200174245008600226250001200312260004100324263000900365300001100374650005000385fol05865950 IMchF20000615103017.0000612s2000 mau 100 0 eng  a 00055759  a0596000138 aDLCcDLC apcc00aQA76.73.P22bP475 200000a005.13/32212 aPerl Conference 4.0d(2000 :cMonterey, Calif.)10aProceedings of the Perl Conference 4.0 :bJuly 17-20, 2000, Monterey, California. a1st ed. aCambridge, Mass. :bO'Reilly,c2000. a0006 ap. cm. 0aPerl (Computer program language)vCongresses.00579nam 22002178a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001300109042000800122050002600130082001700156100002800173245006200201260004100263263000900304300001100313650003700324fol05865956 IMchF20000615102948.0000612s2000 mau 000 0 eng  a 00055770  a1565926099 aDLCcDLC apcc00aQA76.73.P22bB43 200000a005.13/32211 aBlank-Edelman, David N.10aPerl for system administration /cDavid N. Blank-Edelman. aCambridge, Mass. :bO'Reilly,c2000. a0006 ap. cm. 0aPerl (Computer program language)00661nam 22002538a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001300109042000800122050002600130082001700156100001700173245006700190250001200257260004100269263000900310300001100319650003700330700002300367700001700390fol05865967 IMchF20000615102611.0000614s2000 mau 000 0 eng  a 00055799  a0596000278 aDLCcDLC apcc00aQA76.73.P22bW35 200000a005.13/32211 aWall, Larry.10aProgramming Perl /cLarry Wall, Tom Christiansen & Jon Orwant. a3rd ed. aCambridge, Mass. :bO'Reilly,c2000. a0007 ap. cm. 0aPerl (Computer program language)1 aChristiansen, Tom.1 aOrwant, Jon.00603cam 22002054a 4500001001300000003000600013005001700019008004100036010001700077020001500094040001800109042000800127050002600135082001700161100003200178245006000210260005700270300003300327650003700360fol05872355 IMchF20000706095105.0000315s1999 njua 001 0 eng  a 00500678  a013020868X aDLCcDLCdDLC apcc00aQA76.73.P22bL69 199900a005.13/32211 aLowe, Vincentq(Vincent D.)10aPerl programmer's interactive workbook /cVincent Lowe. aUpper Saddle River, NJ :bPrentice Hall PTP,cc1999. axx, 633 p. :bill. ;c23 cm. 0aPerl (Computer program language)00696nam 22002538a 4500001001300000003000600013005001700019008004100036010001700077020002800094040001300122042000800135050002600143082001700169100002600186245004400212260005100256263000900307300001100316500002000327650003700347650001700384650004100401fol05882032 IMchF20000707091904.0000630s2000 cau 001 0 eng  a 00058174  a0764547291 (alk. paper) aDLCcDLC apcc00aQA76.73.P22bF64 200000a005.13/32212 aFoster-Johnson, Eric.10aCross-platform Perl /cEric F. Johnson. aFoster City, CA :bIDG Books Worldwide,c2000. a0009 ap. cm. aIncludes index. 0aPerl (Computer program language) 0aWeb servers. 0aCross-platform software development.
data/spec/data/one.dat ADDED
@@ -0,0 +1 @@
1
+ 00734njm a2200217uu 4500001001500000003000400015005001700019007001500036008004100051010001900092040001300111245006800124260002600192300005600218651004500274700005400319700005500373700003000428852005000458852000800508afc99990058366DLC20071104155141.9sd ummunniauub071103s1939 xxufmnne||||||||| u eng|| aafc99990058366 aDLCcDLC04aThe Texas rangerh[sound recording] /cSung by Beale D. Taylor. aMedina, Texas,c1939. a1 sound disc :banalog, 33 1/3 rpm, mono. ;c12 in. 0aMedinazTexaszUnited States of America.1 aLomax, John Avery, 1867-1948eRecording engineer.1 aLomax, Ruby T. (Ruby Terrill)eRecording engineer.1 aTaylor, Beale D.eSinger. aAmerican Folklife Center, Library of Congress aDLC