Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EPUB 3.x Implementation in Rust

https://www.w3.org/TR/epub-33/

  • Stable
  • Base Header and Text Flow
  • ToC
  • Deflated Zip
  • Stored for valid decrypted files
  • UUID for XHTML's items
  • Validade data entries
  • Optional META_INF (encryption.xml, metadata.xml, manifest.xml, ...)
  • container.xml access
  • Images
  • Multiple CSS stylesheets
  • Checkbox and List's
  • Custom Fonts

Examples

epub-gen-rs supports rust, node and web browser (with wasm).

Rust

let mut epub = EPUB::new(Info {
  title: String::from("A Nice Title"),
  description: String::from("A some description..."),
  publisher: String::from("..."),
  author: String::from("..."),
  toc_title: String::from("Table of Contents"),
  lang: String::from("en"),
  fonts: vec![String::from("Roboto")],
  css: None,
  version: 3,
  stylesheets: vec![],
  encryption: None,
  metadata_xml: None,
  manifest_xml: None,
}, vec![macro_for_this_please![
  "Title",
  "A some content...",
]]);

epub.run();

With a cover image, an inline figure, and multiple stylesheets:

use std::fs;

let cover_bytes = fs::read("cover.jpg").unwrap();
let figure_bytes = fs::read("figure.png").unwrap();

let mut epub = EPUB::new(
  Info {
    title: String::from("A Nice Title"),
    description: String::from("..."),
    publisher: String::from("..."),
    author: String::from("..."),
    toc_title: String::from("Table of Contents"),
    lang: String::from("en"),
    fonts: vec![],
    css: Some(String::from("body { font-family: serif; }")),
    version: 3,
    stylesheets: vec![
      Stylesheet {
        id: String::from("typo"),
        path: String::from("css/typography.css"),
        content: String::from("h1 { font-size: 2rem; } p { line-height: 1.6; }"),
      },
    ],
    encryption: None,
    metadata_xml: None,
    manifest_xml: None,
  },
  vec![vec![
    String::from("Chapter One"),
    String::from("The chart below illustrates the data."),
    String::from(r#"<img src="images/figure.png" alt="Figure 1" />"#),
  ]],
)
.with_images(vec![
  Image {
    id: String::from("cover-img"),
    path: String::from("cover.jpg"),
    data: cover_bytes,
    cover: true,
  },
  Image {
    id: String::from("figure-img"),
    path: String::from("figure.png"),
    data: figure_bytes,
    cover: false,
  },
]);

// epub.run()  — writes <title>.epub to disk
// epub.archive()  — returns Vec<u8> for streaming

Node

npm install epub-gen3

'use strict'

const fs = require('fs')
const path = require('path')
const { Epub } = require('epub-gen3')

const epub = new Epub(
  {
    title: 'exemplo',
    description: 'epub-gen-rs example.',
    publisher: 'epub-gen-rs',
    author: 'Author',
    tocTitle: 'Toc Title',
    lang: 'en',
    fonts: [],
    css: undefined,
    version: 3,
  },
  [
    [
      'One',
      'Nullam tempor, metus vitae sagittis semper, massa nulla posuere ipsum.',
      'Aliquam non posuere ex. Duis fermentum odio metus, quis ultrices nulla cursus vitae.',
    ],
    [
      'Two',
      'Pellentesque tempor, eros eu consectetur cursus, magna turpis lacinia nunc.',
      'Integer iaculis arcu vitae elementum convallis. Praesent quam magna, maximus sed ullamcorper quis.',
    ]
  ],
)

const buf = epub.archive()
const outPath = path.join(__dirname, 'example.epub')
fs.writeFileSync(outPath, buf)
console.log(`${outPath} (${buf.length} bytes)`)

With a cover image, an inline figure, and multiple stylesheets:

const fs = require('fs')
const { Epub } = require('epub-gen3')

const epub = new Epub(
  {
    title: 'exemplo',
    description: 'epub-gen-rs example.',
    publisher: 'epub-gen-rs',
    author: 'Author',
    tocTitle: 'Toc Title',
    lang: 'en',
    fonts: [],
    css: 'body { font-family: serif; }',
    version: 3,
  },
  [
    [
      'Chapter One',
      'The chart below illustrates the data.',
      '<img src="images/figure.png" alt="Figure 1" />',
    ],
  ],
)

epub.setStylesheets([
  { id: 'typo', path: 'css/typography.css', content: 'h1 { font-size: 2rem; } p { line-height: 1.6; }' },
])

epub.setImages([
  { id: 'cover-img', path: 'cover.jpg', data: fs.readFileSync('cover.jpg'), cover: true },
  { id: 'figure-img', path: 'figure.png', data: fs.readFileSync('figure.png'), cover: false },
])

fs.writeFileSync('example.epub', epub.archive())

Browser

import { Epub, ready } from 'epub-gen3/browser'

await ready   // waits for the WASM module to initialise

const epub = new Epub(
  { title: 'My Book', description: '...', publisher: '...', author: '...',
    tocTitle: 'Sumário', lang: 'pt', fonts: [], version: 3 },
  [['1', 'Foo bar baz']]
)

epub.setStylesheets([
  { id: 'base', path: 'css/base.css', content: 'body { font-family: serif; line-height: 1.6; }' },
])

const bytes = epub.archive()
const blob  = new Blob([bytes], { type: 'application/epub+zip' })
const url   = URL.createObjectURL(blob)
const a     = Object.assign(document.createElement('a'), { href: url, download: 'book.epub' })
a.click()

Vite users: add optimizeDeps.exclude: ['epub-gen3'] to vite.config.ts so Vite does not try to pre-bundle the WASM glue code.

// vite.config.ts
export default { optimizeDeps: { exclude: ['epub-gen3'] } }

With a cover image fetched from a URL:

import { Epub, ready } from 'epub-gen3/browser'

await ready

const coverRes = await fetch('/cover.jpg')
const coverData = new Uint8Array(await coverRes.arrayBuffer())

const epub = new Epub(
  { title: 'My Book', description: '...', publisher: '...', author: '...',
    tocTitle: 'Summary', lang: 'pt', fonts: [], version: 3 },
  [
    ['Chapter 1', 'Text.'],
    ['Chapter 2', '<img src="images/cover.jpg" alt="Cover" />'],
  ]
)

epub.setImages([
  { id: 'cover-img', path: 'cover.jpg', data: coverData, cover: true },
])

const bytes = epub.archive()
const blob  = new Blob([bytes], { type: 'application/epub+zip' })
const url   = URL.createObjectURL(blob)
Object.assign(document.createElement('a'), { href: url, download: 'livro.epub' }).click()

About

EPUB 3.x Implementation in Rust. Support Node and Browser

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages