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"
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::*;
fn main() {
let epub = Epub::open_with(
"tests/ebooks/example_epub",
EpubSettings::builder().strict(false),
).unwrap();
assert_eq!("Example EPUB", epub.metadata().title().unwrap().value());
let mut reader = epub.reader(); 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();
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);
let webm_cover = epub.manifest().cover_image().unwrap();
let kind = webm_cover.resource_kind();
assert_eq!(("image", "webm"), (kind.maintype(), kind.subtype()));
let mut fallbacks = webm_cover.fallbacks();
let avif_cover = fallbacks.next().unwrap();
assert_eq!("image/avif", avif_cover.media_type());
let png_cover = fallbacks.next().unwrap();
assert_eq!("image/png", png_cover.media_type());
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();
let dir = Path::new("extracted_images");
fs::create_dir(&dir).unwrap();
for image in epub.manifest().images() {
let img_href = image.href().as_str();
let img = epub.read_resource_bytes(image.resource()).unwrap();
let file_name = Path::new(img_href).file_name().unwrap();
let mut file = fs::File::create(dir.join(file_name)).unwrap();
file.write_all(&img).unwrap();
}
}