Epub output
- Package files
- Metadata and settings
- Fonts
- Javascript
- SVG images
- Troubleshooting
- How epubs are generated
You can create an epub by running the output script with the epub option, and your book folder for the book
option, e.g.:
npm run electric-book -- output --format epub --book great-expectations
Before that will work, though, your project must be prepared correctly.
Package files
The template comes with package.opf
and toc.ncx
files in the book
and samples
folders. For epub output, every book you create should have at least the package.opf
file in its directory. The toc.ncx
is for backwards compatibility with older epub readers, and so some vendors require it.
If you’re creating translations, you also need these files in the translation directory (e.g. at great-expectations/fr/package.opf
). There is an example in the template’s samples
book directory.
Metadata and settings
Your epub will build correctly only if you have provided sufficient, accurate information about it in its YAML file in _data/works/
. You may also need to adjust some epub settings in _data/settings.yml
.
- File list: you must list all the files to be included in your epub in the epub
files
section of your book’s YAML file in_data/works
. - Optionally, add guide names to key files in that list, e.g.
"0-0-cover": "cover"
. - There must be a
nav
section in your book’s YAML file in_data/works
that points to at least one of your epub’s files. For epubs, every item in thenav
must include a file (unlike web output, where label-only items are allowed). - To tell the epub package where to find navigation, you must either:
- Define the epub’s
contents-page
item, as the content file that contains{% include toc %}
, e.g.- contents-page: "0-3-contents"
, and/or - Add the guide name
"toc"
to the relevant file in thefiles
list (e.g.- "0-3-contents": "toc"
).
- Define the epub’s
-
Since EPUB3 requires a
nav
element, it is mandatory to include{% include toc %}
somewhere in your book, even if it’s a file, listed at the end of yourepub
files
list, that contains only:--- --- {% include toc %}
- If your epub must not include a visible table of contents in its pages (e.g. for a novel with no chapter headings), you can hide it visually by setting
hide-nav: true
in theepub
section ofsettings.yml
. -
If you’re using a
toc.ncx
file for backwards compatibility with old ereaders, you have to be especially careful with how you construct your epubtoc
tree in the book’s_data/works
file.In an NCX, you cannot have two items in nav pointing to the same target. So in your epub
toc
in your book’s YAML file in_data/works
, you can’t have two items with the samefile
andid
. To differentiate them, you add anid
pointing to, say, a heading in the document to differentiate one target in the same file from another.Also, in an NCX, every item must include a link. So if an item in your toc has no link, and only children items, then in the
toc.ncx
the Electric Book will create a link for it. It will use thefile
(without theid
) of its first child. So, to ensure that you don’t get duplicate links, you must add anid
to that first child. This way, the parent will point to thefile
, and the first child item will point to thefile
+id
.
Fonts
To embed font files in an epub (for @import
ing in your epub’s CSS), add the font files to _epub/assets/fonts
.
Font files stored anywhere else in your project (e.g. in the main assets/fonts
folder) are not included in epub outputs. This ensures that the epub includes only those font files that are specifically required for your epub.
Currently, the template does not support using different fonts for different epubs. If you are embedding fonts in your epubs, you must use the same ones for all your books.
Javascript
See the Javascript section for more detail.
SVG images
If you include SVG images inline in an epub file – that is, the <svg>
markup itself is in the final HTML, not just linked in an <img src="*.svg">
element, you need to indicate that the file includes an inline SVG. This is because for an epub to be valid, the package.opf
file must flag when a file includes inline SVGs.
In order to do this, you must add this to the file’s top-of-page YAML:
contains-svg: true
If you have many files that contain SVGs, you can set this value as a frontmatter default in _config.yml
. E.g. if all your projects’ title pages include inline SVG, you might include this in _config.yml
:
defaults:
-
scope:
path: "*/01-title-page.html"
values:
contains-svg: true
Troubleshooting
Epubs are notoriously hard to make, largely because validation is so strict. Here are some tips that may be useful when troubleshooting.
-
If you get errors from EpubCheck, the error will usually report the file name, line and column number of the content with the error. For instance,
(1,4587)
means that the error is on line 1, column (or character) 4587.Open the relevant file with the error in an editor that shows you the line and column/character position of your cursor. Then move your cursor to the relevant line and column number. When the error applies to a specific element, the column position is usually at the end of the offending element.
- If you’ve used named HTML entities like
in HTML snippets, kramdown may not have processed those as markdown, and therefore will not have converted them to unicode characters. Named entities are not valid in epub 3, and you’ll need to replace them with their numeric equivalents, such as 
instead of
. - If you get errors about your navigation or TOC (
nav
), see the guidelines on Metadata and settings above. Thetoc.ncx
file is particularly sensitive. - Make sure your book has a
package.opf
file in its book directory. You can copy this from the Electric Book template. (It uses theepub-package.html
include to generate the epub’s metadata and manifest.)
How epubs are generated
This is technical background on how we generate Electric Book epubs. It’s a two-step process.
In Jekyll, using an epub config file (
_configs/_config.epub.yml
), we generate:
- the books, with each translation in a subfolder. Each book and translation has a
package.opf
file.- an
epub
folder (as a Jekyll collection) containing a boilerplateMETA-INF
folder,mimetype
file, andmathjax
folder; and optionaljs
andfonts
folders.In our output script:
- We copy the relevant book or translation folders from
_site/book
(or whatever folderbook
has been renamed to) into_site/epub
. We retain the subdirectory structure of translations, except for thepackage.opf
, which goes to the root ofepub
.- We zip the contents of
epub
to_output/book.zip
(wherebook
may be a renamed book folder), and change the file extension to.epub
.