rbook 0.6.1

A fast, format-agnostic, ergonomic ebook library with a focus on EPUB 2 and 3.
Documentation

rbook

Crates.io Documentation License

rbook

A fast, format-agnostic, ergonomic ebook library with a focus on EPUB.

Features

Feature Overview Documentation
EPUB 2 and 3 Read-only (for now) view of EPUB 2 and 3 formats epub module
Reader Random‐access or sequential iteration over readable content. reader module
Detailed Types Abstractions built on expressive traits and types.
Metadata Typed access to titles, creators, publishers, languages, tags, roles, attributes, and more. metadata module
Manifest Lookup and traverse contained resources such as readable content (XHTML) and images. manifest module
Spine Chronological reading order and preferred page direction spine module
Table of Contents (ToC) Navigation points, including the EPUB 2 guide and EPUB 3 landmarks. toc module
Resources Retrieve bytes or UTF-8 strings for any manifest resource resource module

Usage

[dependencies]

rbook = "0.6.1"                                           # with default features

# rbook = { version = "0.6.1", default-features = false } # excluding default features

Default crate features:

  • prelude: Convenience prelude only including common traits.
  • threadsafe: Enables constraint and support for Send + Sync.

WebAssembly

The wasm32-unknown-unknown target is supported by default.

Examples

  • Opening and reading an EPUB file:
    use rbook::epub::{Epub, EpubSettings};
    use rbook::prelude::*; // Prelude for traits
    
    fn main() {
        // Opening an epub (file or directory)
        let epub = Epub::open_with(
           "tests/ebooks/example_epub",
           // Toggle strict EPUB checks (`true` by default)
           EpubSettings::builder().strict(false),
        ).unwrap();
    
        // Retrieving the title
        assert_eq!("Example EPUB", epub.metadata().title().unwrap().value());
        
        // Creating a reader instance:
        let mut reader = epub.reader(); // or `epub.reader_with(EpubReaderSettings)`
        // Printing the epub contents
        while let Some(Ok(data)) = reader.read_next() {
            let media_type = data.manifest_entry().media_type();
            assert_eq!("application/xhtml+xml", media_type);
            println!("{}", data.content());
        }
        
        assert_eq!(Some(4), reader.current_position());
    }
    
  • Accessing a metadata element:
    use rbook::Epub;
    use rbook::prelude::*;
    
    fn main() {
        let epub = Epub::open("tests/ebooks/example_epub").unwrap();
        
        let creator = epub.metadata().creators().next().unwrap();
        assert_eq!("John Doe", creator.value());
        assert_eq!(Some("Doe, John"), creator.file_as());
        assert_eq!(0, creator.order());
        
        let role = creator.main_role().unwrap();
        assert_eq!("aut", role.code());
        assert_eq!(Some("marc:relators"), role.source());
    }
    
  • Manifest media overlay and fallbacks:
    use rbook::Epub;
    use rbook::prelude::*;
    
    fn main() {
        let epub = Epub::open("tests/ebooks/example_epub").unwrap();
        
        // Retrieving media overlay information
        let chapter_1 = epub.manifest().by_id("c1").unwrap();
        let media_overlay = chapter_1.media_overlay().unwrap();
        let duration = media_overlay.refinements().by_property("media:duration").next().unwrap().value();
        assert_eq!("0:32:29", duration);
        
        // Fallbacks
        let webm_cover = epub.manifest().cover_image().unwrap();
        let kind = webm_cover.resource_kind();
        assert_eq!(("image", "webm"), (kind.maintype(), kind.subtype()));
        
        // If the app does not support `webm`; fallback
        let mut fallbacks = webm_cover.fallbacks();
        let avif_cover = fallbacks.next().unwrap();
        assert_eq!("image/avif", avif_cover.media_type());
        
        // If the app does not support `avif`; fallback
        let png_cover = fallbacks.next().unwrap();
        assert_eq!("image/png", png_cover.media_type());
        
        // No more fallbacks
        assert_eq!(None, fallbacks.next());
    }
    
  • Extracting images from the manifest:
    use rbook::Epub;
    use rbook::prelude::*;
    use std::fs::{self, File};
    use std::path::Path;
    use std::io::Write;
    
    fn main() {
        let epub = Epub::open("example.epub").unwrap();
        
        // Create a new directory to store the extracted images
        let dir = Path::new("extracted_images");
        fs::create_dir(&dir).unwrap();
        
        for image in epub.manifest().images() {
            let img_href = image.href().as_str();
            // Retrieve image contents
            let img = epub.read_resource_bytes(image.resource()).unwrap();
            // Retrieve the file name from the image href
            let file_name = Path::new(img_href).file_name().unwrap();
            // Create a new file
            let mut file = fs::File::create(dir.join(file_name)).unwrap();
            file.write_all(&img).unwrap();
        }
    }