An open API service indexing awesome lists of open source software.

https://github.com/kerams/epubfs

EPUB authoring library for F#.
https://github.com/kerams/epubfs

dotnet ebook epub fsharp

Last synced: 4 months ago
JSON representation

EPUB authoring library for F#.

Awesome Lists containing this project

README

          

# EpubFs

EPUB authoring library for F#.

## Nuget package
[![Nuget](https://img.shields.io/nuget/v/EpubFs.svg?colorB=green)](https://www.nuget.org/packages/EpubFs)

## 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](https://github.com/giraffe-fsharp/Giraffe.ViewEngine), 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

```fsharp
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 =
"""Page one

Ἄνδρα μοι ἔννεπε, Μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσε·
"""
|> 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
```