diff --git a/lightmotif-io/src/error.rs b/lightmotif-io/src/error.rs
index 4cb9707d19be4cee85a86b51dcc5d9eb7914e783..bfd5a2f30d0826abef9bc3e15e8a1436de636832 100644
--- a/lightmotif-io/src/error.rs
+++ b/lightmotif-io/src/error.rs
@@ -1,3 +1,6 @@
+use std::fmt::Display;
+use std::fmt::Formatter;
+
 use nom::error::Error as NomError;
 
 #[derive(Debug)]
@@ -34,3 +37,23 @@ impl From<nom::Err<NomError<&'_ str>>> for Error {
         }
     }
 }
+
+impl Display for Error {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Error::InvalidData => f.write_str("invalid data"),
+            Error::Io(err) => err.fmt(f),
+            Error::Nom(err) => err.fmt(f),
+        }
+    }
+}
+
+impl std::error::Error for Error {
+    fn cause(&self) -> Option<&dyn std::error::Error> {
+        match self {
+            Error::InvalidData => None,
+            Error::Io(e) => Some(e),
+            Error::Nom(e) => Some(e),
+        }
+    }
+}
diff --git a/lightmotif-io/src/transfac/mod.rs b/lightmotif-io/src/transfac/mod.rs
index 42b7ef7a0c96705998e30d3e2413569e9839f94e..777d494bdc0cc68a3fc710ec0d3054b9df67d5f3 100644
--- a/lightmotif-io/src/transfac/mod.rs
+++ b/lightmotif-io/src/transfac/mod.rs
@@ -1,3 +1,5 @@
+//! Parser implementation for the TRANSFAC format.
+
 use std::io::BufRead;
 
 use lightmotif::abc::Alphabet;
@@ -12,6 +14,7 @@ mod reader;
 
 pub use self::reader::Reader;
 
+/// A TRANSFAC record.
 #[derive(Debug, Clone)]
 pub struct Record<A: Alphabet> {
     id: Option<String>,
@@ -50,7 +53,12 @@ impl<A: Alphabet> Record<A> {
         self.data.as_ref()
     }
 
-    /// The raw data found in the matrix.
+    /// The references associated with the record.
+    pub fn references(&self) -> &[Reference] {
+        &self.references
+    }
+
+    /// Get the record matrix as an integer count data.
     pub fn to_counts(&self) -> Option<CountMatrix<A>> {
         if let Some(data) = &self.data {
             let mut counts = DenseMatrix::<u32, A::K>::new(data.rows());
@@ -69,6 +77,7 @@ impl<A: Alphabet> Record<A> {
         }
     }
 
+    /// Get the record matrix as a frequency matrix.
     pub fn to_freq<P>(&self, pseudo: P) -> Option<FrequencyMatrix<A>>
     where
         P: Into<Pseudocounts<A>>,
@@ -116,10 +125,12 @@ pub struct ReferenceNumber {
 }
 
 impl ReferenceNumber {
+    /// Create a new reference number with the given number.
     pub fn new(local: u32) -> Self {
-        Self { local, xref: None }
+        Self::with_xref(local, None)
     }
 
+    /// Create a new reference number with the given number and cross-reference.
     pub fn with_xref<X>(local: u32, xref: X) -> Self
     where
         X: Into<Option<String>>,
@@ -129,6 +140,16 @@ impl ReferenceNumber {
             xref: xref.into(),
         }
     }
+
+    /// The local number of the reference number.
+    pub fn local(&self) -> u32 {
+        self.local
+    }
+
+    /// The cross-reference, if any.
+    pub fn xref(&self) -> Option<&str> {
+        self.xref.as_ref().map(String::as_str)
+    }
 }
 
 #[derive(Clone, Debug)]
@@ -140,6 +161,38 @@ pub struct Reference {
     pmid: Option<String>,
 }
 
+impl Reference {
+    /// Create a new reference with the given reference number.
+    pub fn new(number: ReferenceNumber) -> Self {
+        Self {
+            number,
+            title: None,
+            link: None,
+            pmid: None,
+        }
+    }
+
+    /// The number of the reference.
+    pub fn number(&self) -> &ReferenceNumber {
+        &self.number
+    }
+
+    /// The title of the reference, if any.
+    pub fn title(&self) -> Option<&str> {
+        self.title.as_ref().map(String::as_str)
+    }
+
+    /// A link to the reference, if any.
+    pub fn link(&self) -> Option<&str> {
+        self.link.as_ref().map(String::as_str)
+    }
+
+    /// The PubMed ID of the reference, if any.
+    pub fn pmid(&self) -> Option<&str> {
+        self.pmid.as_ref().map(String::as_str)
+    }
+}
+
 pub fn read<B: BufRead, A: Alphabet>(reader: B) -> self::reader::Reader<B, A> {
     self::reader::Reader::new(reader)
 }
diff --git a/lightmotif-io/src/transfac/reader.rs b/lightmotif-io/src/transfac/reader.rs
index 1a0b48573a51b2738c1bd916c04f606b789cfa36..6a8dcbf32e491c7b88b5f055121f36c06d1967c7 100644
--- a/lightmotif-io/src/transfac/reader.rs
+++ b/lightmotif-io/src/transfac/reader.rs
@@ -6,6 +6,8 @@ use lightmotif::Alphabet;
 use super::Record;
 use crate::error::Error;
 
+/// A reader for TRANSFAC-formatted files.
+#[derive(Debug)]
 pub struct Reader<B: BufRead, A: Alphabet> {
     buffer: String,
     bufread: B,