zcc 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +13 -0
- data/Manifest.txt +36 -1
- data/Rakefile +6 -1
- data/bin/zcc +98 -132
- data/{bin → examples}/linter.pl +0 -0
- data/examples/zcc.yaml +22 -10
- data/examples/zebra/README +2 -0
- data/examples/zebra/key/empty +1 -0
- data/examples/zebra/lock/empty +1 -0
- data/examples/zebra/records/examples/0.xml +1 -0
- data/examples/zebra/records/examples/1.xml +1 -0
- data/examples/zebra/records/examples/2.xml +1 -0
- data/examples/zebra/records/examples/3.xml +1 -0
- data/examples/zebra/records/examples/4.xml +1 -0
- data/examples/zebra/records/examples/5.xml +1 -0
- data/examples/zebra/records/examples/6.xml +1 -0
- data/examples/zebra/records/examples/7.xml +1 -0
- data/examples/zebra/records/examples/8.xml +1 -0
- data/examples/zebra/records/examples/9.xml +1 -0
- data/examples/zebra/register/empty +1 -0
- data/examples/zebra/shadow/empty +1 -0
- data/examples/zebra/tab/bib1.abs +151 -0
- data/examples/zebra/tab/bib1.att +151 -0
- data/examples/zebra/tab/default.idx +57 -0
- data/examples/zebra/tab/explain.abs +224 -0
- data/examples/zebra/tab/explain.att +27 -0
- data/examples/zebra/tab/explain.tag +175 -0
- data/examples/zebra/tab/gils.att +79 -0
- data/examples/zebra/tab/kohalis +1 -0
- data/examples/zebra/tab/numeric.chr +13 -0
- data/examples/zebra/tab/record.abs +66 -0
- data/examples/zebra/tab/sort-string-utf.chr +48 -0
- data/examples/zebra/tab/tagsetm.tag +35 -0
- data/examples/zebra/tab/usmarc.mar +3 -0
- data/examples/zebra/tab/word-phrase-utf.chr +41 -0
- data/examples/zebra/tmp/empty +1 -0
- data/examples/zebra/zebra.cfg +39 -0
- data/lib/zcc/marcadditions.rb +32 -10
- data/lib/zcc/pickers.rb +105 -29
- data/lib/zcc/subfieldeditor.rb +70 -0
- data/lib/zcc/version.rb +1 -1
- data/lib/zcc/zoomer.rb +72 -0
- data/website/index.html +1 -1
- data/website/koha.html +2 -2
- data/website/koha.txt +7 -5
- data/website/zcc.html +59 -31
- data/website/zcc.txt +52 -23
- data/website/zebra.html +80 -0
- data/website/zebra.txt +36 -0
- metadata +76 -6
@@ -0,0 +1,41 @@
|
|
1
|
+
# Generic character map.
|
2
|
+
#
|
3
|
+
# $Id: word-phrase-utf.chr,v 1.1.2.1 2006/07/03 21:56:45 kados Exp $
|
4
|
+
|
5
|
+
# Define the basic value-set. *Beware* of changing this without re-indexing
|
6
|
+
# your databases.
|
7
|
+
lowercase {0-9}{a-y}�z�����
|
8
|
+
uppercase {0-9}{A-Y}�Z�����
|
9
|
+
|
10
|
+
# Breaking characters
|
11
|
+
|
12
|
+
space {\001-\040}!"#$%&'\()*+,-./:;<=>?@\[\\]^_`\{|}~
|
13
|
+
|
14
|
+
# Characters to be considered equivalent for searching purposes.
|
15
|
+
|
16
|
+
# equivalent ��(ae)
|
17
|
+
# equivalent ��(oe)
|
18
|
+
# equivalent �(aa)
|
19
|
+
# equivalent u�
|
20
|
+
|
21
|
+
# Supplemental mappings
|
22
|
+
|
23
|
+
#map (ä) �
|
24
|
+
#map (æ) �
|
25
|
+
#map (ø) �
|
26
|
+
#map (å) �
|
27
|
+
#map (ö) �
|
28
|
+
#map (Ä) �
|
29
|
+
#map (&Aelig;) �
|
30
|
+
#map (Ø) �
|
31
|
+
#map (Å) �
|
32
|
+
#map (Ö) �
|
33
|
+
|
34
|
+
#map �� e
|
35
|
+
#map � a
|
36
|
+
#map � o
|
37
|
+
#map � i
|
38
|
+
|
39
|
+
#map (Aa) (AA)
|
40
|
+
|
41
|
+
#map (aa) a
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# ZCC
|
2
|
+
# Simple Zebra configuration file that defines
|
3
|
+
# MARC21 records
|
4
|
+
#
|
5
|
+
# Where are the config files located?
|
6
|
+
profilePath:/home/jason/.zcc/zebra/tab:/usr/share/idzebra-2.0/tab
|
7
|
+
# modulePath - where to look for loadable zebra modules
|
8
|
+
modulePath: /usr/lib/idzebra-2.0/modules
|
9
|
+
|
10
|
+
encoding: UTF-8
|
11
|
+
# Files that describe the attribute sets supported.
|
12
|
+
attset: bib1.att
|
13
|
+
attset: explain.att
|
14
|
+
attset: gils.att
|
15
|
+
|
16
|
+
# systag sysno rank
|
17
|
+
# Specify record type
|
18
|
+
recordId: file
|
19
|
+
recordType: grs.xml
|
20
|
+
storeKeys: 1
|
21
|
+
|
22
|
+
#added for public server
|
23
|
+
database: zcc
|
24
|
+
|
25
|
+
|
26
|
+
# Lock File Area
|
27
|
+
lockDir: /home/jason/.zcc/zebra/lock
|
28
|
+
perm.anonymous:r
|
29
|
+
register: /home/jason/.zcc/zebra/register:1G
|
30
|
+
|
31
|
+
# Temp File area for result sets
|
32
|
+
setTmpDir: /home/jason/.zcc/zebra/tmp
|
33
|
+
|
34
|
+
# Temp File area for index program
|
35
|
+
keyTmpDir: /home/jason/.zcc/zebra/key
|
36
|
+
|
37
|
+
# Approx. Memory usage during indexing
|
38
|
+
memMax: 50M
|
39
|
+
rank:rank-1
|
data/lib/zcc/marcadditions.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#MARCAdditions are some useful additions made for processing MARC records.
|
2
|
-
module
|
3
|
-
|
2
|
+
module MARC
|
3
|
+
class Record
|
4
4
|
# linter depends on Perl's MARC::Lint and hence Perl's MARC::Record
|
5
5
|
# Use cpan to install them.
|
6
6
|
def linter
|
@@ -21,7 +21,7 @@ module MARCAdditions
|
|
21
21
|
#STDIN.gets
|
22
22
|
#puts
|
23
23
|
#contents = `perl linter.pl "#{self}"`
|
24
|
-
contents = `perl linter.pl "#{xml_rec}"`
|
24
|
+
contents = `perl "#{File.expand_path("~")}"/.zcc/linter.pl "#{xml_rec}"`
|
25
25
|
|
26
26
|
|
27
27
|
#aFile = File.new("temp_lint.mrc","w")
|
@@ -47,7 +47,7 @@ module MARCAdditions
|
|
47
47
|
|
48
48
|
def blank_field_prompt(field, subfield)
|
49
49
|
#puts "subfield: #{subfield}"
|
50
|
-
|
50
|
+
print "\nYour MARC record does not contain #{field}#{subfield}.\nEnter the intended value for #{field}#{subfield} or hit ENTER to leave blank\n#{field}#{subfield} > "
|
51
51
|
value = STDIN.gets.chomp
|
52
52
|
value
|
53
53
|
end
|
@@ -57,9 +57,8 @@ module MARCAdditions
|
|
57
57
|
# See the main script for turning this feature on.
|
58
58
|
def marc_to_csv(template)
|
59
59
|
values = []
|
60
|
-
|
61
|
-
|
62
|
-
# blank_field_prompt = 'puts "subfield: #{subfield}"; puts "There is no valid value in your MARC record.\n Please enter the intended value for #{field}#{subfield} or Enter to leave blank"; value = STDIN.gets.chomp'
|
60
|
+
|
61
|
+
# blank_field_prompt = 'puts "subfield: #{subfield}"; print "There is no valid value in your MARC record.\n Please enter the intended value for #{field}#{subfield} or Enter to leave blank\n#{field}#{subfield}> "; value = STDIN.gets.chomp'
|
63
62
|
|
64
63
|
template.each do |template|
|
65
64
|
field, subfield, leng = template
|
@@ -74,7 +73,7 @@ module MARCAdditions
|
|
74
73
|
fields = self.find_all { | f | f.tag =~ Regexp.new( field.gsub('X','.'))}
|
75
74
|
value = ''
|
76
75
|
if fields.empty?
|
77
|
-
puts "oh, no!"
|
76
|
+
#puts "oh, no!"
|
78
77
|
value = blank_field_prompt(field, subfield)
|
79
78
|
#eval(blank_field_prompt)
|
80
79
|
else
|
@@ -96,7 +95,7 @@ module MARCAdditions
|
|
96
95
|
puts "this is not a valid value for marc_to_csv"
|
97
96
|
end
|
98
97
|
end
|
99
|
-
puts values
|
98
|
+
#puts values
|
100
99
|
values[-1].sub!(/\,$/, '')
|
101
100
|
values = values.to_s
|
102
101
|
values += "\n"
|
@@ -104,11 +103,12 @@ module MARCAdditions
|
|
104
103
|
|
105
104
|
#++ The local_script method is for automating changes to the record before saving it. See the main script to turn on this feature. See zoomer.yaml for instructions on creating a script for your purposes.
|
106
105
|
def local_script(script)
|
106
|
+
#print $clear_code
|
107
107
|
record = self
|
108
108
|
|
109
109
|
#--creating my procs for creating fields and appending subfields
|
110
110
|
# these two should probably be moved to methods
|
111
|
-
create_datafield = proc{|record, field, i1, i2| puts "
|
111
|
+
create_datafield = proc{|record, field, i1, i2| puts "Creating datafield: #{field}"; record.append(MARC::DataField.new(field.to_s, i1.to_s, i2.to_s)); puts "****", record, "***" if $testing;}
|
112
112
|
|
113
113
|
append_subfield = proc{|record, field, subfield, val|
|
114
114
|
field = field.to_s
|
@@ -196,4 +196,26 @@ module MARCAdditions
|
|
196
196
|
fields_rec2.each {|f| puts "- #{f}"} if fields_rec2
|
197
197
|
end
|
198
198
|
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
module ZCC
|
203
|
+
def ZCC.lccn_conversion lccn
|
204
|
+
split_lccn = lccn.split('-')
|
205
|
+
year_len = split_lccn[0].length
|
206
|
+
serial_len = split_lccn[1].length
|
207
|
+
start_length = year_len + serial_len
|
208
|
+
if year_len == 2
|
209
|
+
final_lccn = lccn.gsub('-', "#{'0' * (8 - start_length)}")
|
210
|
+
elsif year_len == 4
|
211
|
+
final_lccn = lccn.gsub('-', "#{'0' * (10 - start_length)}")
|
212
|
+
end
|
213
|
+
final_lccn
|
199
214
|
end
|
215
|
+
end
|
216
|
+
|
217
|
+
#class String
|
218
|
+
# def to_proc
|
219
|
+
# eval "Proc.new #{self} " # or "Proc.new #{self}" in my case
|
220
|
+
# end
|
221
|
+
#end
|
data/lib/zcc/pickers.rb
CHANGED
@@ -1,32 +1,103 @@
|
|
1
|
-
module
|
2
|
-
def
|
1
|
+
module ZCC
|
2
|
+
def ZCC.display_menu(rec_copy, index)
|
3
|
+
field_width = $term_width - 8
|
4
|
+
say("<%= color(\"#{index}\", :index) %> ")
|
5
|
+
['245', '260', '300'].each do |field|
|
6
|
+
string = rec_copy[index][field].to_s
|
7
|
+
string.rstrip!
|
8
|
+
string.lstrip!
|
9
|
+
if string.length < field_width
|
10
|
+
say("\t#{ZCC.zcc_marc_str_bold(string, field)}")
|
11
|
+
else
|
12
|
+
better_string = ZCC.wrap_field(string, field_width)
|
13
|
+
#puts better_string
|
14
|
+
say("\t#{ZCC.zcc_marc_str_bold(better_string, field)}")
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
#currently this goes word by word. how difficult to go field by subfield?
|
21
|
+
def ZCC.wrap_field(s, width)
|
22
|
+
lines = []
|
23
|
+
line = ""
|
24
|
+
smaller_width = width - 7
|
25
|
+
s.split(/\s+/).each do |word|
|
26
|
+
if (line.size + word.size) >= (width - 3)
|
27
|
+
lines << line
|
28
|
+
line = word
|
29
|
+
width = smaller_width
|
30
|
+
elsif line.empty?
|
31
|
+
line = word
|
32
|
+
else
|
33
|
+
line << " " << word
|
34
|
+
end
|
35
|
+
end
|
36
|
+
lines << line if line
|
37
|
+
return lines.join "\n\t\t"
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def ZCC.zcc_marc_str_bold(string, field)
|
42
|
+
#puts field
|
43
|
+
string.gsub!("'", "\'")
|
44
|
+
#string.gsub!("(", "\(")
|
45
|
+
#string.gsub!(")", "\)")
|
46
|
+
if field == '245'
|
47
|
+
string.gsub!(/(\$a\s)(.*?)(\$.)/, "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
|
48
|
+
elsif field == '260'
|
49
|
+
#puts 'gets here'
|
50
|
+
string.gsub!(/(\$c\s)([\[0-9A-Za-z\]]*)(.|$)/, "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
|
51
|
+
|
52
|
+
#string.gsub!(/(\$c)(.*)(\$\s)/, "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
|
53
|
+
#string.gsub!(/(\$c)(.*)(\.|$)/, "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
|
54
|
+
elsif field == '300'
|
55
|
+
string.gsub!(/(\$a)(.*?)(\$|$)/, "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
|
56
|
+
elsif field == 'record'
|
57
|
+
string.sub!(/(LEADER.{19})(.{1})/, "\\1<%= color(\"\\2\", :headline) %>") #colorizes the value of the standard (AACR2, ISBD, or none)
|
58
|
+
end
|
59
|
+
|
60
|
+
string.gsub!( /\$(.)/, "<%= color('$\\1', :marc_tag) %>" )
|
61
|
+
string.gsub!( /^(\d\d\d)\s/, "<%= color('\\1 ', :marc_tag) %>")
|
62
|
+
string
|
63
|
+
end
|
64
|
+
|
65
|
+
def ZCC.not_valid_value
|
66
|
+
print $clear_code
|
67
|
+
say("\a<%= color(\"That's not a valid value. Try again.\", :headline) %> ")
|
68
|
+
sleep 1
|
69
|
+
print "\a"
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
class Array
|
77
|
+
def zcc_select_good_marc(take_how_many)
|
3
78
|
#puts self[0]
|
4
79
|
unless self[0].is_a? MARC::Record
|
5
80
|
raise ArgumentError, "This Array doesn't have a MARC::Record!" end
|
6
|
-
|
7
81
|
#puts self
|
8
|
-
rec_copy = self.dup
|
9
|
-
|
10
|
-
|
11
|
-
#puts rec_copy[3] #if it chokes on a record uncomment and include the record number
|
12
|
-
#i = 0
|
82
|
+
rec_copy = self.dup
|
83
|
+
rec_copy = rec_copy.sort_by {|rec| rec['245']['a']}
|
84
|
+
|
13
85
|
recs_to_return = []
|
14
86
|
loop {
|
15
|
-
|
16
|
-
|index|
|
17
|
-
|
18
|
-
|
19
|
-
puts "\t#{rec_copy[index]['300']}" if rec_copy[index]['300']
|
20
|
-
puts "\n\n"
|
87
|
+
print $clear_code
|
88
|
+
rec_copy.each_index do |index|
|
89
|
+
ZCC.display_menu(rec_copy, index)
|
90
|
+
puts "\n\n"
|
21
91
|
end
|
22
|
-
|
92
|
+
|
93
|
+
|
94
|
+
whichrec = ''
|
23
95
|
if take_how_many =='one'
|
24
|
-
|
96
|
+
whichrec = ask("\n<%= color('Enter # | s# | c#-# | l# | none :', UNDERLINE) %> ", String){ |q| q.readline = true }
|
25
97
|
else
|
26
|
-
|
98
|
+
whichrec = ask("\n<%= color('Enter # | n | s# | c#-# | l# | d :', UNDERLINE) %> ", String){ |q| q.readline = true }
|
27
99
|
end
|
28
|
-
|
29
|
-
|
100
|
+
|
30
101
|
#puts "whichrec #{whichrec[0,1]}"
|
31
102
|
#puts whichrec.class
|
32
103
|
#whichrec = whichrec.to_i unless whichrec.respond_to?(:upcase)
|
@@ -34,31 +105,33 @@ module Pickers
|
|
34
105
|
puts "whichrec is an Integer" if whichrec.is_a?(Integer)
|
35
106
|
see_num = whichrec[1,9].to_i
|
36
107
|
if first_bit == 's'
|
37
|
-
|
38
|
-
print "\
|
39
|
-
|
108
|
+
print $clear_code
|
109
|
+
print "\a"
|
110
|
+
say("#{ZCC.zcc_marc_str_bold(rec_copy[see_num].to_s, 'record')}")
|
111
|
+
ask("<%= color('Hit ENTER to continue...', :headline) %> ")
|
112
|
+
#STDIN.gets
|
40
113
|
next
|
41
114
|
elsif first_bit == 'c'
|
42
|
-
|
115
|
+
say("<%= color('comparison:', :headline) %> ")
|
43
116
|
comparison = whichrec[1,99]
|
44
117
|
compare_nums = comparison.split('-')
|
45
118
|
rec_copy[compare_nums[0].to_i].compare_marc(rec_copy[compare_nums[1].to_i])
|
46
|
-
|
47
|
-
STDIN.gets
|
119
|
+
ask("<%= color('Hit ENTER to continue...', :headline) %> ")
|
120
|
+
#STDIN.gets
|
48
121
|
next
|
49
122
|
elsif first_bit == 'l'
|
50
123
|
#puts rec_copy[whichrec[1,99].to_i]
|
51
124
|
#gets
|
52
125
|
rec_copy[whichrec[1,99].to_i].linter
|
53
|
-
|
54
|
-
STDIN.gets
|
126
|
+
ask("<%= color('Hit ENTER to continue...', :headline) %> ")
|
127
|
+
#STDIN.gets
|
55
128
|
next
|
56
129
|
elsif take_how_many == 'one'
|
57
130
|
if ( whichrec == 'none' )
|
58
131
|
puts "Since you cannot decide on a good record, please refer the book to a cataloger."
|
59
132
|
return "none"
|
60
133
|
elsif ( first_bit =~ /[a-z]/i or whichrec == '' )
|
61
|
-
|
134
|
+
ZCC.not_valid_value
|
62
135
|
next
|
63
136
|
else
|
64
137
|
if whichrec.to_i > (rec_copy.length - 1)
|
@@ -76,7 +149,7 @@ module Pickers
|
|
76
149
|
puts "recs that will be returned #{recs_to_return.length}"
|
77
150
|
return recs_to_return
|
78
151
|
elsif whichrec[0,1] =~ /[a-z]/i
|
79
|
-
|
152
|
+
ZCC.not_valid_value
|
80
153
|
next
|
81
154
|
else
|
82
155
|
if whichrec.to_i > (rec_copy.length - 1)
|
@@ -98,3 +171,6 @@ module Pickers
|
|
98
171
|
end
|
99
172
|
|
100
173
|
end
|
174
|
+
|
175
|
+
|
176
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module MARC
|
2
|
+
|
3
|
+
#edit is a wrapper method to loop until done
|
4
|
+
class Record
|
5
|
+
|
6
|
+
|
7
|
+
def edit
|
8
|
+
puts "Subfield Editing"
|
9
|
+
puts "To denote which subfield you want to edit put it in the form of 245a.\nIn the case of repeating fields or subfields you will be prompted\nto choose the one you wish to edit. "
|
10
|
+
continue = true
|
11
|
+
while continue
|
12
|
+
fs = ask("What field and subfield would you like to edit (in form 245a) or quit?\n> "){|q| q.readline = true}
|
13
|
+
if fs == 'q' || fs == 'quit'
|
14
|
+
continue = false
|
15
|
+
next
|
16
|
+
end
|
17
|
+
if !(fs =~/\d\d\d\w/ )
|
18
|
+
puts "That's not a valid value"
|
19
|
+
next
|
20
|
+
end
|
21
|
+
self.change_subfield(fs)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
#edit_subfield is passed to a MARC::Record object and give a subfield
|
26
|
+
def change_subfield(fs)
|
27
|
+
field_subfield = subfield_parse(fs)
|
28
|
+
field = field_subfield[0]
|
29
|
+
subfield = field_subfield[1]
|
30
|
+
|
31
|
+
fields = self.find_all {|f| f.tag == field}
|
32
|
+
subfields = []
|
33
|
+
for field in fields
|
34
|
+
subfields << field.find_all {|s| s.code == subfield}
|
35
|
+
end
|
36
|
+
subfields.flatten!
|
37
|
+
if subfields.length > 1
|
38
|
+
i = 0
|
39
|
+
for subfield in subfields
|
40
|
+
puts "#{i}\t#{subfield}"
|
41
|
+
i += 1
|
42
|
+
end
|
43
|
+
num_to_change = ask("Which subfield do you want to change?"){|q| q.readline = true}
|
44
|
+
subfield_to_change = subfields[num_to_change.to_i]
|
45
|
+
elsif subfields.length == 1
|
46
|
+
subfield_to_change = subfields[0]
|
47
|
+
elsif subfields.empty?
|
48
|
+
puts "No such subfield!"
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
puts self; puts
|
54
|
+
|
55
|
+
print "Currently:\t"
|
56
|
+
puts subfield_to_change.value
|
57
|
+
edit = ask("Your edit:\t"){|q| q.readline = true}
|
58
|
+
subfield_to_change.value = edit
|
59
|
+
puts; puts self; puts
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
#subfield_parse method for getting from '245a' to ['245','a']
|
64
|
+
def subfield_parse(combined)
|
65
|
+
field_subfield = []
|
66
|
+
field_subfield << combined[0, 3]
|
67
|
+
field_subfield << combined[3,1]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|