glepub

An EPUB toolkit for the Erlang and JavaScript targets.

glepub is the format layer of an EPUB reader: it opens the container, parses the package document (OPF), navigation (EPUB 3 nav documents and EPUB 2 NCX), and exposes a typed Book — metadata, manifest, spine, table of contents, landmarks, and cover.

Like glexml underneath it, glepub performs no I/O of its own. Opening a book takes a Loader: a function from a path inside the container to its bytes. Supply one backed by whatever suits the platform — a zip library on the server, a JSZip-style reader in the browser, a directory on disk, or a dictionary in tests.

let assert Ok(book) = glepub.open(loader)
book.metadata.title            // -> "Moby-Dick; or, The Whale"
list.map(book.spine, fn(s) { s.item.href })
book.toc                       // -> nested TocEntry tree

Types

An opened EPUB publication.

pub type Book {
  Book(
    version: String,
    metadata: Metadata,
    manifest: List(ManifestItem),
    spine: List(SpineItem),
    toc: List(TocEntry),
    page_list: List(TocEntry),
    landmarks: List(TocEntry),
    direction: Direction,
    rendition: Rendition,
    cover: option.Option(ManifestItem),
    loader: fn(String) -> Result(BitArray, Nil),
  )
}

Constructors

  • Book(
      version: String,
      metadata: Metadata,
      manifest: List(ManifestItem),
      spine: List(SpineItem),
      toc: List(TocEntry),
      page_list: List(TocEntry),
      landmarks: List(TocEntry),
      direction: Direction,
      rendition: Rendition,
      cover: option.Option(ManifestItem),
      loader: fn(String) -> Result(BitArray, Nil),
    )

    Arguments

    version

    The package version, e.g. "3.0" or "2.0".

    manifest

    Every resource the package declares.

    spine

    The reading order.

    toc

    The table of contents, from the EPUB 3 nav document or the EPUB 2 NCX, whichever the book provides.

    page_list

    The page list, if the book provides one.

    landmarks

    Landmarks (EPUB 3) or the guide (EPUB 2).

    direction

    Reading direction of the spine.

    cover

    The cover image, when one is identified.

    loader

    The loader the book was opened with, used by resource and document.

pub type Contributor {
  Contributor(
    name: String,
    role: option.Option(String),
    file_as: option.Option(String),
  )
}

Constructors

  • Contributor(
      name: String,
      role: option.Option(String),
      file_as: option.Option(String),
    )

    Arguments

    role

    A MARC relator code such as "aut" or "ill", when given.

    file_as

    The name normalised for sorting, when given.

pub type Direction {
  LeftToRight
  RightToLeft
  DefaultDirection
}

Constructors

  • LeftToRight
  • RightToLeft
  • DefaultDirection
pub type EpubError {
  MissingFile(path: String)
  InvalidXml(path: String, error: glexml.ParseError)
  InvalidPackage(description: String)
}

Constructors

  • MissingFile(path: String)

    The loader had no file at this path.

  • InvalidXml(path: String, error: glexml.ParseError)

    A file exists but is not well-formed XML.

  • InvalidPackage(description: String)

    The container or package is structurally wrong; the description says how.

pub type Layout {
  Reflowable
  PrePaginated
}

Constructors

  • Reflowable
  • PrePaginated

Reads the bytes of a file inside the container, by its path from the container root (e.g. "OEBPS/content.opf"). Paths are given percent-decoded and normalised, with no leading slash.

pub type Loader =
  fn(String) -> Result(BitArray, Nil)
pub type ManifestItem {
  ManifestItem(
    id: String,
    href: String,
    media_type: String,
    properties: List(String),
  )
}

Constructors

  • ManifestItem(
      id: String,
      href: String,
      media_type: String,
      properties: List(String),
    )

    Arguments

    href

    The path within the container, resolved from the package document and percent-decoded, ready to pass to the loader.

pub type Metadata {
  Metadata(
    identifier: String,
    title: String,
    language: String,
    creators: List(Contributor),
    contributors: List(Contributor),
    publisher: option.Option(String),
    description: option.Option(String),
    published: option.Option(String),
    modified: option.Option(String),
    subjects: List(String),
    rights: option.Option(String),
  )
}

Constructors

  • Metadata(
      identifier: String,
      title: String,
      language: String,
      creators: List(Contributor),
      contributors: List(Contributor),
      publisher: option.Option(String),
      description: option.Option(String),
      published: option.Option(String),
      modified: option.Option(String),
      subjects: List(String),
      rights: option.Option(String),
    )

    Arguments

    identifier

    The package’s unique identifier.

    published

    The publication date (dc:date).

    modified

    The last-modified timestamp (dcterms:modified).

pub type Rendition {
  Rendition(
    layout: Layout,
    orientation: option.Option(String),
    spread: option.Option(String),
  )
}

Constructors

pub type SpineItem {
  SpineItem(
    item: ManifestItem,
    linear: Bool,
    properties: List(String),
    cfi: String,
  )
}

Constructors

  • SpineItem(
      item: ManifestItem,
      linear: Bool,
      properties: List(String),
      cfi: String,
    )

    Arguments

    cfi

    The CFI path to this itemref in the package document, e.g. /6/4[chap01ref] — the part of an epubcfi(...) locator before the ! indirection. See glepub/cfi.

One entry of a table of contents, page list, or landmarks navigation.

pub type TocEntry {
  TocEntry(
    label: String,
    href: option.Option(String),
    children: List(TocEntry),
  )
}

Constructors

  • TocEntry(
      label: String,
      href: option.Option(String),
      children: List(TocEntry),
    )

    Arguments

    href

    The target as a container path plus optional fragment, resolved relative to the document that declared it. None for entries that are only headings.

Values

pub fn document(
  book: Book,
  item: ManifestItem,
) -> Result(glexml.Document, EpubError)

Read and parse a manifest item as XML — a content document, for instance. EPUB 2 XHTML may use the named entities of the XHTML DTD; supply them with document_with_dtd if you need them.

pub fn document_with_dtd(
  book: Book,
  item: ManifestItem,
  dtd: glexml.Dtd,
) -> Result(glexml.Document, EpubError)

Like document, with extra DTD declarations available — typically the XHTML entity set for EPUB 2 content documents.

pub fn error_to_string(error: EpubError) -> String

Convert an EpubError into a human readable message.

pub fn is_external(reference: String) -> Bool

Whether a reference in a content document points outside the container.

pub fn item_for_href(
  book: Book,
  href: String,
) -> Result(ManifestItem, Nil)

Find the manifest item a container path (as produced in TocEntry.href, fragment ignored) refers to.

pub fn open(
  loader: fn(String) -> Result(BitArray, Nil),
) -> Result(Book, EpubError)

Open a publication: read META-INF/container.xml, find the package document, and parse the package, navigation, and cover information.

pub fn resolve(base: String, reference: String) -> String

Resolve a reference found in the document at directory base to a container path: percent-decoded, ./.. normalised, fragment kept.

pub fn resource(
  book: Book,
  item: ManifestItem,
) -> Result(BitArray, EpubError)

Read a manifest item’s bytes from the container.

pub fn strip_fragment(href: String) -> String

The container path without any #fragment.

Search Document