Class: DatasetCitation

Inherits:
Object
  • Object
show all
Defined in:
app/models/dataset_citation.rb

Overview

Handles citations for datasets rubocop:disable Metrics/ParameterLists rubocop:disable Metrics/ClassLength rubocop:disable Style/NumericPredicate rubocop:disable Style/IfUnlessModifier

Constant Summary collapse

NEWLINE_INDENTED =
"\r\n\t\t\t\t\t\t\t\t"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(authors, years, title, type, publisher, doi) ⇒ DatasetCitation

Returns a new instance of DatasetCitation.

Parameters:

  • authors (<String>)

    Array of authors.

  • years (<String>)

    Array of years (expected 1 or 2 values).

  • title (String)

    ] Title of the dataset

  • type (String)

    Type of the dataset (e.g. “Data set” or “Unpublished raw data”)



17
18
19
20
21
22
23
24
# File 'app/models/dataset_citation.rb', line 17

def initialize(authors, years, title, type, publisher, doi)
  @authors = authors || []
  @years = years || []
  @title = title
  @type = type
  @publisher = publisher
  @doi = doi
end

Class Method Details

.custom_strip(value) ⇒ Object

Strip a few specific characters that tend to mess up citations (e.g. trailing periods, commas, et cetera)



134
135
136
137
138
139
140
141
142
143
# File 'app/models/dataset_citation.rb', line 134

def self.custom_strip(value)
  return nil if value.nil?
  return "" if value.empty?
  while true
    last_char = value[-1]
    break if last_char.nil? || !last_char.in?(". ,")
    value = value.chomp(last_char)
  end
  value
end

Instance Method Details

#apaObject

Returns a string with APA-ish citation for the dataset Reference: libguides.usc.edu/APA7th/datasets#s-lg-box-22855503



36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'app/models/dataset_citation.rb', line 36

def apa
  apa_title = DatasetCitation.custom_strip(@title)
  apa_title += " [#{@type}]" if @type.present?
  apa_title = append_dot(apa_title)

  apa_publisher = append_dot(@publisher)
  apa_doi = @doi

  tokens = [append_dot(apa_author), append_dot(apa_year), apa_title, apa_publisher, apa_doi].compact_blank
  tokens.join(" ")
rescue => ex
  Rails.logger.error "Error generating APA citation for (#{@title}): #{ex.message}"
  nil
end

#append_dot(value) ⇒ Object

Appends a dot to a string if it does not end with one.



127
128
129
130
131
# File 'app/models/dataset_citation.rb', line 127

def append_dot(value)
  return nil if value.nil?
  return "" if value.empty?
  DatasetCitation.custom_strip(value) + "."
end

#bibtexObject

Returns a string with BibTeX citation for the dataset.

There is no set standard for datasets and therefore the format we produce was put together from a variety of sources including mimicking what Zotero does and looking at examples from Zenodo (e.g. zenodo.org/record/6062882/export/hx#.Yiejad9OnUL)

Notice that we use the @electronic… identifier instead of @dataset… since Zotero does not recognize the later.



59
60
61
62
63
64
65
66
67
68
69
# File 'app/models/dataset_citation.rb', line 59

def bibtex
  tokens = bibtex_checks

  text = "@electronic{#{bibtex_id},\r\n"
  text += tokens.map { |token| "\t#{token}" }.join(",\r\n") + "\r\n"
  text += "}"
  text
rescue => ex
  Rails.logger.error "Error generating BibTex citation for (#{@title}): #{ex.message}"
  nil
end

#bibtex_field(name, value, open_tag = "", close_tag = "") ⇒ Object

Creates a line to represent a BibTex field. Breaks long lines into smaller lines. Examples:

field_name = {{ short value }}
field_name = {{ very very very
            very very very very
            long value }}


103
104
105
106
107
108
# File 'app/models/dataset_citation.rb', line 103

def bibtex_field(name, value, open_tag = "", close_tag = "")
  return nil if value.blank?

  value_trim = bibtex_lines(value).join(NEWLINE_INDENTED)
  name.ljust(12) + "= " + open_tag + value_trim + close_tag
end

#bibtex_field_author(name, authors, open_tag = "{", close_tag = "}") ⇒ Object

Creates a line to represent multiple authors in a BibTex field en.wikibooks.org/wiki/LaTeX/Bibliography_Management#Authors

Example:

author = { author1 and
         author2 and
         author3 }


119
120
121
122
123
124
# File 'app/models/dataset_citation.rb', line 119

def bibtex_field_author(name, authors, open_tag = "{", close_tag = "}")
  return nil if @authors.count <= 0

  value_trim = authors.join(" and #{NEWLINE_INDENTED}")
  name.ljust(12) + "= " + open_tag + value_trim + close_tag
end

#bibtex_idObject

Returns an ID value for a BibTex citation



72
73
74
75
76
77
78
79
# File 'app/models/dataset_citation.rb', line 72

def bibtex_id
  author_id = "unknown"
  if @authors.count > 0
    author_id = @authors.first.downcase.tr(" ", "_").gsub(/[^a-z0-9_]/, "")
  end
  year_id = @years.first&.to_s || "unknown"
  "#{author_id}_#{year_id}"
end

#bibtex_lines(string, max_length = 40) ⇒ Object

Breaks a string into lines of at most max_length. Returns an array with the lines.



83
84
85
86
87
88
89
90
91
92
# File 'app/models/dataset_citation.rb', line 83

def bibtex_lines(string, max_length = 40)
  string = string.to_s # handles non-string values gracefully
  lines = []
  until string.nil?
    # TODO: it would be nice it we break on spaces rather than in the middle of a word.
    lines << string[0..max_length - 1]
    string = string[max_length..-1]
  end
  lines
end

#to_s(style) ⇒ Object



26
27
28
29
30
31
32
# File 'app/models/dataset_citation.rb', line 26

def to_s(style)
  if style == "BibTeX"
    bibtex
  else
    apa
  end
end