marcman 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c76322157b266a0da1293745a4d5ed35ba7c28ad
4
+ data.tar.gz: 7f4d2f7e12ead3184bed9ed9702b425cfdf6d690
5
+ SHA512:
6
+ metadata.gz: ba9a7575e80b7087c3d8c417fbd36509d6d6c405ad7f6467c7f213a9e04f389ef321784b14cef4749800657893614e5b9de410be9d554ce7dd805a27e8dfcb5a
7
+ data.tar.gz: 420e1654fd0bd8b14aa8ecbaf521b762b68ea5d644cc0ae92e0d306646698d6a3abe9c47a4a35144dc641c93b10389aa3d47f3c74ba6c16df8a313d507fa688f
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ *.gem
14
+ Gemfile.lock
15
+ *~
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.2
5
+ before_install: gem install bundler -v 1.16.1
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at github-smr@sneakemail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in marcman.gemspec
6
+ gemspec
7
+
8
+ # Added at 2018-05-17 13:31:31 -0400 by seanredmond:
9
+ gem "launchy", "~> 2.4"
10
+
11
+ # Added at 2018-05-20 17:47:34 -0400 by sean:
12
+ gem "colorize", "~> 0.8.1"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Sean Redmond
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # Marcman
2
+
3
+ Like a man page for MARC. Marcman provides an executable (`marcman`)
4
+ for quickly looking up MARC bibliographic fields by their code. It
5
+ also provides a little quiz (`marcquiz`) to test your knowledge of
6
+ MARC fields and subfields (because once I'd written the rest, making a
7
+ quiz was easy and fun).
8
+
9
+ ## Installation
10
+
11
+ Install the gem:
12
+
13
+ $ gem install marcman
14
+
15
+ Run the program:
16
+
17
+ $ bundle
18
+
19
+ ## Usage
20
+
21
+ Give `marcman` a MARC field code to see its definition:
22
+
23
+ $ marcman 245
24
+ 245: Title Statement
25
+
26
+ If you want to see the indicators user the `-i` flag:
27
+
28
+ $ marcman 245 -i
29
+ 245: Title Statement
30
+ First indicator: Title added entry
31
+ 0 - No added entry
32
+ 1 - Added entry
33
+ Second indicator: Nonfiling characters
34
+ 0 - No nonfiling characters
35
+ 1-9 - Number of nonfiling characters
36
+
37
+ Or to see the subfields use `-s`:
38
+
39
+ $ marcman 245 -s
40
+ 245: Title Statement
41
+ Subfields:
42
+ $a - Title
43
+ $b - Remainder of title
44
+ $c - Statement of responsibility, etc.
45
+ $f - Inclusive dates
46
+ $g - Bulk dates
47
+ $h - Medium
48
+ $k - Form
49
+ $n - Number of part/section of a work
50
+ $p - Name of part/section of a work
51
+ $s - Version
52
+ $6 - Linkage
53
+ $8 - Field link and sequence number
54
+
55
+ If you want to know what is repeatable, use `-r` (and the flags can
56
+ all be combined):
57
+
58
+ $ marcman 245 -sr
59
+ 245: Title Statement (non-repeatable)
60
+ Subfields:
61
+ $a - Title (non-repeatable)
62
+ $b - Remainder of title (non-repeatable)
63
+ $c - Statement of responsibility, etc. (non-repeatable)
64
+ $f - Inclusive dates (non-repeatable)
65
+ $g - Bulk dates (non-repeatable)
66
+ $h - Medium (non-repeatable)
67
+ $k - Form (repeatable)
68
+ $n - Number of part/section of a work (repeatable)
69
+ $p - Name of part/section of a work (repeatable)
70
+ $s - Version (non-repeatable)
71
+ $6 - Linkage (non-repeatable)
72
+ $8 - Field link and sequence number (repeatable)
73
+
74
+ The `-b` flag will try to open the web documentation in your
75
+ default browser. For example:
76
+
77
+ $ marcman 245 -b
78
+
79
+ Should open https://www.loc.gov/marc/bibliographic/bd245.html
80
+
81
+ ## Take the quiz
82
+
83
+ Run `marcquiz` to test your knowledge of MARC in an interarctive quiz:
84
+
85
+ ~ marcquiz
86
+ Question 1 of 10
87
+ Which field is "Content Type"?
88
+
89
+ 1. 538
90
+ 2. 026
91
+ 3. 787
92
+ 4. 336
93
+
94
+ Enter your answer (Q to quit):
95
+
96
+ Use the `-q` flag to change the number of questions. But really it's a
97
+ demo of using the MARC spec data in Marcman for another purpose. if
98
+ you `require "marcman"` in your own code you will have access to
99
+ `Marcman::MARC` -- a big data structure with all the bibliographic
100
+ field definitions.
101
+
102
+ ## Development
103
+
104
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
105
+
106
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
107
+
108
+ ## Contributing
109
+
110
+ Bug reports and pull requests are welcome on GitHub at https://github.com/seanredmond/marcman. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
111
+
112
+ ## License
113
+
114
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
115
+
116
+ ## Code of Conduct
117
+
118
+ Everyone interacting in the Marcman project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/seanredmond/marcman/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "marcman"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/marcman ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "launchy"
4
+ require "marcman"
5
+
6
+
7
+ options = {:browser => false,
8
+ :indicators => false,
9
+ :repeat=>false,
10
+ :subfields => false}
11
+
12
+ # show help if there is no field argument
13
+ ARGV << '-h' if ARGV.empty?
14
+
15
+ OptionParser.new do |opts|
16
+ opts.banner = "Usage: marcman [CODE] [options]"
17
+
18
+ opts.on("-i", "--[no-]indicators", "Show indicator definitions") do |i|
19
+ options[:indicators] = i
20
+ end
21
+
22
+ opts.on("-s", "--[no-]subfields", "Show subfield definitions") do |s|
23
+ options[:subfields] = s
24
+ end
25
+
26
+ opts.on("-r", "--[no-]repeatable",
27
+ "Show repeatability of fields and subfields") do |r|
28
+ options[:repeat] = r
29
+ end
30
+
31
+ opts.on("-b", "--[no-]browse", "Open in browser") do |b|
32
+ options[:browser] = b
33
+ end
34
+
35
+ opts.on_tail("--version", "Show version") do
36
+ puts Marcman::VERSION
37
+ exit
38
+ end
39
+
40
+ end.parse!
41
+
42
+ begin
43
+ code, field = Marcman::getFieldFromCode(ARGV.first)
44
+
45
+ puts "%s: %s%s" % [code, field[:definition], Marcman::formatRepeat(field[:repeat], options[:repeat])]
46
+ if options[:indicators] and field[:indicators]
47
+ (1..2).each do |i|
48
+ puts Marcman::formatIndicators(code, i).join("\n")
49
+ end
50
+ end
51
+
52
+ if options[:subfields] and field[:subfields]
53
+ puts " Subfields:"
54
+ puts Marcman::formatSubfields(code, options[:repeat]).join("\n")
55
+ end
56
+
57
+ if options[:browser]
58
+ if field[:docurl].nil?
59
+ Launchy.open(
60
+ "https://www.loc.gov/marc/bibliographic/bd%s.html" % code.downcase
61
+ )
62
+ else
63
+ Launchy.open(field[:docurl])
64
+ end
65
+ end
66
+ rescue Marcman::BadMarcFieldFormatError => e
67
+ puts e
68
+ exit 1
69
+ rescue Marcman::NoMarcFieldError => e
70
+ puts e
71
+ end
data/exe/marcquiz ADDED
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "colorize"
4
+ require "marcman"
5
+ require "optparse"
6
+
7
+ class StopTheQuiz < StandardError; end
8
+
9
+ # Loop until a valid response is given. Return the answer as an integer
10
+ def getAnswer(cnt)
11
+ print "Enter your answer (Q to quit): "
12
+
13
+ loop do
14
+ answer = gets.chomp
15
+ if answer.downcase == "q"
16
+ raise StopTheQuiz.new
17
+ end
18
+
19
+ if answer >= "1" and answer <= cnt.to_s
20
+ return answer.to_i
21
+ break
22
+ end
23
+
24
+ print "Enter a number between 1 and %d, or Q to quit:" % cnt
25
+ end
26
+ end
27
+
28
+ # Print message saying whether you were right or wrong. Return 1 point for
29
+ # right, 0 for wrong
30
+ def evaluate(correct, candidates)
31
+ cnt = candidates.count
32
+ code = candidates[correct-1][0]
33
+ definition = candidates[correct-1][1][:definition]
34
+
35
+ if getAnswer(cnt) == correct
36
+ puts "Correct!".colorize(:green)
37
+ return 1
38
+ end
39
+
40
+ puts"Sorry, the right answer was #%d. %s: %s"
41
+ .colorize(:red) % [correct, code, definition]
42
+
43
+ return 0
44
+ end
45
+
46
+ # Print out codes as possible answers
47
+ def askCodes(candidates)
48
+ candidates.each_with_index do |c, i|
49
+ puts "%d. %s" % [i + 1, c[0]]
50
+ end
51
+ puts ""
52
+ end
53
+
54
+ # Print out definitiosn as possible answers
55
+ def askDefs(candidates)
56
+ candidates.each_with_index do |c, i|
57
+ puts "%d. %s" % [i + 1, c[1][:definition]]
58
+ end
59
+ puts ""
60
+ end
61
+
62
+ # Question Format 1:
63
+ # Give the code for a field definition
64
+ def qformat1(candidates, correct)
65
+ puts "Which field is \"%s\"?".
66
+ underline % candidates[correct-1][1][:definition]
67
+ puts ""
68
+
69
+ askCodes(candidates)
70
+
71
+ return evaluate(correct, candidates)
72
+ end
73
+
74
+ # Question Format 2:
75
+ # Give the definitions for a field code
76
+ def qformat2(candidates, correct)
77
+
78
+ puts "Which is field %s?".underline % candidates[correct-1][0]
79
+ puts ""
80
+
81
+ askDefs(candidates)
82
+
83
+ return evaluate(correct, candidates)
84
+ end
85
+
86
+ # Question Format 3:
87
+ # Give the definition for a subfield code
88
+ def qformat3(test_field, candidates, correct)
89
+ puts "For field %s: \"%s\" which subfield is subfield %s?"
90
+ .underline % [test_field[0],
91
+ test_field[1][:definition],
92
+ candidates[correct - 1][0]]
93
+ puts ""
94
+
95
+ askDefs(candidates)
96
+
97
+ return evaluate(correct, candidates)
98
+ end
99
+
100
+ # Question Format 4:
101
+ # Give the code for a subfield candidate
102
+ def qformat4(test_field, candidates, correct)
103
+ puts "For field %s: \"%s\" which subfield is \"%s\"?"
104
+ .underline % [test_field[0],
105
+ test_field[1][:definition],
106
+ candidates[correct - 1][1][:definition]]
107
+ puts ""
108
+
109
+ askCodes(candidates)
110
+
111
+ return evaluate(correct, candidates)
112
+ end
113
+
114
+ # Recursively find a field that a) has subfields and b) has more than one
115
+ # subfield for question formats 3 & 4
116
+ def getFieldWithSubfields(fields)
117
+ f = fields.sample(1).first
118
+ if f[1][:subfields].nil? or f[1][:subfields].count < 2
119
+ return getFieldWithSubfields(fields)
120
+ end
121
+ return f
122
+ end
123
+
124
+ def formatScore(score, n)
125
+ "%d/%d (%d%%)" % [score, n, ((score / n) * 100).round]
126
+ end
127
+
128
+
129
+ # Pose a question in one of 4 formats. Recurse until the full number of
130
+ # questions has been asked
131
+ def ask(fields, n, q, score = 0.0)
132
+ return score if n > q # We're done
133
+
134
+ puts "Question %d of %d" % [n, q]
135
+
136
+ # Pick a question format
137
+ format = [1,2,3,4].sample(1).first
138
+
139
+ if format < 3
140
+ candidates = fields.sample(4).shuffle
141
+ correct = [1,2,3,4].sample(1).first
142
+
143
+ if format == 1
144
+ score += qformat1(candidates, correct)
145
+ else format == 2
146
+ score += qformat2(candidates, correct)
147
+ end
148
+ else
149
+ test_field = getFieldWithSubfields(fields)
150
+ candidates = test_field[1][:subfields].map{|k, v| [k, v]}.sample(4)
151
+ correct = (1..candidates.count).to_a.sample(1).first
152
+
153
+ if format == 3
154
+ score += qformat3(test_field, candidates, correct)
155
+ else
156
+ score += qformat4(test_field, candidates, correct)
157
+ end
158
+ end
159
+
160
+ # puts "Score: %d out of %d (%d%%)" % [score, n, ((score / n) * 100).round]
161
+
162
+ puts "Score: %s" % formatScore(score, n)
163
+ puts ""
164
+
165
+ return ask(fields, n+1, q, score)
166
+ end
167
+
168
+ options = {:q => 10}
169
+ OptionParser.new do |opts|
170
+ opts.banner = "Usage: marcquiz [options]"
171
+
172
+ opts.on("-q", "--questions=QUESTIONS",
173
+ "Number of questions for the quiz (Default: 10") do |q|
174
+ options[:q] = q.to_i
175
+ end
176
+ end.parse!
177
+
178
+
179
+ begin
180
+ puts "Your final score: %s" % formatScore(
181
+ ask(Marcman::MARC.map{|k, v| [k, v]},1, options[:q]),
182
+ options[:q])
183
+ rescue StopTheQuiz
184
+ puts "Thanks for playing!"
185
+ end
@@ -0,0 +1,60 @@
1
+ module Marcman
2
+ # Constants for widely used subfield definitions. These are roughly in
3
+ # descending order of use
4
+
5
+ LINKAGE = {"$6"=>{:definition=>"Linkage", :repeat=>false}}
6
+ FIELDLINK = {"$8"=>{:definition=>"Field link and sequence number", :repeat=>true}}
7
+
8
+ MATSPEC = {:definition=>"Materials specified", :repeat=>false}
9
+ RWURI = {:definition=>"Real World Object URI"}
10
+ ARECNUM = {:definition=>"Authority record control number or standard number"}
11
+ RELAT = {:definition=>"Relationship"}
12
+ ISSNR = {:definition=>"International Standard Serial Number"}
13
+ ISSNNR = {:definition=>"International Standard Serial Number",
14
+ :repeat=>false}
15
+ MISCINF = {:definition=>"Miscellaneous information"}
16
+ INSTAPP = {:definition=>"Institution to which field applies", :repeat=>false}
17
+ SOURCE = {:definition=>"Source", :repeat=>false}
18
+ NAMEPRT = {:definition=>"Name of part/section of a work"}
19
+ RELINFO = {:definition=>"Relationship information"}
20
+ UNIFORM = {:definition=>"Uniform title", :repeat=>false}
21
+ MEDIUM = {:definition=>"Medium", :repeat=>false}
22
+ RELATOR = {:definition=>"Relator term"}
23
+ CTRLSUB = {:definition=>"Control subfield", :repeat=>false}
24
+ NOTER = {:definition=>"Note"}
25
+ FORMSUB = {:definition=>"Form subheading"}
26
+ TITLENR = {:definition=>"Title", :repeat=>false}
27
+ LANGNR = {:definition=>"Language of a work", :repeat=>false}
28
+ DATENR = {:definition=>"Date of a work", :repeat=>false}
29
+ PUBNOTE = {:definition=>"Public note"}
30
+ RECCTRL = {:definition=>"Record control number"}
31
+ WRKTITL = {:definition=>"Title of a work", :repeat=>false}
32
+ QUALINF = {:definition=>"Qualifying information", :repeat=>false}
33
+ ISBNR = {:definition=>"International Standard Book Number"}
34
+ PLCPUB = {:definition=>"Place, publisher, and date of publication",
35
+ :repeat=>false}
36
+ EDTNNR = {:definition=>"Edition", :repeat=>false}
37
+ RELPRTS = {:definition=>"Related parts"}
38
+ PHYSDSC = {:definition=>"Physical description", :repeat=>false}
39
+ MSDETL = {:definition=>"Material-specific details", :repeat=>false}
40
+ VRSNR = {:definition=>"Version"}
41
+ OIID = {:definition=>"Other item identifier"}
42
+ NPUBNOT = {:definition=>"Nonpublic note"}
43
+ CODENR = {:definition=>"CODEN designation", :repeat=>false}
44
+ MAINENT = {:definition=>"Main entry heading", :repeat=>false}
45
+ NUMPART = {:definition=>"Number of part/section of a work"}
46
+ TECHREP = {:definition=>"Standard Technical Report Number", :repeat=>false}
47
+ SRCTERM = {:definition=>"Source of term", :repeat=>false}
48
+ RELSERD = {:definition=>"Series data for related item"}
49
+ REPNUM = {:definition=>"Report number"}
50
+ MUSKEY = {:definition=>"Key for music", :repeat=>false}
51
+ MUSMED = {:definition=>"Medium of performance for music"}
52
+ HEADSRC = {:definition=>"Source of heading or term", :repeat=>false}
53
+ AFFIL = {:definition=>"Affiliation", :repeat=>false}
54
+ GEOSUB = {:definition=>"Geographic subdivision"}
55
+ CRONSUB = {:definition=>"Chronological subdivision"}
56
+ FRMSUBD = {:definition=>"Form subdivision"}
57
+ ARRANGE = {:definition=>"Arranged statement for music", :repeat=>false}
58
+ GNRLSUB = {:definition=>"General subdivision"}
59
+ ITEMNUM = {:definition=>"Item number", :repeat=>false}
60
+ end
@@ -0,0 +1,4 @@
1
+ module Marcman
2
+ class BadMarcFieldFormatError < StandardError; end
3
+ class NoMarcFieldError < StandardError; end
4
+ end