A Recipe for Accessibility: Turning your TTRPG into an eBook

Martin Nerurkar
14 min readMay 24, 2022

--

A simple method of turning your game text into an EPUB eBook!

Hey there!

I’m Martin, and I make video games and tabletop role-playing games under my label Sharkbomb Studios. Most of my tabletop RPG releases to date have been as PDFs but it turns out that’s not the best format, when it comes to accessibility. All those nice and fancy layouts don’t really parse that well, when it comes to e-readers.

So we need something else. Granted, a straight up .txt file might do the trick but that’s a very minimal approach. What to do, if you want a portable, screen-reader-friendly format but still retain some of your game’s identity?

Well, EPUB can help!

Showing the cover of The Mending Circle (used as an example in this text) and a screenshot from its EPUB

EPUB is an open format for eBooks and is supported by a large percentage of eBook readers. However, like everything it comes with its own little quirks. When I established the workflow introduced in this article, my goal was to find a process that had as few manual steps between the input text and the output EPUB.

I loathe the idea of redundancy and trying to keep two documents up to date when things change seemed madness. So my idea was that the process should be easy and low-friction, to make it easier to keep the EPUB up-to-date. Also since Markdown has become a big part of my overall workflow, I wanted the source file to be in Markdown.

Luckily I’ve found a method that fulfills all these criteria. If that sounds interesting, then read on!

What you need:

  • A cursory grasp of the Markdown format
  • An understanding of of HTML and CSS
  • A text editor (I use Typora because it has nice Markdown support)
  • An installation of Pandoc

Overview

The process breaks down as follows:

  • Create a Markdown version of your E text
  • Collect any images and fonts you want to embed
  • Create a CSS file of your desired styling
  • Create a metadata file with extra info about your book
  • Convert all these into an EPUB

After all this is done, updating is easy. When your content changes in the Markdown file, all you need to do is trigger another conversion and you have an updated EPUB.

The Conversion

Essentially what happens during the conversion process is that the Markdown (together with the meta data and CSS) is converted into an EPUB file. An EPUB is essentially a container that bundles the text (in HTML format, one file for each chapter) and the other assets (CSS, images, fonts…) together into a single file.

Other Methods

Other methods I played around with but discounted were the EPUB export directly from Typora (my Markdown editor of choice) or converting the source Markdown to HTML and then to convert that HTML to EPUB via calibre (an excellent ebook manager).

Preparing your Markdown Text

Markdown is a very simple way to create rich, formatted text. More information can be be found on markdownguide.org or other sites.

In general this is pretty simple to do, if you’re simply organizing text. Keeping your header levels well organized and peppering some lists here and there is easy. Complex tables are tricky and something I haven’t really played around with so be careful with those.

Beyond formatted text there are a number of other things you might want to do, to spice up your book. Here’s some of what I used:

Adding Images

You can add images the way you normally do in Markdown (![Alt text](img/url "title")) and the process includes them. However I found that using straight up HTML code in my Markdown file works even better because it allows you to define a width for your image.

Here’s an example:

<img src="images/cotw-aura-nurturing.png" width=300 alt="A man with a flowing beard and a flower crown in his long hair."/>

The image paths used here are relative to the .BAT file and will be included in the EPUB during the conversion process. Try to keep your file sizes small to not create a massive EPUB file.

Defining Sections

You can add custom CSS classes to a header. This means that the header and everything contained within it is wrapped into that header. To do so simply append {.class} to the header line. For example I used this to define some sections as sidebars to then display those differently.

Here’s an example.

### From Torn to Friend {.sidebar}

If you plan to play your witch again and you have become friends with the former Torn, then you might want to write a few notes about them onto the back of your playsheet. This way they could appear in a future story and help out another Torn. Paying it forward, as it were. Once during each future healing story you can call on them to help you out with your quest. If this supports a Challenge Roll, you may add another dice to this roll.

Since a header and everything that belongs to it is wrapped in a pair of <section> tags and since these tags are given the class supplied here, these can be used to style specific parts of your text differently. Check out this text's part on CSS for more details about sidebar formatting that's compatible with different devices.

For sections that have no header you can directly put html tags (probably with <p class="indent">text</p> or something) into your markdown or use formatting like Blockquote to format parts of the text in a certain way.

Relative Links

If you want to create links within your document that lead to section then you can use the following formatting: [link](#relevant-header)

Relevant header would be the name of that specific section. However since the section names can’t have spaces they are changed to all lowercase and delimited by dashes if multi-word (The Wound Sigil turns into the-wound-sigil). These links remain intact, even if the link and the target end up in different chapter files.

If your link points towards something different than the link’s text itself suggests you may want to add a title to the link to make it more informative when it’s highlighted for non-visual readers. Here’s how: [Link](#target-anchor "link title text")

Adding your Assets

If you want your EPUB to contain more than just formatted text, you may want to add images or custom fonts to the whole thing.

Images

All the images you want to include should be close to where your source text file is. A subfolder named “images/" is probably a good place for them. I have included both .JPG and .PNG files with transparency in my books with no difficulties and it seems that .GIF and .SVG should also be doable.

A side note on your book’s cover: It is not added as an image in the markdown text but rather imported via the metadata file. Also my research told me that 2,048 × 1,536 pixels is good cover size because it displays well, even on the relatively high-resolution screen of an iPad witout being too large and cumbersome.

Fonts

As with the images, your fonts sould be close to where your source text file is. Again I suggest a subfolder called “fonts/". As for formats: I used both OTF and TTF format without any issues. Even both within one EPUB.

You will have to do some CSS work to enable your fonts and you need to specify your font folder in the conversion process but both of these things will be detailed below.

Also note that many eReaders do not support custom fonts. Still I choose to include those because font-choices can add a lot to a game’s visual identity.

Styling the CSS

So this part is the trickiest section of it all and it involved a lot of trial and error. The key issue being that the various eReaders all have both different capabilities (color vs black and white, for example) and different ways to interpret the CSS.

I’ve listed my solutions for my use cases below. They have been tested with some simulators and the devices that I could get my hands on but the wide variety of devices out there makes it impossible to guarantee that they work as expected in all cases.

If you encounter any issues, or better yet, find some improved solutions, do let me know!

Media Queries

With so many different devices you may want to control the styling based on some properties or aspects of the device used to read the EPUB. CSS allows you to do this with what’s called a Media Query. This can be used to display things differently based on the size of the reader’s resolution, its aspect ratio or colors. There’s a number of helpful tutorial on this online:

I primarily used this for two things: First to check if the target device could display rich colors or not. If it couldn’t then I went with a simple black and white display. Second to use the width of the device to change the size of some margins.

Here’s an example for the first case: Using device colors. In a section with the class .red all regular text paragraphs will be black in no-color devices, a bright red in simple color devices and a more muted, red on devices with a lot of color fidelity.

section.red p {
color: black;
}
@media (color) {
section.red p {
color: red;
}
}
@media (min-color: 8) {
section.red p {
color: #c8172c;
}
}

And here’s an example for the second case: using device width. Here, blockquote text is displayed with a small margin (0.5em) on narrow devices. Devices with a width of at least 800px have an increased margin (1em) and devices with a width of at least 1024px have an even wider margin (2em).

blockquote {
margin-left: 0.5em;
}
@media (device-width: 800px) {
blockquote {
margin-left: 1em;
}
}
@media (device-width: 1024px) {
blockquote {
margin-left: 2em;
}
}

Sidebars

Fiddling with sidebars was a little tricky. Since the EPUB is a single flow of text actual sidebars are too finnicky to make work. Instead, what I opted for was to insert the sidebar as part of the normal text flow but with specific formatting. At least on higher-quality displays. For non-color devices, it doesn’t really change anything in the formatting since I could get nothing to look right otherwise.

Read on for some display options with example CSS code.

This first variant creates a simple, light orange, rounded border around the sidebar to clearly delineate the text:

section.sidebar {
page-break-inside: avoid;
break-inside: avoid;
}
@media (min-color: 8) {
section.sidebar {
padding: 1em 1.5rem;
margin: 0.5em 1rem;
border-radius: 1em;
border: 2px solid rgb(247,170,165);
}
}
a light orange border around a stretch of text

Alternatively you can use a background behind the sidebar text to provide a larger splash of color. This is risky however, since some eBook reader software (such as Apple’s iBooks) allows users to enable dark mode and other color versions. So you need to make sure your colors look good, even if the text is suddenly white on black. A way to achieve this is to make your background color transparent, so it displays nice on black and on white backgrounds.

Here’s the CSS code:

section.sidebar {
page-break-inside: avoid;
break-inside: avoid;
}
@media (min-color: 8) {
section.sidebar {
padding: 1em 1rem;
margin: 1em 1rem;
border-radius: 1em;
background-color: rgba(247,170,165,0.5);
}
}

This is what it looks like in a fancy e-reader both on white and on black.

A transparent background around a stretch of text, half on white and half on black

And finally, another option would be to use a bar on the left of the text to delineate it from the body text. Here’s the CSS:

section.sidebar {
page-break-inside: avoid;
break-inside: avoid;
}
@media (min-color: 8) {
section.sidebar {
padding: 0em 1rem;
margin: 1em 1rem;
border-width: 0px 0px 0px 4px;
border-style: solid;
border-color: rgb(247,170,165);
}
}

And this is what it looks like:

A light orange line along the left side of a stretch of text

Obvious there’s a lot of options beyond that and you should feel free to experiment. The important part is that whatever you do, you try to honor the user’s choices on their end. If they invert their colors, then you should make sure things remain readable.

Controlling Wrapping

What you can also do with CSS is to control when and where the text breaks. Either into a different column or a different page. For example, generally you don’t want text to break after your headers, so maybe you want to do something like this, using page-break-after and break-after:

h1, h2, h3, h4, h5, h6 { 
page-break-after: avoid;
break-after: avoid;
}

Also, if you are using sidebars or other condensed blocks of text, you might want to keep these together, if possible. For that you can use page-break-inside and break-inside.

section.sidebar {
page-break-inside: avoid;
break-inside: avoid;
}

However, as usual: Not all devices conform to this. My old kindle didn’t care, really. It’s still worth it setting up some of these, for the devices that do.

Fonts

To make your fonts be usable within your CSS you need to define the font faces first. This is an example definition for a set of fonts in various styles and weights. Note that the location is relative to the CSS file, which is in a “/styles/" subfolder within the EPUB, while the fonts are kept in their own "/fonts/" folder.

@font-face {
font-family: GentiumBookBasic;
font-style: normal;
font-weight: normal;
src:url("../fonts/GentiumBookBasic-Regular.ttf");
}
@font-face {
font-family: GentiumBookBasic;
font-style: normal;
font-weight: bold;
src:url("../fonts/GentiumBookBasic-Bold.ttf");
}
@font-face {
font-family: GentiumBookBasic;
font-style: italic;
font-weight: normal;
src:url("../fonts/GentiumBookBasic-Italic.ttf");
}
@font-face {
font-family: GentiumBookBasic;
font-style: italic;
font-weight: bold;
src:url("../fonts/GentiumBookBasic-BoldItalic.ttf");
}

Note that some devices (such as older kindle models) will not use your fonts but instead use system fonts only.

Title Page

The conversion generates a title page (with the class .titlepage) based on the metadata (see below). This page has a <h1> level header of your book's title and then a series of <p> and <div> tags with some of the different pieces of information. To format these nicely, you may want to do something like this:

.titlepage > h1, .titlepage > p, .titlepage > div {
text-align: center;
}

Note that each of the p and div also has their own class like title, subtitle, author, publisher or rights. In case you want to format them individually, that is possible. If you're adding more or different metadata check the section on Debugging to figure out which classes are applied.

More Stuff

The CSS part of the whole process is probably the most finicky bit. All in all it is recommended to define as little as possible to make the different devices (and their user settings) override as much as they want.

For example relative sizes are better than absolute ones in most cases. Colors are also very tricky, especially for text. If you do want to work with that make sure to pick shades that work even in dark mode. The same is true for backgrounds, here using transparency can help make things work in many circumstances.

You can also find a number of other eBook CSS tricks in this article.

Defining the Metadata

Pandoc will make use of this metadata file to define some higher level information about the final EPUB. There are different ways to format this but I have found success with the following structure:

---
title: The Mending Circle
subtitle: A game of Hope and Healing
author: Martin Nerurkar
publisher: Sharkbomb Studios
lang: en-US
rights: © 2021 Martin Nerurkar
cover-image: cover.jpg
---

The individual items in this list should be self-evident. The only point of note may be that the path to the cover image is relative to the .bat file. If you’re interested in providing more metadata to your eBook or you want to learn more, you can find a detailed explanation in the pandoc documentation on the EPUB metadata file.

Converting with Pandoc

Pandoc may seem a bit daunting at first, because it’s a command-line program but that was part of what I liked about it as it meant I could convert with a few clicks and without launching another program and selecting lots of options.

All you need to do (on Windows) is create a batch file (.bat). This is basically a text file with a particular content that is renamed to have a .bat ending. When you double click this file the instructions within the file are executed. If that sounds daunting, don’t worry, I’ll lead you through it.

Here’s the contents of my convert.bat file:

C:\pandoc.exe -o book.epub -f markdown source.md --metadata-file=metadata.txt --epub-embed-font=fonts/* --css styles.css --toc-depth=2

If you want to get more details on the conversion itself, here’s the pandoc documentation on EPUB creation. But now let’s look at the different parts of that batch file:

C:\pandoc.exe

This is the path to the pandoc.exe on my machine. Make sure it points to the .exe as installed on your computer.

-o book.epub

This defines the output file (-o for output)name and format. Since no path is given it will be created in the folder that the .bat file is in.

-f markdown source.md

This lets pandoc know what file and format we use as our source. In this case it’s markdown and our source file is called source.md.

— metadata-file=metadata.txt

This points toward the metadata file. It uses a path relative to the .bat file so in this case metadata.txt is in the same folder as our .bat file.

— epub-embed-font=fonts/*

This tells the EPUB to embed all fonts (via the * wildcard) in the font folder for use in the EPUB. Again the path is relative to the .bat file.

— css styles.css

This points to the CSS file used in the EPUB. As you can probably guess, it’s relative to the .bat file’s location.

— toc-depth=2

This entry tells the converter what kind of header level it should include in the table of contents. In this case H1 and H2 headers are included, H3 and higher are not.

There’s a number of other interesting options such as --epub-chapter-level or --epub-subdirectory. You can find out more in the pandoc documentation on options.

Aftercare

Here’s some things you may want to look into after you’ve created your first EPUB:

Debugging

If something isn’t right or you want to try out some things quickly, you can use the Calibre eBook Editor or the Sigil eBook editor to open your EPUB and view the source CSS and HTML files. This can help you understand how things are put together. It even lets you edit things on the fly to see what the result would look like.

You may also want to run EPUBCheck to see if your output EPUB works fine. I’ve had no issues so far but this never hurts.

Previewing

Since the device your EPUB is read on can have a sizable effect on the end result you might want to test it on as many devices as you can. One would hope there was some piece of software that lets you simulate all different readers to check things with a click without switching devices, but unfortunately that’s not really the case.

There is the Kindle Previewer software from amazon, that does simulate some of their family of devices but it doesn’t seem to work all that well. And then there’s Abby Goldsmith’s solution of using the eReader apps of the bigger companies to simulate their device’s behavior. Here’s a quick writeup of her simple method.

Acknowledgements

Figuring out this workflow was a little like hacking my way through a jungle. Thankfully there were a few helpful guiding lights that made things a lot easier. Here’s the big heroes that helped me get a handle on things:

And that’s it! Thanks for reading and hope this was helpful!

Martin

--

--