Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIKE] Investigate bibtex for citation #359

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ gem 'bootsnap', require: false

# Additional gems
gem 'action_policy'
gem 'bibtex-ruby'
gem 'citeproc-ruby'
gem 'cocina-models'
gem 'config'
gem 'csl-styles'
gem 'dor-services-client', '>= 15.2.1'
gem 'dor-workflow-client', '>= 7.6.1'
gem 'druid-tools'
Expand Down
21 changes: 21 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bibtex-ruby (6.1.0)
latex-decode (~> 0.0)
racc (~> 1.7)
bigdecimal (3.1.8)
bindex (0.8.1)
bootsnap (1.18.4)
Expand Down Expand Up @@ -129,6 +132,12 @@ GEM
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
chronic (0.10.2)
citeproc (1.0.10)
namae (~> 1.0)
citeproc-ruby (2.1.0)
citeproc (~> 1.0, >= 1.0.9)
csl (~> 2.0)
observer (< 1.0)
cocina-models (0.99.1)
activesupport
deprecation
Expand All @@ -155,6 +164,11 @@ GEM
bigdecimal
rexml
crass (1.0.6)
csl (2.0.0)
namae (~> 1.0)
rexml
csl-styles (2.0.1)
csl (~> 2.0)
cssbundling-rails (1.4.1)
railties (>= 6.0.0)
cyperful (0.2.0)
Expand Down Expand Up @@ -287,6 +301,7 @@ GEM
kaminari-core (= 1.2.2)
kaminari-core (1.2.2)
language_server-protocol (3.17.0.3)
latex-decode (0.4.0)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
Expand Down Expand Up @@ -316,6 +331,8 @@ GEM
turbo-rails
msgpack (1.7.5)
multi_json (1.15.0)
namae (1.2.0)
racc (~> 1.7)
net-http (0.6.0)
uri
net-imap (0.5.1)
Expand All @@ -337,6 +354,7 @@ GEM
racc (~> 1.4)
nokogiri (1.17.2-x86_64-linux)
racc (~> 1.4)
observer (0.1.2)
okcomputer (1.18.5)
openapi3_parser (0.10.0)
commonmarker (>= 1.0)
Expand Down Expand Up @@ -552,12 +570,15 @@ PLATFORMS
DEPENDENCIES
action_policy
bcrypt (~> 3.1.7)
bibtex-ruby
bootsnap
capistrano-passenger
capistrano-rails
capybara
citeproc-ruby
cocina-models
config
csl-styles
cssbundling-rails
cyperful
debug
Expand Down
79 changes: 79 additions & 0 deletions app/services/to_bib_tex/citation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# frozen_string_literal: true

module ToBibTex
# Maps Cocina DRO to a BibTex object
class Citation
def self.call(...)
new(...).call
end

def initialize(cocina_object:)
@cocina_object = cocina_object
@bibliography = BibTeX::Bibliography.new
@cp = CiteProc::Processor.new style: 'apa', format: 'text'
end

def call
# work_type, work_subtypes = CocinaSupport.work_type_and_subtypes_for(cocina_object:)
bibliography << cocina_to_bibtex
debugger
cp.import bibliography.to_citeproc
cp.render :bibliography, id: druid_sym, format: :apa
end

private

attr_reader :cocina_object, :bibliography, :cp

def cocina_to_bibtex
BibTeX::Entry.new do |entry|
entry.type = :article
entry.key = druid_sym
entry.title = CocinaSupport.title_for(cocina_object:)
entry.author = person_authors_string
entry.organization = organization_authors_string
entry.year = CocinaSupport.event_date_for(cocina_object:, type: 'publication')[:year]
entry.keywords = CocinaSupport.keywords_for(cocina_object:).join(', ')
entry.publisher = "Stanford Digital Repository"
entry.howpublished = "\\url\{#{Settings.purl.url}/#{cocina_object.externalIdentifier}\}"
end
end

def druid_sym
cocina_object.externalIdentifier.split(':').last.to_sym
end

def person_authors_string
CocinaSupport.authors_for(cocina_object:).select do |author|
author['role_type'] == 'person'
end.map do |author|
[author['last_name'], author['first_name']].join(', ')
end.join(' and ')
end

def organization_authors_string
CocinaSupport.authors_for(cocina_object:).select do |author|
author['role_type'] == 'organization'
end.map do |org|
org['organization_name']
end.join(' and ')
end
end
end

# BebTeX types:
# article (Cocina: Text/Article)
# book (Cocina: Text/Book)
# booklet
# conference (Cocina: Text/Conference session)
# inbook (Cocina: Text/Book chapter)
# incollection
# inproceedings (Cocina: ???/Conference session)
# manual (Cocina: Documentation)
# mastersthesis (Cocina: Thesis)
# misc
# phdthesis
# proceedings
# techreport (Cocina: Technical report)
# unpublished (Cocina: Working paper)

14 changes: 14 additions & 0 deletions spec/services/to_bib_tex/citation_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe ToBibTex::Citation, type: :mapping do
subject(:bibtex) { described_class.call(cocina_object:) }

let(:cocina_object) { dro_with_metadata_fixture }
let(:citation) { 'My title. (2024).' }

it 'maps to BibTex' do
expect(bibtex.first.to_s).to equal(citation)
end
end