blacklight_marc 0.0.2 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a60af104e098faf23df159fc6b40d969930e1dcf
4
- data.tar.gz: 282afc9c475de163651aec56541ca89dca089a10
3
+ metadata.gz: 24c6e3dc1f7daff18432642867d570b2ffb4a6f5
4
+ data.tar.gz: 1f8bc8a88cb1e29c5605b9de140612c38d1d3588
5
5
  SHA512:
6
- metadata.gz: 7f4efd8d66bbd5c9943fda14bc4269b93cc807dde946ce3a2442bf69f306c1ba633dd004fc5407651ba3cdab60f562f1c8f8ffe396cf48765ff26350bc63fc4e
7
- data.tar.gz: deededf0ded38297e41e159c2b8c4eece7acf741991ebc839869d84f408be3b5cf0b54e982a55b66375297ffb5e3584af8e378fc82f32ca52920b7ac9114fd4e
6
+ metadata.gz: 4625cf4d1a6a15db370f2c5fafcaa0b8d0a369d3a87bf009c4d46917af7d5539d5367d117a1c97cbeb35a977553d4c60519ecbca51b1114b97c5fe1a1334321a
7
+ data.tar.gz: 26ffce0d381dd7dd4cd1d5bf3b7dd772962d4257cbe4acef266853b9eb17b44af356c42376fa1842f79e3d459a6537bce26e5584202ca3a5a814787bc82ebd54
@@ -21,4 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_dependency "railties", ">= 3.2.6", "< 5"
24
+ # Let's allow future versions of marc, count on
25
+ # them to be backwards compat until 1.1
26
+ spec.add_dependency "marc", ">= 0.4.3", "< 1.1" # Marc record parser.
24
27
  end
@@ -0,0 +1,71 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # This is a document extension meant to be mixed into a
4
+ # Blacklight::Solr::Document class, such as SolrDocument. It provides support
5
+ # for restoration of MARC data (xml or binary) from a Solr stored field, and
6
+ # then provides various transformations/exports of that Marc via the included
7
+ # Blacklight::Solr::Document::MarcExport module.
8
+ #
9
+ # This extension would normally be registered using
10
+ # Blacklight::Solr::Document#use_extension. eg:
11
+ #
12
+ # SolrDocument.use_extension( Blacklight::Solr::Document::Marc ) { |document| my_logic_for_document_has_marc?( document ) }
13
+ #
14
+ # This extension also expects a :marc_source_field and :marc_format_type to
15
+ # be registered with the hosting classes extension_parameters. In an initializer
16
+ # or other startup code:
17
+ # SolrDocument.extension_paramters[:marc_source_field] = "name_of_solr_stored_field"
18
+ # SolrDocument.extension_parameters[:marc_format_type] = :marc21 # or :marcxml
19
+ require 'marc'
20
+ module Blacklight::Solr::Document::Marc
21
+
22
+ include Blacklight::Solr::Document::MarcExport # All our export_as stuff based on to_marc.
23
+
24
+ class UnsupportedMarcFormatType < RuntimeError; end
25
+
26
+ def self.extended(document)
27
+ # Register our exportable formats, we inherit these from MarcExport
28
+ Blacklight::Solr::Document::MarcExport.register_export_formats( document )
29
+ end
30
+
31
+ # ruby-marc object
32
+ def to_marc
33
+ @_ruby_marc_obj ||= load_marc
34
+ end
35
+
36
+
37
+ protected
38
+ def marc_source
39
+ @_marc_source ||= fetch(_marc_source_field)
40
+ end
41
+
42
+ def load_marc
43
+ case _marc_format_type.to_s
44
+ when 'marcxml'
45
+ records = MARC::XMLReader.new(StringIO.new( fetch(_marc_source_field) )).to_a
46
+ return records[0]
47
+ when 'marc21'
48
+ return MARC::Record.new_from_marc( fetch(_marc_source_field) )
49
+ else
50
+
51
+ raise UnsupportedMarcFormatType.new("Only marcxml and marc21 are supported, this documents format is #{_marc_format_type} and the current extension parameters are #{self.class.extension_parameters.inspect}")
52
+ end
53
+ end
54
+
55
+
56
+
57
+ def _marc_helper
58
+ @_marc_helper ||= (
59
+ Blacklight::Marc::Document.new fetch(_marc_source_field), _marc_format_type )
60
+ end
61
+
62
+ def _marc_source_field
63
+ self.class.extension_parameters[:marc_source_field]
64
+ end
65
+
66
+ def _marc_format_type
67
+ #TODO: Raise if not present
68
+ self.class.extension_parameters[:marc_format_type]
69
+ end
70
+
71
+ end
@@ -0,0 +1,602 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # -*- coding: utf-8 -*-
3
+ # Written for use with Blacklight::Solr::Document::Marc, but you can use
4
+ # it for your own custom Blacklight document Marc extension too -- just
5
+ # include this module in any document extension (or any other class)
6
+ # that provides a #to_marc returning a ruby-marc object. This module will add
7
+ # in export_as translation methods for a variety of formats.
8
+ module Blacklight::Solr::Document::MarcExport
9
+
10
+ def self.register_export_formats(document)
11
+ document.will_export_as(:xml)
12
+ document.will_export_as(:marc, "application/marc")
13
+ # marcxml content type:
14
+ # http://tools.ietf.org/html/draft-denenberg-mods-etc-media-types-00
15
+ document.will_export_as(:marcxml, "application/marcxml+xml")
16
+ document.will_export_as(:openurl_ctx_kev, "application/x-openurl-ctx-kev")
17
+ document.will_export_as(:refworks_marc_txt, "text/plain")
18
+ document.will_export_as(:endnote, "application/x-endnote-refer")
19
+ end
20
+
21
+
22
+ def export_as_marc
23
+ to_marc.to_marc
24
+ end
25
+
26
+ def export_as_marcxml
27
+ to_marc.to_xml.to_s
28
+ end
29
+ alias_method :export_as_xml, :export_as_marcxml
30
+
31
+
32
+ # TODO This exporting as formatted citation thing should be re-thought
33
+ # redesigned at some point to be more general purpose, but this
34
+ # is in-line with what we had before, but at least now attached
35
+ # to the document extension where it belongs.
36
+ def export_as_apa_citation_txt
37
+ apa_citation( to_marc )
38
+ end
39
+
40
+ def export_as_mla_citation_txt
41
+ mla_citation( to_marc )
42
+ end
43
+
44
+ def export_as_chicago_citation_txt
45
+ chicago_citation( to_marc )
46
+ end
47
+
48
+ # Exports as an OpenURL KEV (key-encoded value) query string.
49
+ # For use to create COinS, among other things. COinS are
50
+ # for Zotero, among other things. TODO: This is wierd and fragile
51
+ # code, it should use ruby OpenURL gem instead to work a lot
52
+ # more sensibly. The "format" argument was in the old marc.marc.to_zotero
53
+ # call, but didn't neccesarily do what it thought it did anyway. Left in
54
+ # for now for backwards compatibilty, but should be replaced by
55
+ # just ruby OpenURL.
56
+ def export_as_openurl_ctx_kev(format = nil)
57
+ title = to_marc.find{|field| field.tag == '245'}
58
+ author = to_marc.find{|field| field.tag == '100'}
59
+ corp_author = to_marc.find{|field| field.tag == '110'}
60
+ publisher_info = to_marc.find{|field| field.tag == '260'}
61
+ edition = to_marc.find{|field| field.tag == '250'}
62
+ isbn = to_marc.find{|field| field.tag == '020'}
63
+ issn = to_marc.find{|field| field.tag == '022'}
64
+ unless format.nil?
65
+ format.is_a?(Array) ? format = format[0].downcase.strip : format = format.downcase.strip
66
+ end
67
+ export_text = ""
68
+ if format == 'book'
69
+ export_text << "ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&amp;rfr_id=info%3Asid%2Fblacklight.rubyforge.org%3Agenerator&amp;rft.genre=book&amp;"
70
+ export_text << "rft.btitle=#{(title.nil? or title['a'].nil?) ? "" : CGI::escape(title['a'])}+#{(title.nil? or title['b'].nil?) ? "" : CGI::escape(title['b'])}&amp;"
71
+ export_text << "rft.title=#{(title.nil? or title['a'].nil?) ? "" : CGI::escape(title['a'])}+#{(title.nil? or title['b'].nil?) ? "" : CGI::escape(title['b'])}&amp;"
72
+ export_text << "rft.au=#{(author.nil? or author['a'].nil?) ? "" : CGI::escape(author['a'])}&amp;"
73
+ export_text << "rft.aucorp=#{CGI::escape(corp_author['a']) if corp_author['a']}+#{CGI::escape(corp_author['b']) if corp_author['b']}&amp;" unless corp_author.blank?
74
+ export_text << "rft.date=#{(publisher_info.nil? or publisher_info['c'].nil?) ? "" : CGI::escape(publisher_info['c'])}&amp;"
75
+ export_text << "rft.place=#{(publisher_info.nil? or publisher_info['a'].nil?) ? "" : CGI::escape(publisher_info['a'])}&amp;"
76
+ export_text << "rft.pub=#{(publisher_info.nil? or publisher_info['b'].nil?) ? "" : CGI::escape(publisher_info['b'])}&amp;"
77
+ export_text << "rft.edition=#{(edition.nil? or edition['a'].nil?) ? "" : CGI::escape(edition['a'])}&amp;"
78
+ export_text << "rft.isbn=#{(isbn.nil? or isbn['a'].nil?) ? "" : isbn['a']}"
79
+ elsif (format =~ /journal/i) # checking using include because institutions may use formats like Journal or Journal/Magazine
80
+ export_text << "ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal&amp;rfr_id=info%3Asid%2Fblacklight.rubyforge.org%3Agenerator&amp;rft.genre=article&amp;"
81
+ export_text << "rft.title=#{(title.nil? or title['a'].nil?) ? "" : CGI::escape(title['a'])}+#{(title.nil? or title['b'].nil?) ? "" : CGI::escape(title['b'])}&amp;"
82
+ export_text << "rft.atitle=#{(title.nil? or title['a'].nil?) ? "" : CGI::escape(title['a'])}+#{(title.nil? or title['b'].nil?) ? "" : CGI::escape(title['b'])}&amp;"
83
+ export_text << "rft.aucorp=#{CGI::escape(corp_author['a']) if corp_author['a']}+#{CGI::escape(corp_author['b']) if corp_author['b']}&amp;" unless corp_author.blank?
84
+ export_text << "rft.date=#{(publisher_info.nil? or publisher_info['c'].nil?) ? "" : CGI::escape(publisher_info['c'])}&amp;"
85
+ export_text << "rft.issn=#{(issn.nil? or issn['a'].nil?) ? "" : issn['a']}"
86
+ else
87
+ export_text << "ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Fblacklight.rubyforge.org%3Agenerator&amp;"
88
+ export_text << "rft.title=" + ((title.nil? or title['a'].nil?) ? "" : CGI::escape(title['a']))
89
+ export_text << ((title.nil? or title['b'].nil?) ? "" : CGI.escape(" ") + CGI::escape(title['b']))
90
+ export_text << "&amp;rft.creator=" + ((author.nil? or author['a'].nil?) ? "" : CGI::escape(author['a']))
91
+ export_text << "&amp;rft.aucorp=#{CGI::escape(corp_author['a']) if corp_author['a']}+#{CGI::escape(corp_author['b']) if corp_author['b']}" unless corp_author.blank?
92
+ export_text << "&amp;rft.date=" + ((publisher_info.nil? or publisher_info['c'].nil?) ? "" : CGI::escape(publisher_info['c']))
93
+ export_text << "&amp;rft.place=" + ((publisher_info.nil? or publisher_info['a'].nil?) ? "" : CGI::escape(publisher_info['a']))
94
+ export_text << "&amp;rft.pub=" + ((publisher_info.nil? or publisher_info['b'].nil?) ? "" : CGI::escape(publisher_info['b']))
95
+ export_text << "&amp;rft.format=" + (format.nil? ? "" : CGI::escape(format))
96
+ end
97
+ export_text.html_safe unless export_text.blank?
98
+ end
99
+
100
+
101
+ # This format used to be called 'refworks', which wasn't really
102
+ # accurate, sounds more like 'refworks tagged format'. Which this
103
+ # is not, it's instead some weird under-documented Refworks
104
+ # proprietary marc-ish in text/plain format. See
105
+ # http://robotlibrarian.billdueber.com/sending-marcish-data-to-refworks/
106
+ def export_as_refworks_marc_txt
107
+ # plugin/gem weirdness means we do need to manually require
108
+ # here.
109
+ # As of 11 May 2010, Refworks has a problem with UTF-8 if it's decomposed,
110
+ # it seems to want C form normalization, although RefWorks support
111
+ # couldn't tell me that. -jrochkind
112
+ # DHF: moved this require a little lower in the method.
113
+ # require 'unicode'
114
+
115
+ fields = to_marc.find_all { |f| ('000'..'999') === f.tag }
116
+ text = "LEADER #{to_marc.leader}"
117
+ fields.each do |field|
118
+ unless ["940","999"].include?(field.tag)
119
+ if field.is_a?(MARC::ControlField)
120
+ text << "#{field.tag} #{field.value}\n"
121
+ else
122
+ text << "#{field.tag} "
123
+ text << (field.indicator1 ? field.indicator1 : " ")
124
+ text << (field.indicator2 ? field.indicator2 : " ")
125
+ text << " "
126
+ field.each {|s| s.code == 'a' ? text << "#{s.value}" : text << " |#{s.code}#{s.value}"}
127
+ text << "\n"
128
+ end
129
+ end
130
+ end
131
+
132
+ if Blacklight.jruby?
133
+ require 'java'
134
+ java_import java.text.Normalizer
135
+ Normalizer.normalize(text, Normalizer::Form::NFC).to_s
136
+ else
137
+ begin
138
+ require 'unicode'
139
+ Unicode.normalize_C(text)
140
+ rescue LoadError
141
+ Blacklight.logger.warn "Unable to load unicode library in #export_as_refworks_marc_txt; skipping unicode normalization"
142
+ text
143
+ end
144
+ end
145
+ end
146
+
147
+ # Endnote Import Format. See the EndNote User Guide at:
148
+ # http://www.endnote.com/support/enx3man-terms-win.asp
149
+ # Chapter 7: Importing Reference Data into EndNote / Creating a Tagged “EndNote Import” File
150
+ #
151
+ # Note: This code is copied from what used to be in the previous version
152
+ # in ApplicationHelper#render_to_endnote. It does NOT produce very good
153
+ # endnote import format; the %0 is likely to be entirely illegal, the
154
+ # rest of the data is barely correct but messy. TODO, a new version of this,
155
+ # or better yet just an export_as_ris instead, which will be more general
156
+ # purpose.
157
+ def export_as_endnote()
158
+ end_note_format = {
159
+ "%A" => "100.a",
160
+ "%C" => "260.a",
161
+ "%D" => "260.c",
162
+ "%E" => "700.a",
163
+ "%I" => "260.b",
164
+ "%J" => "440.a",
165
+ "%@" => "020.a",
166
+ "%_@" => "022.a",
167
+ "%T" => "245.a,245.b",
168
+ "%U" => "856.u",
169
+ "%7" => "250.a"
170
+ }
171
+ marc_obj = to_marc
172
+
173
+ # TODO. This should be rewritten to guess
174
+ # from actual Marc instead, probably.
175
+ format_str = 'Generic'
176
+
177
+ text = ''
178
+ text << "%0 #{ format_str }\n"
179
+ # If there is some reliable way of getting the language of a record we can add it here
180
+ #text << "%G #{record['language'].first}\n"
181
+ end_note_format.each do |key,value|
182
+ values = value.split(",")
183
+ first_value = values[0].split('.')
184
+ if values.length > 1
185
+ second_value = values[1].split('.')
186
+ else
187
+ second_value = []
188
+ end
189
+
190
+ if marc_obj[first_value[0].to_s]
191
+ marc_obj.find_all{|f| (first_value[0].to_s) === f.tag}.each do |field|
192
+ if field[first_value[1]].to_s or field[second_value[1]].to_s
193
+ text << "#{key.gsub('_','')}"
194
+ if field[first_value[1]].to_s
195
+ text << " #{field[first_value[1]].to_s}"
196
+ end
197
+ if field[second_value[1]].to_s
198
+ text << " #{field[second_value[1]].to_s}"
199
+ end
200
+ text << "\n"
201
+ end
202
+ end
203
+ end
204
+ end
205
+ text
206
+ end
207
+
208
+ ## DEPRECATED stuff left in for backwards compatibility, but should
209
+ # be gotten rid of eventually.
210
+
211
+ def to_zotero(format)
212
+ warn("[DEPRECATION] Simply call document.export_as_openurl_kev to get an openURL kev context object suitable for including in a COinS; then have view code make the span for the COinS. ")
213
+ "<span class=\"Z3988\" title=\"#{export_as_openurl_kev(format)}\"></span>"
214
+ end
215
+
216
+ def to_apa
217
+ warn("[DEPRECATION] Call document.export_as_apa_citation instead.")
218
+ export_as_apa_citation
219
+ end
220
+
221
+ def to_mla
222
+ warn("[DEPRECATION] Call document.export_as_mla_citation instead.")
223
+ end
224
+
225
+
226
+
227
+ protected
228
+
229
+ # Main method for defining chicago style citation. If we don't end up converting to using a citation formatting service
230
+ # we should make this receive a semantic document and not MARC so we can use this with other formats.
231
+ def chicago_citation(marc)
232
+ authors = get_all_authors(marc)
233
+ author_text = ""
234
+ unless authors[:primary_authors].blank?
235
+ if authors[:primary_authors].length > 10
236
+ authors[:primary_authors].each_with_index do |author,index|
237
+ if index < 7
238
+ if index == 0
239
+ author_text << "#{author}"
240
+ if author.ends_with?(",")
241
+ author_text << " "
242
+ else
243
+ author_text << ", "
244
+ end
245
+ else
246
+ author_text << "#{name_reverse(author)}, "
247
+ end
248
+ end
249
+ end
250
+ author_text << " et al."
251
+ elsif authors[:primary_authors].length > 1
252
+ authors[:primary_authors].each_with_index do |author,index|
253
+ if index == 0
254
+ author_text << "#{author}"
255
+ if author.ends_with?(",")
256
+ author_text << " "
257
+ else
258
+ author_text << ", "
259
+ end
260
+ elsif index + 1 == authors[:primary_authors].length
261
+ author_text << "and #{name_reverse(author)}."
262
+ else
263
+ author_text << "#{name_reverse(author)}, "
264
+ end
265
+ end
266
+ else
267
+ author_text << authors[:primary_authors].first
268
+ end
269
+ else
270
+ temp_authors = []
271
+ authors[:translators].each do |translator|
272
+ temp_authors << [translator, "trans."]
273
+ end
274
+ authors[:editors].each do |editor|
275
+ temp_authors << [editor, "ed."]
276
+ end
277
+ authors[:compilers].each do |compiler|
278
+ temp_authors << [compiler, "comp."]
279
+ end
280
+
281
+ unless temp_authors.blank?
282
+ if temp_authors.length > 10
283
+ temp_authors.each_with_index do |author,index|
284
+ if index < 7
285
+ author_text << "#{author.first} #{author.last} "
286
+ end
287
+ end
288
+ author_text << " et al."
289
+ elsif temp_authors.length > 1
290
+ temp_authors.each_with_index do |author,index|
291
+ if index == 0
292
+ author_text << "#{author.first} #{author.last}, "
293
+ elsif index + 1 == temp_authors.length
294
+ author_text << "and #{name_reverse(author.first)} #{author.last}"
295
+ else
296
+ author_text << "#{name_reverse(author.first)} #{author.last}, "
297
+ end
298
+ end
299
+ else
300
+ author_text << "#{temp_authors.first.first} #{temp_authors.first.last}"
301
+ end
302
+ end
303
+ end
304
+ title = ""
305
+ additional_title = ""
306
+ section_title = ""
307
+ if marc["245"] and (marc["245"]["a"] or marc["245"]["b"])
308
+ title << citation_title(clean_end_punctuation(marc["245"]["a"]).strip) if marc["245"]["a"]
309
+ title << ": #{citation_title(clean_end_punctuation(marc["245"]["b"]).strip)}" if marc["245"]["b"]
310
+ end
311
+ if marc["245"] and (marc["245"]["n"] or marc["245"]["p"])
312
+ section_title << citation_title(clean_end_punctuation(marc["245"]["n"])) if marc["245"]["n"]
313
+ if marc["245"]["p"]
314
+ section_title << ", <i>#{citation_title(clean_end_punctuation(marc["245"]["p"]))}.</i>"
315
+ elsif marc["245"]["n"]
316
+ section_title << "."
317
+ end
318
+ end
319
+
320
+ if !authors[:primary_authors].blank? and (!authors[:translators].blank? or !authors[:editors].blank? or !authors[:compilers].blank?)
321
+ additional_title << "Translated by #{authors[:translators].collect{|name| name_reverse(name)}.join(" and ")}. " unless authors[:translators].blank?
322
+ additional_title << "Edited by #{authors[:editors].collect{|name| name_reverse(name)}.join(" and ")}. " unless authors[:editors].blank?
323
+ additional_title << "Compiled by #{authors[:compilers].collect{|name| name_reverse(name)}.join(" and ")}. " unless authors[:compilers].blank?
324
+ end
325
+
326
+ edition = ""
327
+ edition << setup_edition(marc) unless setup_edition(marc).nil?
328
+
329
+ pub_info = ""
330
+ if marc["260"] and (marc["260"]["a"] or marc["260"]["b"])
331
+ pub_info << clean_end_punctuation(marc["260"]["a"]).strip if marc["260"]["a"]
332
+ pub_info << ": #{clean_end_punctuation(marc["260"]["b"]).strip}" if marc["260"]["b"]
333
+ pub_info << ", #{setup_pub_date(marc)}" if marc["260"]["c"]
334
+ elsif marc["502"] and marc["502"]["a"] # MARC 502 is the Dissertation Note. This holds the correct pub info for these types of records.
335
+ pub_info << marc["502"]["a"]
336
+ elsif marc["502"] and (marc["502"]["b"] or marc["502"]["c"] or marc["502"]["d"]) #sometimes the dissertation note is encoded in pieces in the $b $c and $d sub fields instead of lumped into the $a
337
+ pub_info << "#{marc["502"]["b"]}, #{marc["502"]["c"]}, #{clean_end_punctuation(marc["502"]["d"])}"
338
+ end
339
+
340
+ citation = ""
341
+ citation << "#{author_text} " unless author_text.blank?
342
+ citation << "<i>#{title}.</i> " unless title.blank?
343
+ citation << "#{section_title} " unless section_title.blank?
344
+ citation << "#{additional_title} " unless additional_title.blank?
345
+ citation << "#{edition} " unless edition.blank?
346
+ citation << "#{pub_info}." unless pub_info.blank?
347
+ citation
348
+ end
349
+
350
+
351
+
352
+ def mla_citation(record)
353
+ text = ''
354
+ authors_final = []
355
+
356
+ #setup formatted author list
357
+ authors = get_author_list(record)
358
+
359
+ if authors.length < 4
360
+ authors.each do |l|
361
+ if l == authors.first #first
362
+ authors_final.push(l)
363
+ elsif l == authors.last #last
364
+ authors_final.push(", and " + name_reverse(l) + ".")
365
+ else #all others
366
+ authors_final.push(", " + name_reverse(l))
367
+ end
368
+ end
369
+ text += authors_final.join
370
+ unless text.blank?
371
+ if text[-1,1] != "."
372
+ text += ". "
373
+ else
374
+ text += " "
375
+ end
376
+ end
377
+ else
378
+ text += authors.first + ", et al. "
379
+ end
380
+ # setup title
381
+ title = setup_title_info(record)
382
+ if !title.nil?
383
+ text += "<i>" + mla_citation_title(title) + "</i> "
384
+ end
385
+
386
+ # Edition
387
+ edition_data = setup_edition(record)
388
+ text += edition_data + " " unless edition_data.nil?
389
+
390
+ # Publication
391
+ text += setup_pub_info(record) + ", " unless setup_pub_info(record).nil?
392
+
393
+ # Get Pub Date
394
+ text += setup_pub_date(record) unless setup_pub_date(record).nil?
395
+ if text[-1,1] != "."
396
+ text += "." unless text.nil? or text.blank?
397
+ end
398
+ text
399
+ end
400
+
401
+ def apa_citation(record)
402
+ text = ''
403
+ authors_list = []
404
+ authors_list_final = []
405
+
406
+ #setup formatted author list
407
+ authors = get_author_list(record)
408
+ authors.each do |l|
409
+ authors_list.push(abbreviate_name(l)) unless l.blank?
410
+ end
411
+ authors_list.each do |l|
412
+ if l == authors_list.first #first
413
+ authors_list_final.push(l.strip)
414
+ elsif l == authors_list.last #last
415
+ authors_list_final.push(", &amp; " + l.strip)
416
+ else #all others
417
+ authors_list_final.push(", " + l.strip)
418
+ end
419
+ end
420
+ text += authors_list_final.join
421
+ unless text.blank?
422
+ if text[-1,1] != "."
423
+ text += ". "
424
+ else
425
+ text += " "
426
+ end
427
+ end
428
+ # Get Pub Date
429
+ text += "(" + setup_pub_date(record) + "). " unless setup_pub_date(record).nil?
430
+
431
+ # setup title info
432
+ title = setup_title_info(record)
433
+ text += "<i>" + title + "</i> " unless title.nil?
434
+
435
+ # Edition
436
+ edition_data = setup_edition(record)
437
+ text += edition_data + " " unless edition_data.nil?
438
+
439
+ # Publisher info
440
+ text += setup_pub_info(record) unless setup_pub_info(record).nil?
441
+ unless text.blank?
442
+ if text[-1,1] != "."
443
+ text += "."
444
+ end
445
+ end
446
+ text
447
+ end
448
+ def setup_pub_date(record)
449
+ if !record.find{|f| f.tag == '260'}.nil?
450
+ pub_date = record.find{|f| f.tag == '260'}
451
+ if pub_date.find{|s| s.code == 'c'}
452
+ date_value = pub_date.find{|s| s.code == 'c'}.value.gsub(/[^0-9|n\.d\.]/, "")[0,4] unless pub_date.find{|s| s.code == 'c'}.value.gsub(/[^0-9|n\.d\.]/, "")[0,4].blank?
453
+ end
454
+ return nil if date_value.nil?
455
+ end
456
+ clean_end_punctuation(date_value) if date_value
457
+ end
458
+ def setup_pub_info(record)
459
+ text = ''
460
+ pub_info_field = record.find{|f| f.tag == '260'}
461
+ if !pub_info_field.nil?
462
+ a_pub_info = pub_info_field.find{|s| s.code == 'a'}
463
+ b_pub_info = pub_info_field.find{|s| s.code == 'b'}
464
+ a_pub_info = clean_end_punctuation(a_pub_info.value.strip) unless a_pub_info.nil?
465
+ b_pub_info = b_pub_info.value.strip unless b_pub_info.nil?
466
+ text += a_pub_info.strip unless a_pub_info.nil?
467
+ if !a_pub_info.nil? and !b_pub_info.nil?
468
+ text += ": "
469
+ end
470
+ text += b_pub_info.strip unless b_pub_info.nil?
471
+ end
472
+ return nil if text.strip.blank?
473
+ clean_end_punctuation(text.strip)
474
+ end
475
+
476
+ def mla_citation_title(text)
477
+ no_upcase = ["a","an","and","but","by","for","it","of","the","to","with"]
478
+ new_text = []
479
+ word_parts = text.split(" ")
480
+ word_parts.each do |w|
481
+ if !no_upcase.include? w
482
+ new_text.push(w.capitalize)
483
+ else
484
+ new_text.push(w)
485
+ end
486
+ end
487
+ new_text.join(" ")
488
+ end
489
+
490
+ # This will replace the mla_citation_title method with a better understanding of how MLA and Chicago citation titles are formatted.
491
+ # This method will take in a string and capitalize all of the non-prepositions.
492
+ def citation_title(title_text)
493
+ prepositions = ["a","about","across","an","and","before","but","by","for","it","of","the","to","with","without"]
494
+ new_text = []
495
+ title_text.split(" ").each_with_index do |word,index|
496
+ if (index == 0 and word != word.upcase) or (word.length > 1 and word != word.upcase and !prepositions.include?(word))
497
+ # the split("-") will handle the capitalization of hyphenated words
498
+ new_text << word.split("-").map!{|w| w.capitalize }.join("-")
499
+ else
500
+ new_text << word
501
+ end
502
+ end
503
+ new_text.join(" ")
504
+ end
505
+
506
+ def setup_title_info(record)
507
+ text = ''
508
+ title_info_field = record.find{|f| f.tag == '245'}
509
+ if !title_info_field.nil?
510
+ a_title_info = title_info_field.find{|s| s.code == 'a'}
511
+ b_title_info = title_info_field.find{|s| s.code == 'b'}
512
+ a_title_info = clean_end_punctuation(a_title_info.value.strip) unless a_title_info.nil?
513
+ b_title_info = clean_end_punctuation(b_title_info.value.strip) unless b_title_info.nil?
514
+ text += a_title_info unless a_title_info.nil?
515
+ if !a_title_info.nil? and !b_title_info.nil?
516
+ text += ": "
517
+ end
518
+ text += b_title_info unless b_title_info.nil?
519
+ end
520
+
521
+ return nil if text.strip.blank?
522
+ clean_end_punctuation(text.strip) + "."
523
+
524
+ end
525
+
526
+ def clean_end_punctuation(text)
527
+ if [".",",",":",";","/"].include? text[-1,1]
528
+ return text[0,text.length-1]
529
+ end
530
+ text
531
+ end
532
+
533
+ def setup_edition(record)
534
+ edition_field = record.find{|f| f.tag == '250'}
535
+ edition_code = edition_field.find{|s| s.code == 'a'} unless edition_field.nil?
536
+ edition_data = edition_code.value unless edition_code.nil?
537
+ if edition_data.nil? or edition_data == '1st ed.'
538
+ return nil
539
+ else
540
+ return edition_data
541
+ end
542
+ end
543
+
544
+ def get_author_list(record)
545
+ author_list = []
546
+ authors_primary = record.find{|f| f.tag == '100'}
547
+ author_primary = authors_primary.find{|s| s.code == 'a'}.value unless authors_primary.nil? rescue ''
548
+ author_list.push(clean_end_punctuation(author_primary)) unless author_primary.nil?
549
+ authors_secondary = record.find_all{|f| ('700') === f.tag}
550
+ if !authors_secondary.nil?
551
+ authors_secondary.each do |l|
552
+ author_list.push(clean_end_punctuation(l.find{|s| s.code == 'a'}.value)) unless l.find{|s| s.code == 'a'}.value.nil?
553
+ end
554
+ end
555
+
556
+ author_list.uniq!
557
+ author_list
558
+ end
559
+
560
+ # This is a replacement method for the get_author_list method. This new method will break authors out into primary authors, translators, editors, and compilers
561
+ def get_all_authors(record)
562
+ translator_code = "trl"; editor_code = "edt"; compiler_code = "com"
563
+ primary_authors = []; translators = []; editors = []; compilers = []
564
+ record.find_all{|f| f.tag === "100" }.each do |field|
565
+ primary_authors << field["a"] if field["a"]
566
+ end
567
+ record.find_all{|f| f.tag === "700" }.each do |field|
568
+ if field["a"]
569
+ relators = []
570
+ relators << clean_end_punctuation(field["e"]) if field["e"]
571
+ relators << clean_end_punctuation(field["4"]) if field["4"]
572
+ if relators.include?(translator_code)
573
+ translators << field["a"]
574
+ elsif relators.include?(editor_code)
575
+ editors << field["a"]
576
+ elsif relators.include?(compiler_code)
577
+ compilers << field["a"]
578
+ else
579
+ primary_authors << field["a"]
580
+ end
581
+ end
582
+ end
583
+ {:primary_authors => primary_authors, :translators => translators, :editors => editors, :compilers => compilers}
584
+ end
585
+
586
+ def abbreviate_name(name)
587
+ name_parts = name.split(", ")
588
+ first_name_parts = name_parts.last.split(" ")
589
+ temp_name = name_parts.first + ", " + first_name_parts.first[0,1] + "."
590
+ first_name_parts.shift
591
+ temp_name += " " + first_name_parts.join(" ") unless first_name_parts.empty?
592
+ temp_name
593
+ end
594
+
595
+ def name_reverse(name)
596
+ name = clean_end_punctuation(name)
597
+ return name unless name =~ /,/
598
+ temp_name = name.split(", ")
599
+ return temp_name.last + " " + temp_name.first
600
+ end
601
+
602
+ end
@@ -1,3 +1,3 @@
1
1
  module BlacklightMarc
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -5,5 +5,10 @@ module BlacklightMarc
5
5
  rake_tasks do
6
6
  load "railties/solr_marc.rake"
7
7
  end
8
+
9
+ initializer "blacklight MARC" do
10
+ Blacklight::Solr::Document.autoload :Marc, 'blacklight/solr/document/marc'
11
+ Blacklight::Solr::Document.autoload :MarcExport, 'blacklight/solr/document/marc_export'
12
+ end
8
13
  end
9
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blacklight_marc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
@@ -58,6 +58,26 @@ dependencies:
58
58
  - - <
59
59
  - !ruby/object:Gem::Version
60
60
  version: '5'
61
+ - !ruby/object:Gem::Dependency
62
+ name: marc
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: 0.4.3
68
+ - - <
69
+ - !ruby/object:Gem::Version
70
+ version: '1.1'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.4.3
78
+ - - <
79
+ - !ruby/object:Gem::Version
80
+ version: '1.1'
61
81
  description: SolrMarc support for Blacklight
62
82
  email:
63
83
  - justin@curationexperts.com
@@ -72,6 +92,8 @@ files:
72
92
  - Rakefile
73
93
  - blacklight_marc.gemspec
74
94
  - lib/SolrMarc.jar
95
+ - lib/blacklight/solr/document/marc.rb
96
+ - lib/blacklight/solr/document/marc_export.rb
75
97
  - lib/blacklight_marc.rb
76
98
  - lib/blacklight_marc/version.rb
77
99
  - lib/generators/blacklight_marc/marc_generator.rb