class BibTeX::Entry::RDFConverter

Constants

BIBO_TYPES
DEFAULT_REMOVE_FROM_FALLBACK

Attributes

bibtex[R]
graph[R]

Public Class Methods

convert(bibtex, graph = RDF::Graph.new, agent = {}) click to toggle source

converts a BibTeX entry to RDF @return [RDF::Graph] the RDF graph of this entry

# File lib/bibtex/entry/rdf_converter.rb, line 42
def self.convert(bibtex, graph = RDF::Graph.new, agent = {})
  new(bibtex, graph, agent).convert!
end
new(bibtex, graph = RDF::Graph.new, agent = {}) click to toggle source

@param [BibTeX::Entry] the entry to convert

# File lib/bibtex/entry/rdf_converter.rb, line 47
def initialize(bibtex, graph = RDF::Graph.new, agent = {})
  @bibtex = bibtex
  @graph = graph
  @agent = agent
end

Public Instance Methods

abstract() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 67
def abstract
  return unless bibtex.field?(:abstract)

  remove_from_fallback(:abstract)

  graph << [entry, RDF::Vocab::DC.abstract, bibtex[:abstract].to_s]
  graph << [entry, bibo[:abstract], bibtex[:abstract].to_s]
end
annote() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 76
def annote
  return unless bibtex.field?(:annote)

  remove_from_fallback(:annote)

  pub = RDF::Node.new
  graph << [pub, RDF.type, bibo[:Note]]
  graph << [pub, bibo[:content], bibtex[:annote]]

  graph << [entry, bibo[:annotates], pub]
end
author() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 88
def author
  return unless bibtex.field?(:author)

  remove_from_fallback(:author)

  seq = RDF::Node.new

  graph << [seq, RDF.type, RDF[:Seq]]
  graph << [entry, bibo[:authorList], seq]

  bibtex[:author].each do |name|
    node = agent(name) { create_agent(name, :Person) }

    graph << [entry, RDF::Vocab::DC.creator, node]
    graph << [seq, RDF.li, node]
  end
end
bdsk_url() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 106
def bdsk_url
  count = 1
  while bibtex.field?("bdsk-url-#{count}".to_sym)
    field = "bdsk-url-#{count}".to_sym
    remove_from_fallback(field)
    graph << [entry, RDF::Vocab::DC.URI, bibtex[field].to_s]
    graph << [entry, bibo[:uri], bibtex[field].to_s]
    count += 1
  end
end
booktitle() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 117
def booktitle
  return unless bibtex.field?(:booktitle)

  remove_from_fallback(:booktitle)
  return if bibtex.has_parent? &&
            bibtex.parent[:title] == bibtex[:booktitle]
  return if bibtex.has_parent? &&
            bibtex.parent[:booktitle] == bibtex[:booktitle]
  return if bibtex.has_parent? &&
            bibtex.parent[:isbn] == bibtex[:isbn]
  return if bibtex[:title] == bibtex[:booktitle]

  series = RDF::Node.new
  graph << [series, RDF.type, bibo[:Document]]
  graph << [series, RDF::Vocab::DC.title, bibtex[:booktitle].to_s]

  graph << [entry, RDF::Vocab::DC.isPartOf, series]
end
chapter() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 136
def chapter
  return unless bibtex.field?(:chapter)

  remove_from_fallback(:chapter)

  graph << [entry, bibo[:chapter], bibtex[:chapter].to_s]
end
children() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 144
def children
  return unless bibtex.has_children?

  bibtex.children.each do |child|
    child_id = RDF::URI.new(child.identifier)
    BibTeX::Entry::RDFConverter.new(child, graph, agent).convert! unless uri_in_graph?(child_id)
    graph << [entry, RDF::Vocab::DC.hasPart, child_id]
  end
end
convert!() click to toggle source

@return [RDF::Graph] the RDF graph of this entry

# File lib/bibtex/entry/rdf_converter.rb, line 54
def convert!
  bibtex.parse_names
  bibtex.parse_month

  unless uri_in_graph?(entry)
    methods = self.class.instance_methods(false) - [:convert!]
    methods.each { |m| send(m) }
    run_fallback
  end

  graph
end
date_added() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 162
def date_added
  return unless bibtex.field?(:'date-added')

  remove_from_fallback(:'date-added')

  graph << [entry, RDF::Vocab::DC.created, bibtex[:'date-added'].to_s]
end
date_modified() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 170
def date_modified
  return unless bibtex.field?(:'date-modified')

  remove_from_fallback(:'date-modified')

  graph << [entry, RDF::Vocab::DC.modified, bibtex[:'date-modified'].to_s]
end
doi() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 178
def doi
  return unless bibtex.field?(:doi)

  remove_from_fallback(:doi)

  graph << [entry, bibo[:doi], bibtex[:doi].to_s]
  graph << [entry, RDF::Vocab::DC.identifier, "doi:#{bibtex[:doi]}"]
end
edition() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 187
def edition
  return unless bibtex.field?(:edition)

  remove_from_fallback(:edition)

  graph << [entry, bibo[:edition], bibtex[:edition].to_s]
end
editor() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 195
def editor
  return unless bibtex.field?(:editor)

  remove_from_fallback(:editor)

  seq = RDF::Node.new

  graph << [seq, RDF.type, RDF[:Seq]]
  graph << [entry, bibo[:editorList], seq]

  bibtex[:editor].each do |name|
    node = agent(name) { create_agent(name, :Person) }

    graph << [entry, bibo.name, node]
    graph << [seq, RDF.li, node]
  end
end
fallback_default() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 213
def fallback_default
  remove_from_fallback(*DEFAULT_REMOVE_FROM_FALLBACK)
end
howpublished() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 217
def howpublished
  return unless bibtex.field?(:howpublished)
  return unless bibtex[:howpublished] =~ /^#{URI::DEFAULT_PARSER.make_regexp}$/

  remove_from_fallback(:howpublished)

  graph << [entry, RDF::Vocab::DC.URI, bibtex[:howpublished].to_s]
  graph << [entry, bibo[:uri], bibtex[:howpublished].to_s]
end
institution() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 227
def institution
  return unless bibtex.field?(:institution)

  remove_from_fallback(:institution)

  org = agent(bibtex[:institution].to_s) { create_agent(bibtex[:institution].to_s, :Organization) }

  graph << [entry, RDF::Vocab::DC.contributor, org]
end
isbn() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 237
def isbn
  return unless bibtex.field?(:isbn)

  remove_from_fallback(:isbn)

  graph << [entry, bibo[:isbn], bibtex[:isbn].to_s]

  graph << if bibtex.contained?
             [entry, RDF::Vocab::DC.isPartOf, "urn:isbn:#{bibtex[:isbn]}"]
           else
             [entry, RDF::Vocab::DC.identifier, "urn:isbn:#{bibtex[:isbn]}"]
           end
end
issn() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 251
def issn
  return unless bibtex.field?(:issn)

  remove_from_fallback(:issn)

  graph << [entry, bibo[:issn], bibtex[:issn].to_s]
  graph << if bibtex.contained?
             [entry, RDF::Vocab::DC.isPartOf, "urn:issn:#{bibtex[:issn]}"]
           else
             [entry, RDF::Vocab::DC.identifier, "urn:issn:#{bibtex[:issn]}"]
           end
end
journal_dc_part_of() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 278
def journal_dc_part_of
  return unless bibtex.field?(:journal)
  return if bibtex.has_parent? && bibtex.parent[:title] == bibtex[:journal]
  return if bibtex.has_parent? && bibtex.parent[:issn] == bibtex[:issn]

  journal = RDF::Node.new
  graph << [journal, RDF.type, bibo[:Journal]]
  graph << [journal, RDF::Vocab::DC.title, bibtex[:journal].to_s]

  graph << [entry, RDF::Vocab::DC.isPartOf, journal]
end
journal_dc_source() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 264
def journal_dc_source
  return unless bibtex.field?(:journal)

  remove_from_fallback(:journal)

  source = []
  source << bibtex[:journal].to_s
  source << "Vol. #{bibtex[:volume]}" if bibtex.field?(:volume)
  source << "No. #{bibtex[:number]}" if bibtex.field?(:number)
  pagination = bibtex[:pagination] || 'pp.'
  source << "#{pagination} #{bibtex[:pages]}" if bibtex.field?(:pages)
  graph << [entry, RDF::Vocab::DC.source, source.join(', ')]
end
key() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 290
def key
  graph << [entry, RDF::Vocab::DC.identifier, "urn:bibtex:#{bibtex.key}"]
end
keywords() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 294
def keywords
  return unless bibtex.field?(:keywords)

  remove_from_fallback(:keywords)

  bibtex[:keywords].to_s.split(/\s*[,;]\s*/).each do |keyword|
    graph << [entry, RDF::Vocab::DC.subject, keyword]
  end
end
language() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 304
def language
  return unless bibtex.field?(:language)

  remove_from_fallback(:language)

  bibtex[:language] = 'german' if bibtex[:language] == 'ngerman'

  graph << [entry, RDF::Vocab::DC.language, bibtex[:language].to_s]
end
lccn() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 326
def lccn
  return unless bibtex.field?(:lccn)

  remove_from_fallback(:lccn)

  graph << [entry, bibo[:lccn], bibtex[:lccn].to_s]
end
location() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 314
def location
  return unless bibtex.field?(:location)

  remove_from_fallback(:location)

  graph << [entry, RDF::Vocab::DC.Location, bibtex[:location].to_s]
  if %i[proceedings inproceedings conference].include?(bibtex.type)
    event = RDF::Vocabulary.new('http://purl.org/NET/c4dm/event.owl')
    graph << [entry, event[:place], org]
  end
end
note() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 334
def note
  return unless bibtex.field?(:note)

  remove_from_fallback(:note)

  pub = RDF::Node.new
  graph << [pub, RDF.type, bibo[:Note]]
  graph << [pub, bibo[:content], bibtex[:note]]

  graph << [entry, bibo[:annotates], pub]
end
number() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 346
def number
  return unless bibtex.field?(:number)

  remove_from_fallback(:number)

  graph << case bibtex.type
           when :techreport || :manual || :unpublished
             [entry, bibo[:number], bibtex[:number].to_s]
           else
             [entry, bibo[:issue], bibtex[:number].to_s]
           end
end
organization() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 359
def organization
  return unless bibtex.field?(:organization)

  remove_from_fallback(:organization)

  org = agent(bibtex[:organization].to_s) { create_agent(bibtex[:organization].to_s, :Organization) }

  graph << [entry, RDF::Vocab::DC.contributor, org]
  graph << [entry, bibo[:organizer], org] if %i[proceedings inproceedings conference].include?(bibtex.type)
end
pages() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 370
def pages
  return unless bibtex.field?(:pages)

  remove_from_fallback(:pages)

  if bibtex[:pages].to_s =~ /^\s*(\d+)\s*-+\s*(\d+)\s*$/
    graph << [entry, bibo[:pageStart], Regexp.last_match[1]]
    graph << [entry, bibo[:pageEnd], Regexp.last_match[2]]
  else
    graph << [entry, bibo[:pages], bibtex[:pages].to_s]
  end
end
pagetotal() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 383
def pagetotal
  return unless bibtex.field?(:pagetotal)

  remove_from_fallback(:pagetotal)

  graph << [entry, bibo[:numPages], bibtex[:pagetotal].to_s]
end
parent() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 391
def parent
  return unless bibtex.has_parent?

  remove_from_fallback(:crossref)

  parent_id = RDF::URI.new(bibtex.parent.identifier)
  BibTeX::Entry::RDFConverter.new(bibtex.parent, graph, agent).convert! unless uri_in_graph?(parent_id)
  graph << [entry, RDF::Vocab::DC.isPartOf, parent_id]
end
publisher() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 401
def publisher
  return unless bibtex.field?(:publisher, :organization, :school, :institution)

  remove_from_fallback(:publisher, :address)

  org =
    if bibtex.field?(:publisher)
      agent(bibtex[:publisher].to_s) { create_agent(bibtex[:publisher].to_s, :Organization) }
    elsif bibtex.field?(:organization)
      agent(bibtex[:organization].to_s) { create_agent(bibtex[:organization].to_s, :Organization) }
    elsif bibtex.field?(:school)
      agent(bibtex[:school].to_s) { create_agent(bibtex[:school].to_s, :Organization) }
    elsif bibtex.field?(:institution)
      agent(bibtex[:institution].to_s) { create_agent(bibtex[:institution].to_s, :Organization) }
    end

  if bibtex.field?(:address)
    address = RDF::Vocabulary.new('http://schemas.talis.com/2005/address/schema#')
    graph << [org, address[:localityName], bibtex[:address]]
  end

  graph << [entry, RDF::Vocab::DC.publisher, org]
  graph << [entry, bibo[:publisher], org]
end
school() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 426
def school
  return unless bibtex.field?(:school)

  remove_from_fallback(:school)

  org = agent(bibtex[:school].to_s) { create_agent(bibtex[:school].to_s, :Organization) }

  graph << [entry, RDF::Vocab::DC.contributor, org]
end
series() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 436
def series
  return unless bibtex.field?(:series)

  remove_from_fallback(:series)
  return if bibtex.has_parent? && bibtex.parent[:title] == bibtex[:series]
  return if bibtex.has_parent? && bibtex.parent[:series] == bibtex[:series]
  return if bibtex.has_parent? && bibtex.parent[:issn] == bibtex[:issn]

  series = RDF::Node.new
  graph << [series, RDF.type, bibo[:MultiVolumeBook]]
  graph << [series, RDF::Vocab::DC.title, bibtex[:series].to_s]

  graph << [entry, RDF::Vocab::DC.isPartOf, series]
end
thesis_degree() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 451
def thesis_degree
  return unless bibo_class == :Thesis

  degree =
    case bibtex.type
    # ms = masters degree in science
    # Only ma and ms available. We simply chose one.
    when :mastersthesis then bibo['degrees/ms']
    when :phdthesis then bibo['degrees/phd']
    end

  degree =
    case bibtex[:type]
    when 'mathesis' then bibo['degrees/ma']
    when 'phdthesis' then bibo['degrees/phd']
    when /Dissertation/i then bibo['degrees/phd']
    when /Bachelor['s]{0,2} Thesis/i then "Bachelor's Thesis"
    when /Diplomarbeit/i then bibo['degrees/ms']
    when /Magisterarbeit/i then bibo['degrees/ma']
    else degree
    end

  unless degree.nil?
    remove_from_fallback(:type)
    graph << [entry, bibo[:degree], degree]
  end
end
title() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 479
def title
  return unless bibtex.field?(:title)

  remove_from_fallback(:title)

  title = [bibtex[:title].to_s, bibtex[:subtitle].to_s]
          .reject { |t| t.nil? || t.empty? }
          .join(': ')
  graph << [entry, RDF::Vocab::DC.title, title]
  graph << [entry, bibo[:shortTitle], bibtex[:title].to_s] if bibtex.field?(:subtitle)
end
translator() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 491
def translator
  return unless bibtex.field?(:translator)

  remove_from_fallback(:translator)

  node = agent(bibtex[:translator].to_s) do
    create_agent(bibtex[:translator].to_s, :Person)
  end

  graph << [entry, RDF::Vocab::DC.contributor, node]
  graph << [entry, bibo[:translator], node]
end
type() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 504
def type
  graph << [entry, RDF.type, bibo[bibo_class]]

  case bibtex.type
  when :proceedings, :journal
    graph << [entry, RDF::Vocab::DC.type, 'Collection']
  else
    graph << [entry, RDF::Vocab::DC.type, 'Text']
  end
end
url() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 515
def url
  return unless bibtex.field?(:url)

  remove_from_fallback(:url)

  graph << [entry, RDF::Vocab::DC.URI, bibtex[:url].to_s]
  graph << [entry, bibo[:uri], bibtex[:url].to_s]
end
volume() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 524
def volume
  return unless bibtex.field?(:volume)

  remove_from_fallback(:volume)

  graph << [entry, bibo[:volume], bibtex[:volume].to_s]
end
volumes() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 532
def volumes
  return unless bibtex.field?(:volumes)

  remove_from_fallback(:volumes)

  graph << [entry, bibo[:numVolumes], bibtex[:volumes].to_s]
end
year() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 540
def year
  return unless bibtex.field?(:year)

  remove_from_fallback(:year, :month)

  year = bibtex[:year].to_s
  if bibtex.field?(:month)
    month = BibTeX::Entry::MONTHS.find_index(bibtex[:month].to_s.intern)
    month += 1 unless month.nil?
  end
  date = month.nil? ? year : [year, month].join('-')

  graph << [entry, RDF::Vocab::DC.issued, date]
end

Private Instance Methods

agent(key = nil) { || ... } click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 573
def agent(key = nil)
  if key.nil?
    @agent
  else
    key = key.respond_to?(:to_hash) ? key.to_hash : key
    @agent[key] ||= yield
  end
end
bibo() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 561
def bibo
  @bibo ||= RDF::Vocabulary.new('http://purl.org/ontology/bibo/')
end
bibo_class() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 565
def bibo_class
  BIBO_TYPES[bibtex[:type]] || BIBO_TYPES[bibtex.type] || :Document
end
create_agent(name, type) click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 582
def create_agent(name, type)
  node = RDF::Node.new

  graph << [node, RDF.type, RDF::Vocab::FOAF[type]]
  graph << [node, RDF::Vocab::FOAF.name, name.to_s]

  if name.is_a?(BibTeX::Name)
    %i[given family prefix suffix].each do |part|
      value = name.send(part)
      graph << [node, bibo["#{part}Name"], value.to_s] unless value.nil?
    end
  end

  node
end
entry() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 569
def entry
  @entry ||= RDF::URI.new(bibtex.identifier)
end
fallback() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 606
def fallback
  @fallback ||= bibtex.fields.keys
end
remove_from_fallback(*fields) click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 610
def remove_from_fallback(*fields)
  fields.each { |field| fallback.delete(field) }
end
run_fallback() click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 614
def run_fallback
  return if fallback.empty?

  ml = RDF::Vocabulary.new('http://bibtexml.sf.net/')
  fallback.each do |field|
    graph << [entry, ml[field], bibtex[field]]
  end
end
uri_in_graph?(uri) click to toggle source
# File lib/bibtex/entry/rdf_converter.rb, line 598
def uri_in_graph?(uri)
  solutions = RDF::Query.execute(graph) do
    pattern [uri, nil, nil]
  end

  !solutions.empty?
end