epub

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 2, 2023 License: MIT Imports: 24 Imported by: 49

README

CI Coverage Status Go Report Card License GoDoc


Features

  • Documented API
  • Creates valid EPUB 3.0 files
  • Adds an additional EPUB 2.0 table of contents (as seen here) for maximum compatibility
  • Includes support for adding CSS, images, and fonts

For an example of actual usage, see https://github.com/bmaupin/go-docs-epub

Contributions

Contributions are welcome; please see CONTRIBUTING.md for more information.

Development

Clone this repository using Git. Run tests as documented below.

Dependencies are managed using Go modules

Testing

EPUBCheck

EPUBCheck is a tool that will check an EPUB for validation errors.

If EPUBCheck is installed locally, it will be run alongside the Go tests. To install EPUBCheck:

  1. Make sure you have Java installed on your system

  2. Get the latest version of EPUBCheck from https://github.com/w3c/epubcheck/releases

  3. Download and extract EPUBCheck in the root directory of this project, e.g.

    wget https://github.com/IDPF/epubcheck/releases/download/v4.2.5/epubcheck-4.2.5.zip
    unzip epubcheck-4.2.5.zip
    

If you do not wish to install EPUBCheck locally, you can manually validate the EPUB:

  1. Set doCleanup = false in epub_test.go

  2. Run the tests (see below)

  3. Upload the generated My EPUB.epub file to http://validator.idpf.org/

Run tests

go test

Documentation

Overview

Package epub generates valid EPUB 3.0 files with additional EPUB 2.0 table of contents (as seen here: https://github.com/bmaupin/epub-samples) for maximum compatibility.

Basic usage:

// Create a new EPUB
e := epub.NewEpub("My title")

// Set the author
e.SetAuthor("Hingle McCringleberry")

// Add a section
section1Body := `<h1>Section 1</h1>
<p>This is a paragraph.</p>`
e.AddSection(section1Body, "Section 1", "", "")

// Write the EPUB
err = e.Write("My EPUB.epub")
if err != nil {
	// handle error
}

Index

Examples

Constants

View Source
const (
	CSSFolderName   = "css"
	FontFolderName  = "fonts"
	ImageFolderName = "images"
	VideoFolderName = "videos"
	AudioFolderName = "audios"
)

Folder names used for resources inside the EPUB

Variables

This section is empty.

Functions

func Use added in v0.10.0

func Use(s FSType)

Use s as default storage/ This is typically used in an init function. Default to local filesystem

Types

type Epub

type Epub struct {
	sync.Mutex
	*http.Client
	// contains filtered or unexported fields
}

Epub implements an EPUB file.

func NewEpub

func NewEpub(title string) *Epub

NewEpub returns a new Epub.

func (*Epub) AddAudio added in v1.1.0

func (e *Epub) AddAudio(source string, audioFilename string) (string, error)

AddAudio adds an audio to the EPUB and returns a relative path to the audio file that can be used in EPUB sections in the format: ../AudioFolderName/internalFilename

The audio source should either be a URL, a path to a local file, or an embedded data URL; in any case, the audio file will be retrieved and stored in the EPUB.

The internal filename will be used when storing the audio file in the EPUB and must be unique among all audio files. If the same filename is used more than once, FilenameAlreadyUsedError will be returned. The internal filename is optional; if no filename is provided, one will be generated.

func (*Epub) AddCSS

func (e *Epub) AddCSS(source string, internalFilename string) (string, error)

AddCSS adds a CSS file to the EPUB and returns a relative path to the CSS file that can be used in EPUB sections in the format: ../CSSFolderName/internalFilename

The CSS source should either be a URL, a path to a local file, or an embedded data URL; in any case, the CSS file will be retrieved and stored in the EPUB.

The internal filename will be used when storing the CSS file in the EPUB and must be unique among all CSS files. If the same filename is used more than once, FilenameAlreadyUsedError will be returned. The internal filename is optional; if no filename is provided, one will be generated.

Example
e := epub.NewEpub("My title")

// Add CSS
css1Path, err := e.AddCSS("testdata/cover.css", "epub.css")
if err != nil {
	log.Fatal(err)
}

// The filename is optional
css2Path, err := e.AddCSS("testdata/cover.css", "")
if err != nil {
	log.Fatal(err)
}

// Use the CSS in a section
sectionBody := `    <h1>Section 1</h1>
	<p>This is a paragraph.</p>`
e.AddSection(sectionBody, "Section 1", "", css1Path)

fmt.Println(css1Path)
fmt.Println(css2Path)
Output:

../css/epub.css
../css/cover.css

func (*Epub) AddFont

func (e *Epub) AddFont(source string, internalFilename string) (string, error)

AddFont adds a font file to the EPUB and returns a relative path to the font file that can be used in EPUB sections in the format: ../FontFolderName/internalFilename

The font source should either be a URL, a path to a local file, or an embedded data URL; in any case, the font file will be retrieved and stored in the EPUB.

The internal filename will be used when storing the font file in the EPUB and must be unique among all font files. If the same filename is used more than once, FilenameAlreadyUsedError will be returned. The internal filename is optional; if no filename is provided, one will be generated.

Example
e := epub.NewEpub("My title")

// Add a font from a local file
font1Path, err := e.AddFont("testdata/redacted-script-regular.ttf", "font.ttf")
if err != nil {
	log.Fatal(err)
}

// The filename is optional
font2Path, err := e.AddFont("testdata/redacted-script-regular.ttf", "")
if err != nil {
	log.Fatal(err)
}

fmt.Println(font1Path)
fmt.Println(font2Path)
Output:

../fonts/font.ttf
../fonts/redacted-script-regular.ttf

func (*Epub) AddImage

func (e *Epub) AddImage(source string, imageFilename string) (string, error)

AddImage adds an image to the EPUB and returns a relative path to the image file that can be used in EPUB sections in the format: ../ImageFolderName/internalFilename

The image source should either be a URL, a path to a local file, or an embedded data URL; in any case, the image file will be retrieved and stored in the EPUB.

The internal filename will be used when storing the image file in the EPUB and must be unique among all image files. If the same filename is used more than once, FilenameAlreadyUsedError will be returned. The internal filename is optional; if no filename is provided, one will be generated.

Example
e := epub.NewEpub("My title")

// Add an image from a local file
img1Path, err := e.AddImage("testdata/gophercolor16x16.png", "go-gopher.png")
if err != nil {
	log.Fatal(err)
}

// Add an image from a URL. The filename is optional
img2Path, err := e.AddImage("https://golang.org/doc/gopher/gophercolor16x16.png", "")
if err != nil {
	log.Fatal(err)
}

fmt.Println(img1Path)
fmt.Println(img2Path)
Output:

../images/go-gopher.png
../images/gophercolor16x16.png

func (*Epub) AddSection

func (e *Epub) AddSection(body string, sectionTitle string, internalFilename string, internalCSSPath string) (string, error)

AddSection adds a new section (chapter, etc) to the EPUB and returns a relative path to the section that can be used from another section (for links).

The body must be valid XHTML that will go between the <body> tags of the section XHTML file. The content will not be validated.

The title will be used for the table of contents. The section will be shown in the table of contents in the same order it was added to the EPUB. The title is optional; if no title is provided, the section will not be added to the table of contents.

The internal filename will be used when storing the section file in the EPUB and must be unique among all section files. If the same filename is used more than once, FilenameAlreadyUsedError will be returned. The internal filename is optional; if no filename is provided, one will be generated.

The internal path to an already-added CSS file (as returned by AddCSS) to be used for the section is optional.

Example
e := epub.NewEpub("My title")

// Add a section. The CSS path is optional
section1Body := `    <h1>Section 1</h1>
	<p>This is a paragraph.</p>`
section1Path, err := e.AddSection(section1Body, "Section 1", "firstsection.xhtml", "")
if err != nil {
	log.Fatal(err)
}

// Link to the first section
section2Body := fmt.Sprintf(`    <h1>Section 2</h1>
	<a href="%s">Link to section 1</a>`,
	section1Path)
// The title and filename are also optional
section2Path, err := e.AddSection(section2Body, "", "", "")
if err != nil {
	log.Fatal(err)
}

fmt.Println(section1Path)
fmt.Println(section2Path)
Output:

firstsection.xhtml
section0001.xhtml

func (*Epub) AddSubSection added in v1.0.0

func (e *Epub) AddSubSection(parentFilename string, body string, sectionTitle string, internalFilename string, internalCSSPath string) (string, error)

AddSubSection adds a nested section (chapter, etc) to an existing section. The method returns a relative path to the section that can be used from another section (for links).

The parent filename must be a valid filename from another section already added.

The body must be valid XHTML that will go between the <body> tags of the section XHTML file. The content will not be validated.

The title will be used for the table of contents. The section will be shown as a nested entry of the parent section in the table of contents. The title is optional; if no title is provided, the section will not be added to the table of contents.

The internal filename will be used when storing the section file in the EPUB and must be unique among all section files. If the same filename is used more than once, FilenameAlreadyUsedError will be returned. The internal filename is optional; if no filename is provided, one will be generated.

The internal path to an already-added CSS file (as returned by AddCSS) to be used for the section is optional.

Example
e := epub.NewEpub("My title")

// Add a section. The CSS path is optional
section1Body := `    <h1>Section 1</h1>
	<p>This is a paragraph.</p>`
section1Path, err := e.AddSection(section1Body, "Section 1", "firstsection.xhtml", "")
if err != nil {
	log.Fatal(err)
}

// Link to the first section
section2Body := fmt.Sprintf(`    <h1>Section 2</h1>
	<a href="%s">Link to section 1</a>`,
	section1Path)
// The title and filename are also optional
section2Path, err := e.AddSubSection(section1Path, section2Body, "", "", "")
if err != nil {
	log.Fatal(err)
}

fmt.Println(section1Path)
fmt.Println(section2Path)
Output:

firstsection.xhtml
section0001.xhtml

func (*Epub) AddVideo added in v0.11.0

func (e *Epub) AddVideo(source string, videoFilename string) (string, error)

AddVideo adds an video to the EPUB and returns a relative path to the video file that can be used in EPUB sections in the format: ../VideoFolderName/internalFilename

The video source should either be a URL, a path to a local file, or an embedded data URL; in any case, the video file will be retrieved and stored in the EPUB.

The internal filename will be used when storing the video file in the EPUB and must be unique among all video files. If the same filename is used more than once, FilenameAlreadyUsedError will be returned. The internal filename is optional; if no filename is provided, one will be generated.

func (*Epub) Author

func (e *Epub) Author() string

Author returns the author of the EPUB.

func (*Epub) Description added in v0.5.1

func (e *Epub) Description() string

Description returns the description of the EPUB.

func (*Epub) Identifier added in v0.2.0

func (e *Epub) Identifier() string

Identifier returns the unique identifier of the EPUB.

func (*Epub) Lang

func (e *Epub) Lang() string

Lang returns the language of the EPUB.

func (*Epub) Ppd added in v0.2.1

func (e *Epub) Ppd() string

Ppd returns the page progression direction of the EPUB.

func (*Epub) SetAuthor

func (e *Epub) SetAuthor(author string)

SetAuthor sets the author of the EPUB.

func (*Epub) SetCover

func (e *Epub) SetCover(internalImagePath string, internalCSSPath string)

SetCover sets the cover page for the EPUB using the provided image source and optional CSS.

The internal path to an already-added image file (as returned by AddImage) is required.

The internal path to an already-added CSS file (as returned by AddCSS) to be used for the cover is optional. If the CSS path isn't provided, default CSS will be used.

Example
e := epub.NewEpub("My title")

// Set the cover. The CSS file is optional
coverImagePath, _ := e.AddImage("testdata/gophercolor16x16.png", "cover.png")
e.SetCover(coverImagePath, "")

// Update the cover using custom CSS
coverCSSPath, _ := e.AddCSS("testdata/cover.css", "")
e.SetCover(coverImagePath, coverCSSPath)
Output:

func (*Epub) SetDescription added in v0.5.1

func (e *Epub) SetDescription(desc string)

SetDescription sets the description of the EPUB.

func (*Epub) SetIdentifier added in v0.2.0

func (e *Epub) SetIdentifier(identifier string)

SetIdentifier sets the unique identifier of the EPUB, such as a UUID, DOI, ISBN or ISSN. If no identifier is set, a UUID will be automatically generated.

Example
e := epub.NewEpub("My title")

// Set the identifier to a UUID
e.SetIdentifier("urn:uuid:a1b0d67e-2e81-4df5-9e67-a64cbe366809")

// Set the identifier to an ISBN
e.SetIdentifier("urn:isbn:9780101010101")
Output:

func (*Epub) SetLang

func (e *Epub) SetLang(lang string)

SetLang sets the language of the EPUB.

func (*Epub) SetPpd added in v0.2.1

func (e *Epub) SetPpd(direction string)

SetPpd sets the page progression direction of the EPUB.

func (*Epub) SetTitle

func (e *Epub) SetTitle(title string)

SetTitle sets the title of the EPUB.

func (*Epub) Title

func (e *Epub) Title() string

Title returns the title of the EPUB.

func (*Epub) Write

func (e *Epub) Write(destFilePath string) error

Write writes the EPUB file. The destination path must be the full path to the resulting file, including filename and extension. The result is always writen to the local filesystem even if the underlying storage is in memory.

func (*Epub) WriteTo added in v0.10.0

func (e *Epub) WriteTo(dst io.Writer) (int64, error)

WriteTo the dest io.Writer. The return value is the number of bytes written. Any error encountered during the write is also returned.

type FSType added in v0.10.0

type FSType int
const (
	// This defines the local filesystem
	OsFS FSType = iota
	// This defines the memory filesystem
	MemoryFS
)

type FileRetrievalError added in v0.4.0

type FileRetrievalError struct {
	Source string // The source of the file whose retrieval failed
	Err    error  // The underlying error that was thrown
}

FileRetrievalError is thrown by AddCSS, AddFont, AddImage, or Write if there was a problem retrieving the source file that was provided.

func (*FileRetrievalError) Error added in v0.4.0

func (e *FileRetrievalError) Error() string

type FilenameAlreadyUsedError added in v0.4.0

type FilenameAlreadyUsedError struct {
	Filename string // Filename that caused the error
}

FilenameAlreadyUsedError is thrown by AddCSS, AddFont, AddImage, or AddSection if the same filename is used more than once.

func (*FilenameAlreadyUsedError) Error added in v0.4.0

func (e *FilenameAlreadyUsedError) Error() string

type ParentDoesNotExistError added in v1.0.0

type ParentDoesNotExistError struct {
	Filename string // Filename that caused the error
}

ParentDoesNotExistError is thrown by AddSubSection if the parent with the previously defined internal filename does not exist.

func (*ParentDoesNotExistError) Error added in v1.0.0

func (e *ParentDoesNotExistError) Error() string

type UnableToCreateEpubError added in v0.4.0

type UnableToCreateEpubError struct {
	Path string // The path that was given to Write to create the EPUB
	Err  error  // The underlying error that was thrown
}

UnableToCreateEpubError is thrown by Write if it cannot create the destination EPUB file

func (*UnableToCreateEpubError) Error added in v0.4.0

func (e *UnableToCreateEpubError) Error() string

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL