BibframeRuby

A Ruby gem for parsing BIBFRAME data into Ruby objects. Currently supports JSON-LD, with Turtle and RDF/XML support planned.

Built on the RDF.rb ecosystem, BibframeRuby converts BIBFRAME documents into typed Ruby objects with idiomatic accessors and linked relationships.

Installation

Add this line to your application's Gemfile:

gem "bibframe_ruby"

And then execute:

bundle install

Or install it yourself as:

gem install bibframe_ruby

Usage

Parsing JSON-LD

require "bibframe_ruby"

# Parse a JSON-LD string
json = File.read("work.jsonld")
graph = BibframeRuby.parse(json)

# Or parse directly from a file (format detected from extension)
graph = BibframeRuby.parse_file("work.jsonld")

# Parse from a remote URI (fetches the content)
graph = BibframeRuby.parse_uri("https://id.loc.gov/resources/hubs/4076e139-793f-bb85-515c-840510066bac.jsonld")

Accessing Resources

The returned Graph provides typed collections:

graph.works      # => [BibframeRuby::Work, ...]
graph.instances  # => [BibframeRuby::Instance, ...]
graph.items      # => [BibframeRuby::Item, ...]
graph.hubs       # => [BibframeRuby::Hub, ...]
graph.resources  # => all parsed resources

Working with a Work

work = graph.works.first

work.id
# => "https://dev.bcld.info/works/25305194-1115-43ab-8a7c-4ef586a1e8e5"

work.types
# => ["Monograph", "Text", "Work"]

work.title.main_title
# => "The dungeon anarchist's cookbook"

work.title.non_sort_num
# => "4"

work.language
# => "http://id.loc.gov/vocabulary/languages/eng"

work.genre_forms
# => ["http://id.loc.gov/authorities/genreForms/gf2023026123", ...]

work.summary
# => "\"Welcome to the Gun Show! The top ten list is populated..."

work.classifications.length
# => 2

Contributions

contribution = work.contributions.first

contribution.primary?
# => true

contribution.role
# => "http://id.loc.gov/vocabulary/relators/aut"

contribution.agent.id
# => "http://id.loc.gov/rwo/agents/no2023085548"

Working with an Instance

When you parse both a Work and its Instance, the relationships are automatically linked:

instance = graph.instances.first

instance.title.main_title
# => "The dungeon anarchist's cookbook"

instance.extent
# => "532 pages"

instance.dimensions
# => "24 cm"

instance.edition_statement
# => "First Ace edition"

instance.publication_statement
# => "New York: Ace, 2024"

# Bidirectional linking
instance.work.title.main_title
# => "The dungeon anarchist's cookbook"

work.instances.first == instance
# => true

Working with a Hub

Hubs are abstract resources that bridge between Works — commonly used for authority-linked title/author combinations.

graph = BibframeRuby.parse_file("hub.jsonld")
hub = graph.hubs.first

hub.id
# => "http://id.loc.gov/resources/hubs/4076e139-793f-bb85-515c-840510066bac"

hub.types
# => ["Work", "Hub", "Series"]

hub.title.main_title
# => "Dungeon crawler Carl (Series)"

hub.contributions.first.primary?
# => true

hub.relations.length
# => 1

Identifiers

instance.identifiers.length
# => 2

lccn = instance.identifiers.find { |id| id.types.include?("Lccn") }
isbn = instance.identifiers.find { |id| id.types.include?("Isbn") }

Hash-Style Property Access

Any property can be accessed by name, even if there is no named accessor:

work["language"]
# => "http://id.loc.gov/vocabulary/languages/eng"

work["aap"]
# => "Dinniman, Matt. The dungeon anarchist's cookbook"

Combining Multiple Documents

To parse related documents together (e.g., a Work and its Instance), combine their RDF graphs before building:

work_graph = BibframeRuby::Parser.new(work_json, format: :jsonld).parse
instance_graph = BibframeRuby::Parser.new(instance_json, format: :jsonld).parse

# Merge statements into one graph
instance_graph.each_statement { |s| work_graph << s }

# Build with linked relationships
result = BibframeRuby::Graph.from_rdf(work_graph)

result.works.first.instances.first.extent
# => "532 pages"

Converting from MARC

Convert MARC records (binary MARC21 or MARCXML) to BIBFRAME using the Library of Congress marc2bibframe2 XSLT stylesheets:

# Convert a binary MARC file
graph = BibframeRuby.convert_marc("record.mrc")

# With a custom base URI for minted resource URIs
graph = BibframeRuby.convert_marc("record.mrc", baseuri: "https://mylib.org/catalog/")

# MARCXML is also accepted
graph = BibframeRuby.convert_marc("record.xml", baseuri: "https://mylib.org/catalog/")

graph.works.first.title.main_title
# => "The Title"

The baseuri parameter controls the base URI for generated resource identifiers (default: http://example.org/). The optional idsource parameter identifies the converting agent.

Stub Resources

When a parsed document references an external resource by URI (e.g., an agent in the Library of Congress), a stub Resource is created with just the id set:

agent = work.contributions.first.agent
agent.id
# => "http://id.loc.gov/rwo/agents/no2023085548"

agent.is_a?(BibframeRuby::Resource)
# => true

Serializing to RDF

Serialize a graph or individual resource back to JSON-LD or Turtle:

# Serialize the entire graph to JSON-LD (default)
puts graph.to_rdf

# Serialize to Turtle
puts graph.to_rdf(format: :turtle)

# Serialize a single resource (includes its nested blank nodes)
puts work.to_rdf
puts work.to_rdf(format: :turtle)

Output includes BIBFRAME-aware prefixes (bf:, bflc:, rdfs:, etc.) for readable output.

Model Reference

Class Accessors
Resource id, types, properties, [], []=, to_rdf
Work title, contributions, instances, language, subjects, genre_forms, summary, classifications, relations
Instance title, work, identifiers, extent, carrier, media, provision_activity, edition_statement, dimensions, publication_statement, items
Hub title, contributions, language, identifiers, relations, label
Item instance, held_by, shelf_mark
Contribution agent, role, primary?
Title main_title, subtitle, non_sort_num
Agent label
Person label (inherits from Agent)
Organization label (inherits from Agent)
Subject label, source

All models inherit from Resource and support hash-style access via [] for any property.

Supported Formats

Format Status File Extension
JSON-LD Supported .jsonld
Turtle Supported .ttl
RDF/XML Supported .rdf
MARC21 (binary) Supported (convert) .mrc
MARCXML Supported (convert) .xml

Development

After checking out the repo, run bin/setup to install dependencies.

Running Tests

bundle exec rspec

With documentation output:

bundle exec rspec --format documentation

Console

You can run bin/console for an interactive prompt to experiment with the gem.

Requirements

  • Ruby >= 3.2.0

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/aaron-collier/bibframe_ruby.