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
filessection 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
navsection in your book’s YAML file in_data/worksthat points to at least one of your epub’s files. For epubs, every item in thenavmust 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-pageitem, 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 thefileslist (e.g.- "0-3-contents": "toc").
- Define the epub’s
-
Since EPUB3 requires a
navelement, it is mandatory to include{% include toc %}somewhere in your book, even if it’s a file, listed at the end of yourepubfileslist, 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: truein theepubsection ofsettings.yml. -
If you’re using a
toc.ncxfile for backwards compatibility with old ereaders, you have to be especially careful with how you construct your epubtoctree in the book’s_data/worksfile.In an NCX, you cannot have two items in nav pointing to the same target. So in your epub
tocin your book’s YAML file in_data/works, you can’t have two items with the samefileandid. To differentiate them, you add anidpointing 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.ncxthe 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 anidto 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 @importing 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.ncxfile is particularly sensitive. - Make sure your book has a
package.opffile in its book directory. You can copy this from the Electric Book template. (It uses theepub-package.htmlinclude 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.opffile.- an
epubfolder (as a Jekyll collection) containing a boilerplateMETA-INFfolder,mimetypefile, andmathjaxfolder; and optionaljsandfontsfolders.In our output script:
- We copy the relevant book or translation folders from
_site/book(or whatever folderbookhas 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
epubto_output/book.zip(wherebookmay be a renamed book folder), and change the file extension to.epub.