Skip to content

Commit

Permalink
Add APA and Chicago CiteProc citations
Browse files Browse the repository at this point in the history
- Moves shared CiteProc methods into their own module
  • Loading branch information
maxkadel committed Oct 8, 2024
1 parent 79407d2 commit 1c20768
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@ detectors:
- Requests::RequestMailer#service_error_email
- Bookmark#self.destroy_without_solr_documents
- Bookmark#self.update_to_alma_ids
- Blacklight::Document::CiteProc#properties
- Blacklight::Document::DublinCore#export_as_oai_dc_xml
- Blacklight::Document::DublinCore#export_as_rdf_dc
- Blacklight::Document::Email#add_holdings_text
Expand All @@ -762,7 +763,6 @@ detectors:
- Blacklight::Document::JsonLd#date
- Blacklight::Document::JsonLd#identifier
- Blacklight::Document::JsonLd#location
- Blacklight::Document::Mla#properties
- Blacklight::Document::Ris#author_roles_1display_to_ris
- Blacklight::Document::Ris#export_as_ris
- Blacklight::Marc::DocumentExtension#build_ctx
Expand Down
4 changes: 2 additions & 2 deletions app/components/orangelight/document/citation_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
class Orangelight::Document::CitationComponent < Blacklight::Document::CitationComponent
DEFAULT_FORMATS = {
'blacklight.citation.mla': :export_as_mla,
'blacklight.citation.apa': :export_as_apa_citation_txt,
'blacklight.citation.chicago': :export_as_chicago_citation_txt
'blacklight.citation.apa': :export_as_apa,
'blacklight.citation.chicago': :export_as_chicago
}.freeze

def initialize(document:, formats: DEFAULT_FORMATS)
Expand Down
21 changes: 21 additions & 0 deletions app/models/concerns/blacklight/document/apa.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

# Creates an html APA citation for non-Marc records
module Blacklight::Document::Apa
def self.extended(document)
Blacklight::Document::Apa.register_export_formats(document)
end

def self.register_export_formats(document)
document.will_export_as(:apa, 'text/html')
end

def export_as_apa
return export_as_apa_citation_txt if alma?

cp = CiteProc::Processor.new style: 'apa', format: 'html'
item = CiteProc::Item.new(properties)
cp.import(item)
cp.render(:bibliography, id:).first
end
end
21 changes: 21 additions & 0 deletions app/models/concerns/blacklight/document/chicago.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

# Creates an html Chicago citation for non-Marc records
module Blacklight::Document::Chicago
def self.extended(document)
Blacklight::Document::Chicago.register_export_formats(document)
end

def self.register_export_formats(document)
document.will_export_as(:chicago, 'text/html')
end

def export_as_chicago
return export_as_chicago_citation_txt if alma?

cp = CiteProc::Processor.new style: 'chicago-author-date', format: 'html'
item = CiteProc::Item.new(properties)
cp.import(item)
cp.render(:bibliography, id:).first
end
end
62 changes: 62 additions & 0 deletions app/models/concerns/blacklight/document/cite_proc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true

## Adds the methods needed for CiteProc citations,
# Including MLA, APA, and Chicago
module Blacklight::Document::CiteProc
private

def properties
props = {}
props[:id] = id
props[:edition] = cite_proc_edition if cite_proc_edition
props[:type] = cite_proc_type if cite_proc_type
props[:author] = cite_proc_author if cite_proc_author
props[:title] = cite_proc_title if cite_proc_title
props[:publisher] = cite_proc_publisher if cite_proc_publisher
props[:'publisher-place'] = cite_proc_publisher_place if cite_proc_publisher_place
props[:issued] = cite_proc_issued if cite_proc_issued
props
end

def cite_proc_type
self[:format]&.first&.downcase
end

def cite_proc_author
@cite_proc_author ||= begin
family, given = citation_fields_from_solr[:author_citation_display]&.first&.split(', ')
CiteProc::Name.new(family:, given:) if family || given
end
end

def cite_proc_edition
@cite_proc_edition ||= begin
str = citation_fields_from_solr[:edition_display]&.first
str&.dup&.sub!(/[[:punct:]]?$/, '')
end
end

def cite_proc_title
@cite_proc_title ||= citation_fields_from_solr[:title_citation_display]&.first
end

def cite_proc_publisher
@cite_proc_publisher ||= citation_fields_from_solr[:pub_citation_display]&.first&.split(': ').try(:[], 1)
end

def cite_proc_publisher_place
@cite_proc_publisher_place ||= citation_fields_from_solr[:pub_citation_display]&.first&.split(': ').try(:[], 0)
end

def cite_proc_issued
@cite_proc_issued ||= citation_fields_from_solr[:pub_date_start_sort]
end

def citation_fields_from_solr
@citation_fields_from_solr ||= begin
params = { q: "id:#{RSolr.solr_escape(id)}", fl: "author_citation_display, title_citation_display, pub_citation_display, number_of_pages_citation_display, pub_date_start_sort, edition_display" }
solr_response = Blacklight.default_index.connection.get('select', params:)
solr_response["response"]["docs"].first.with_indifferent_access
end
end
end
57 changes: 0 additions & 57 deletions app/models/concerns/blacklight/document/mla.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,61 +18,4 @@ def export_as_mla
cp.import(item)
cp.render(:bibliography, id:).first
end

private

def properties
props = {}
props[:id] = id
props[:edition] = mla_edition if mla_edition
props[:type] = mla_type if mla_type
props[:author] = mla_author if mla_author
props[:title] = mla_title if mla_title
props[:publisher] = mla_publisher if mla_publisher
props[:'publisher-place'] = mla_publisher_place if mla_publisher_place
props[:issued] = mla_issued if mla_issued
props
end

def mla_type
self[:format]&.first&.downcase
end

def mla_author
@mla_author ||= begin
family, given = citation_fields_from_solr[:author_citation_display]&.first&.split(', ')
CiteProc::Name.new(family:, given:) if family || given
end
end

def mla_edition
@mla_edition ||= begin
str = citation_fields_from_solr[:edition_display]&.first
str&.dup&.sub!(/[[:punct:]]?$/, '')
end
end

def mla_title
@mla_title ||= citation_fields_from_solr[:title_citation_display]&.first
end

def mla_publisher
@mla_publisher ||= citation_fields_from_solr[:pub_citation_display]&.first&.split(': ').try(:[], 1)
end

def mla_publisher_place
@mla_publisher_place ||= citation_fields_from_solr[:pub_citation_display]&.first&.split(': ').try(:[], 0)
end

def mla_issued
@mla_issued ||= citation_fields_from_solr[:pub_date_start_sort]
end

def citation_fields_from_solr
@citation_fields_from_solr ||= begin
params = { q: "id:#{RSolr.solr_escape(id)}", fl: "author_citation_display, title_citation_display, pub_citation_display, number_of_pages_citation_display, pub_date_start_sort, edition_display" }
solr_response = Blacklight.default_index.connection.get('select', params:)
solr_response["response"]["docs"].first.with_indifferent_access
end
end
end
10 changes: 10 additions & 0 deletions app/models/solr_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,19 @@ class SolrDocument
## Adds JSON-LD
use_extension(Blacklight::Document::JsonLd)

## Adds the methods needed for CiteProc citations,
# Including MLA, APA, and Chicago
use_extension(Blacklight::Document::CiteProc)

## Adds MLA html
use_extension(Blacklight::Document::Mla)

# Adds APA html
use_extension(Blacklight::Document::Apa)

# Adds Chicago html
use_extension(Blacklight::Document::Chicago)

def identifier_data
values = identifiers.each_with_object({}) do |identifier, hsh|
hsh[identifier.data_key.to_sym] ||= []
Expand Down
53 changes: 53 additions & 0 deletions spec/models/apa_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Blacklight::Document::Apa, citation: true do
let(:document) { SolrDocument.new(properties).export_as_apa }

context 'with a SCSB record' do
context 'with a book' do
let(:properties) do
{
id: "SCSB-2635660",
format: ['Book'],
author_citation_display: ["Saer, Juan José"],
edition_display: ['1a edición.'],
title_citation_display: ['El entenado'],
pub_citation_display: ["Barcelona: Destino"],
pub_date_start_sort: 1988
}
end

it 'includes the author' do
expect(document).to include('Saer')
expect(document).to include('Juan José. ')
end

it 'includes the author with the proper delimiter' do
pending('Fixing the bug with CiteProc')
expect(document).to include('Saer, Juan José. ')
end

it 'includes the title in italics' do
expect(document).to include('<i>El entenado</i>')
end

it 'includes the publisher' do
expect(document).to include('Destino')
end

it 'does not include the place of publication' do
expect(document).not_to include('Barcelona')
end

it 'includes the publication date' do
expect(document).to include('1988')
end

it 'includes the edition' do
expect(document).to include('(1a edición)')
end
end
end
end
53 changes: 53 additions & 0 deletions spec/models/chicago_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Blacklight::Document::Chicago, citation: true do
let(:document) { SolrDocument.new(properties).export_as_chicago }

context 'with a SCSB record' do
context 'with a book' do
let(:properties) do
{
id: "SCSB-2635660",
format: ['Book'],
author_citation_display: ["Saer, Juan José"],
edition_display: ['1a edición.'],
title_citation_display: ['El entenado'],
pub_citation_display: ["Barcelona: Destino"],
pub_date_start_sort: 1988
}
end

it 'includes the author' do
expect(document).to include('Saer')
expect(document).to include('Juan José. ')
end

it 'includes the author with the proper delimiter' do
pending('Fixing the bug with CiteProc')
expect(document).to include('Saer, Juan José. ')
end

it 'includes the title in italics' do
expect(document).to include('<i>El Entenado</i>')
end

it 'includes the publisher' do
expect(document).to include('Destino')
end

it 'includes the place of publication' do
expect(document).to include('Barcelona')
end

it 'includes the publication date' do
expect(document).to include('1988')
end

it 'includes the edition' do
expect(document).to include('1A edición')
end
end
end
end

0 comments on commit 1c20768

Please sign in to comment.