All formats

epub-builder

LanguageRust
LicenseMPL-2.0
Repositorygithub.com/crowdagger/epub-builder
Documentationdocs.rs/epub-builder
Depends onzip crate (or the zip command), upon (templates), html-escape, uuid, chrono
Read / writeno / yes (EPUB 2.0.1, 3.0.1, 3.3)

epub-builder takes care of the EPUB boilerplate: you add XHTML chapters, images, a stylesheet and metadata, and it writes mimetype, container.xml, the OPF package, toc.ncx, the EPUB 3 nav.xhtml and an optional inline table of contents page, then zips everything. It’s used by Crowbook and other Rust tools that turn Markdown into e-books.

The default output is EPUB 2.0.1 for maximum compatibility; call epub_version to produce EPUB 3. Chapter content must be valid XHTML: the crate doesn’t convert or validate HTML.

Installation#

TOML
[dependencies]
epub-builder = "0.8"

The default features include both the pure-Rust ZIP writer (ZipLibrary) and a wrapper around the zip command (ZipCommand).

Basic usage: create an EPUB#

Rust
use epub_builder::{EpubBuilder, EpubContent, EpubVersion, ReferenceType, Result, ZipLibrary};
use std::fs::File;

fn chapter(title: &str, text: &str) -> String {
    format!(
        r#"<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head><title>{title}</title></head>
<body><h1>{title}</h1><p>{text}</p></body>
</html>"#
    )
}

fn main() -> Result<()> {
    let mut builder = EpubBuilder::new(ZipLibrary::new()?)?;
    builder.epub_version(EpubVersion::V30);
    builder
        .metadata("author", "Jane Doe")?
        .metadata("title", "My Book")?
        .metadata("lang", "en")?
        .stylesheet("body { font-family: serif; }".as_bytes())?
        .add_content(
            EpubContent::new("chapter_1.xhtml", chapter("Chapter 1", "First chapter.").as_bytes())
                .title("Chapter 1")
                .reftype(ReferenceType::Text),
        )?
        .add_content(
            EpubContent::new("chapter_2.xhtml", chapter("Chapter 2", "Second chapter.").as_bytes())
                .title("Chapter 2"),
        )?;

    let mut file = File::create("book.epub")?;
    builder.generate(&mut file)?;
    Ok(())
}

.title() puts the chapter in the table of contents; content without a title is in the reading order but not in the TOC.

How to add a cover image#

Rust
let cover = std::fs::read("cover.jpg")?;
builder.add_cover_image("cover.jpg", cover.as_slice(), "image/jpeg")?;

How to add images used in chapters#

Rust
let photo = std::fs::read("photo.png")?;
builder.add_resource("images/photo.png", photo.as_slice(), "image/png")?;
// in the chapter XHTML: <img src="images/photo.png" alt="photo"/>

How to build nested table of contents entries#

Rust
use epub_builder::TocElement;

builder.add_content(
    EpubContent::new("part1.xhtml", part1_xhtml.as_bytes())
        .title("Part 1")
        .child(TocElement::new("part1.xhtml#ch1", "Chapter 1"))
        .child(TocElement::new("part1.xhtml#ch2", "Chapter 2")),
)?;
// or: a following EpubContent with .level(2) is nested under the previous one

How to add an inline table of contents page#

Rust
builder.inline_toc();

This adds a table of contents page to the reading order, in addition to the navigation document that readers show in their menus.

Tips#