Skip to content

Latest commit

 

History

History
101 lines (78 loc) · 4.35 KB

README.md

File metadata and controls

101 lines (78 loc) · 4.35 KB

EpubFs

EPUB authoring library for F#.

Nuget package

Nuget

Project status

This library has been extracted from a personal project of mine and represents the bare minimum necessary to create EPUB files for my purposes. As such, I do not intend to continue developing any new major features.

However, if you or your company have a need for a particular feature or require that some other part of the EPUB spec be implemented, and you are willing to pay for the development, I would be more than happy to work with you!

Bug reports and PRs will naturally still be looked at.

Usage

In order to create an EPUB, you need to supply some metadata and a file manifest including the title page, list of files with the actual book content as well as any CSS files you want to use.

Content files

Content files are accepted in the form of XmlNode list, which you can construct using the Giraffe.ViewEngine DSL, or as a Stream containing an XHTML that you have obtained in some other way.

CSS files

You can also include stylesheets to be used in the book. If a content file is provided as XmlNode list, every CSS file will automatically be referenced therein. On the other hand, if you're supplying a full XHTML file, you need to import the stylesheet (in the traditional HTML fashion) yourself by using the FileName of a matching CSS file.

Table of contents (navigation document)

Every EPUB requires a navigation document. There are two choices here - either you supply an XHTML (it has to conform to the navigation spec!) directly, or you let the library generate a simple table of contents page with hyperlinks to each of your content files (whose Navigation is not set to None).

Example

open EpubFs
open EpubFs.Write
open Giraffe.ViewEngine
open System.IO
open System.Text

let metadata = {
    // A unique book identifier, could be ISBN or URL...
    Id = "my-book"
    Title = "Ὀδύσσεια"
    // List of language tags - you should use ISO 639-2
    // If you specify more than one, the first is considered the primary language of the book
    Languages = [ "grc" ]
    // `None` defaults to DateTimeOffset.UtcNow
    ModifiedAt = None
    Source = Some "https://el.wikisource.org/wiki/%CE%9F%CE%B4%CF%8D%CF%83%CF%83%CE%B5%CE%B9%CE%B1"
    Creators = [ "John Doe"; "Ὅμηρος" ]
}

// The CSS Stream you would like to use throughout the book
let css = new MemoryStream (Encoding.UTF8.GetBytes ".red-font { color: red }")

// Let's declare the title page document using `Giraffe.ViewEngine`
// Use the `red-font` class from our stylesheet
let titlePage = {
    FileName = "title.xhtml"
    Title = "Title"
    Input = Structured [
        h1 [ _class "red-font" ] [
            str "Ὀδύσσεια"
        ]
    ]
    Navigation = None
}

// We already have a pre-built XHTML of the first content document, so pass it as a stream
// Notice the manual reference to our stylesheet
use chapter1Stream =
    """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><link href="main.css" type="text/css" rel="stylesheet"/><title>Page one</title></head><body><div class="red-font">Ἄνδρα μοι ἔννεπε, Μοῦσα, πολύτροπον, ὃς μάλα πολλὰ</div><div>πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσε·</div></body></html>"""
    |> Encoding.UTF8.GetBytes
    |> MemoryStream

let chapter1 = {
    FileName = "chapter1.xhtml"
    Title = "Chapter 1"
    Input = ContentInput.Raw (RawInput.Stream page1Stream)
    // Setting navigation to `Some` so that this document appears in the table of contents
    Navigation = Some Linear
}

let manifest = {
    // Usually used by e-book readers as the book thumbnail
    CoverImage = None
    // Table of contents will be generated for us
    NavXhtml = Autogenerated
    TitlePage = titlePage
    ContentFiles = [ chapter1 ]
    CssFiles = [
        // The file will be stored in the archive under this name
        // It's also what you use to reference the stylesheet in XHTML
        { FileName = "main.css"; Input = RawInput.Stream css }
    ]
}

use fs = File.OpenWrite "odyssey.epub"
write fs metadata manifest