What I've learned making an .epub Ebook with Quarto (2024)

I’ve been working on an ebook (that you can read overhere) made using Quarto. Since I’m also selling aDRM-free Epub and PDF on Leanpub I wanted toshare some tips and tricks I’ve learned to generate an Epub that passesepubcheck using Quarto.

Quarto is a tool made by Posit and is an open-source scientific and technicalpublishing tool. If you know what LaTeX is, then it should be easy for you togrok Quarto. The idea of Quarto is that you write documents using Markdown, andthen compile these source files into either PDFs, Word documents, but alsobooks, web-sites, ebooks (in the Epub format) and so on… It’s quite powerful,and you can also use programming language code chunks for literate programming.Quarto support R, Python, Julia and ObsevableJS chunks.

So, as I said, I’ve been using Quarto to write an ebook, and from a single setof Markdown source files I can generate the website (linked above), the PDF ofthe book and the Epub of the book. But you see, if you want to sell an Epub onplatforms like Leanpub, the generated Epub must pass epubcheck. epubcheck isa command line application that verifies that your Epub satisfies certainquality checks. If these quality standards are not satisfied, there is noguarantee that Epub readers can successfully open your Epub. Leanpub actuallyallows you to upload an Epub that does not pass epubcheck, but they warn youthat you really should strive for publishing an Epub without any errors orwarnings raised by epubcheck. For example, the first version of my Epub did notpass epubcheck and I couldn’t upload it to my Kindle.

In this blog post I’ll show you what you should do to generate an Epub thatpasses epubcheck using Quarto.

Starting from the default template

Start by installing Quarto by downloading the right package for your operatingsystem here. To start from a book templateopen a terminal and run:

quarto create-project example_book --type book

Let’s open the _quarto.yml file that is inside the newly createdexample_book/. This is your book’s configuration file. It should look likethis:

project: type: bookbook: title: "example_book" author: "Jane Doe" date: "3/3/2023" chapters: - index.qmd - intro.qmd - summary.qmd - references.qmdbibliography: references.bibformat: html: theme: cosmo pdf: documentclass: scrreprt

You can change whatever you like, but for our purposes, we are going to add theepub output format all the way at the bottom of the file. So change theselines:

format: html: theme: cosmo pdf: documentclass: scrreprt

into these lines:

format: html: theme: cosmo epub: toc: true

I’ve added the epub format as an output, as well as the toc: true option,which builds a table of contents. I’ve also removed the pdf output because youneed to have a LaTeX distribution installed for this, and the point of this blogpost is not to talk about the PDF output (which works flawlessly by the way).Before compiling, let’s open one of the .qmd files. These files are theMarkdown source files that we need to edit in order to fill our book withcontent. Let’s open intro.qmd and change these lines from:

# IntroductionThis is a book created from markdown and executable code.See @knuth84 for additional discussion of literate programming.

to:

# IntroductionThis is a book created from markdown and executable code.See @knuth84 for additional discussion of literate programming.![By Boaworm - Own work, CC BY 3.0, https://commons.wikimedia.org/w/index.php?curid=10649477](images/640px-Eyjafjallajokull_Gigjokull_in_ash.jpg)

Download the image from thislinkand create the images/ folder at the root of the book, right next to the.qmd files.

This syntax is the default syntax for adding pictures in a Markdown document. Ifyou’re an R user, you could also use an R code chunk and the functionknitr::include_graphics() to achieve the same thing.

Let’s compile our little example book, and then use epubcheck to see what’swrong! Use these commands to render the book in all the formats:

cd example_book/quarto render

You should see a folder called _book appear on the root of your project.Inside this folder, you will see a bunch of .html files: these constitute theweb-site of your book. You can right click on index.html and open it with aweb browser and see how your book, as a web-site, looks like. You could hostthis book on Github pages for free!

But what interests us is the .epub file. If your PDF reader supports thisformat, you can open it and see how it looks. On Windows you could useSumatraPDF. I use Okular on Linux to open PDF and Epub documents. Anyways, theredoesn’t seem to be anything wrong with it. You can open it, you can read it, itseems to be working just fine. But let’s see if epubcheck thinks the same. Youcan download epubcheck from here.Save the downloaded file on the root directory of the book and decompress it.Inside the decompressed folder, you’ll see a file called epubcheck.jar. Putyour epub file right next to it, in the same folder. Now, open a terminal andnavigate to the right folder and run the following command to check the epubfile:

cd epubcheck-5.0.0 # or whatever version it is you downloadedjava -jar epubcheck.jar example_book.epub

You should see this output:

Validating using EPUB version 3.3 rules.ERROR(RSC-005): example_book.epub/EPUB/content.opf(6,39): Error while parsing file: character content of element "dc:date" invalid; must be a string with length at least 1 (actual length was 0)WARNING(OPF-053): example_book.epub/EPUB/content.opf(6,39): Date value "" does not follow recommended syntax as per http://www.w3.org/TR/NOTE-datetime:zero-length string.ERROR(RSC-005): example_book.epub/EPUB/text/ch002.xhtml(354,16): Error while parsing file: element "figcaption" not allowed here; expected the element end-tag, text, element "a", "abbr", "area", "audio", "b", "bdi", "bdo", "br", "button", "canvas", "cite", "code", "data", "datalist", "del", "dfn", "em", "embed", "epub:switch", "i", "iframe", "img", "input", "ins", "kbd", "label", "link", "map", "mark", "meta", "meter", "ns1:math", "ns2:svg", "object", "output", "picture", "progress", "q", "ruby", "s", "samp", "script", "select", "small", "span", "strong", "sub", "sup", "template", "textarea", "time", "u", "var", "video" or "wbr" (with xmlns:ns1="http://www.w3.org/1998/Math/MathML" xmlns:ns2="http://www.w3.org/2000/svg") or an element from another namespaceCheck finished with errorsMessages: 0 fatals / 2 errors / 1 warning / 0 infosEPUBCheck completed

So we get 2 errors and 1 warning! Let’s look at the first error:

ERROR(RSC-005): example_book.epub/EPUB/content.opf(6,39): Error while parsing file: character content of element "dc:date" invalid; must be a string with length at least 1 (actual length was 0)

The first error message states that our epub does not have a valid dc:dateattribute. The warning is also related to this. We can correct this by addingthis attribute in the _quarto.yml file:

format: epub: toc: true date: "2023-03-01"

However this is not enough. There is a bug in the current release of Quarto thatprevents this from working, even though we did what we should. However, this bugis already corrected in the development version of the nextrelease.But until the next version of Quarto, 1.3, gets released, here is theworkaround; you need to also specify the language of the book:

format: html: theme: cosmo epub: toc: true lang: en-GB date: "2023-03-01"

And now epubcheck does not complain about the date anymore!

The next error:

ERROR(RSC-005): example_book.epub/EPUB/text/ch002.xhtml(354,16): Error while parsing file: element "figcaption" not allowed here; expected the element end-tag, text, element "a", "abbr", "area", "audio", "b", "bdi", "bdo", "br", "button", "canvas", "cite", "code", "data", "datalist", "del", "dfn", "em", "embed", "epub:switch", "i", "iframe", "img", "input", "ins", "kbd", "label", "link", "map", "mark", "meta", "meter", "ns1:math", "ns2:svg", "object", "output", "picture", "progress", "q", "ruby", "s", "samp", "script", "select", "small", "span", "strong", "sub", "sup", "template", "textarea", "time", "u", "var", "video" or "wbr" (with xmlns:ns1="http://www.w3.org/1998/Math/MathML" xmlns:ns2="http://www.w3.org/2000/svg") or an element from another namespace

is related to the image. It turns out that including the image like we didgenerates code that is not quite correct from the point of view of thestandard that Epubs should follow. You should know that Epubs are actually acollection of HTML files, so you can include images by using HTML code in thesource Markdown files.

If you insert the image like so, the error should disappear:

<figure> <img src="images/640px-Eyjafjallajokull_Gigjokull_in_ash.jpg" alt="By Boaworm - Own work, CC BY 3.0, https://commons.wikimedia.org/w/index.php?curid=10649477"></img> <figcaption>By Boaworm - Own work, CC BY 3.0, https://commons.wikimedia.org/w/index.php?curid=10649477</figcaption></figure>

If you re-render the Epub, and try epubcheck again, you should see this:

java -jar epubcheck.jar example_book.epubValidating using EPUB version 3.3 rules.No errors or warnings detected.Messages: 0 fatals / 0 errors / 0 warnings / 0 infos

Using Github Actions to build the book

Finally, as a bonus, if you’re using Github, you can also use Github Actions togenerate the web-site, as well as the Epub (and the PDF if you want). If you goto this repository,which contains the example book from this post, you can find the workflow toautomatically build the Epub and web-site from your Quarto source in the.github/workflows/ folder. Create the same folder structure in your repositoryand copy the .yml file that is in it to these folders. You should then createa gh-pages branch and make sure that Github Actions has the requiredpermissions to push. For this, go to the Settings menu of your repository,then Actions (listed in the menu on the left), then General, and then underWorkflow permissions make sure that Read and write permissions is checked.

What I've learned making an .epub Ebook with Quarto (1)

Now, each time you push, you should see your Epub get built in the gh-pagesbranch! If you use R code chunks, you also need to set up an action to set up R.Take a look at therepoof my book for an example.

Hope you enjoyed! If you found this blog post useful, you might want to followme on Mastodon or twitter for blog post updates andbuy me an espresso or paypal.me, or buy my ebooks.You can also watch my videos on youtube.So much content for you to consoom!

What I've learned making an .epub Ebook with Quarto (2)Buy me an Espresso

What I've learned making an .epub Ebook with Quarto (2024)
Top Articles
Latest Posts
Article information

Author: Maia Crooks Jr

Last Updated:

Views: 6308

Rating: 4.2 / 5 (43 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Maia Crooks Jr

Birthday: 1997-09-21

Address: 93119 Joseph Street, Peggyfurt, NC 11582

Phone: +2983088926881

Job: Principal Design Liaison

Hobby: Web surfing, Skiing, role-playing games, Sketching, Polo, Sewing, Genealogy

Introduction: My name is Maia Crooks Jr, I am a homely, joyous, shiny, successful, hilarious, thoughtful, joyous person who loves writing and wants to share my knowledge and understanding with you.