The tutorial about using pandoc to createttrpg content in both html and epub.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

16 KiB

Creating ePub and html content for ttrpg designers.

You want to publish an adventure?

So you want to publish an adventure in both html for web and an ePub for readers and mobile?


Read on my friend, because I am about to gift you the knowledge to do both without the need for any (overly) complex and expensive software.


Lets us crack on.

What we will be doing

| Creating the project files. | Creating a micro adventure. | Writing markdown. | Converting it to html for web. | Converting it to ePub for readers and mobile.

The build commands at the end of this file are for Linux, but the commands should be identical for mac OS. For windows the command may be a little different but you should be able to figure it out.

What do I need?

  • A text editor
  • Pandoc
  • Tarot cards
  • Your computers terminal

The text editor is a text editor. You use it to edit text.

Pandoc is a program that can be used to convert from various markup formats to others. You will use it to convert the markdown that you will write into both html and ePub.

You will already have a text editor somewhere, but will need to install pandoc.

The terminal is the text interface your computer has. If you are using Linux you know this already. On OS X it is an application called Terminal and on windows you can use either cmd.exe or Power Shell. These are all pre installed on your computer and you should be able to find them with a quick search.

We will need the terminal to build your project.

Set up our project

Create a directory somewhere in your mess of a file system, this will be where we will put our project. Name it what you like, I do not care.

We will be creating some files in that directory.

  • template.html

    A html file that will act as the template that your html output will be created in.

  • style.css

    A css style file that will be used to make things look nice.


    A markdown file that will contain your adventures text.


This file is the template into which the markdown you write will be inserted when you convert it to html. This file is mostly just filled with things that tell your browser how to display the page that you create.

Create an empty plain text file called template.html, and copy the following html into it.

<!DOCTYPE html>
<html lang="en">

<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css">


You don't, for this to work, need to know what all this means, but I am going to explain it because knowledge is power1. Read it or don't.


CSS (crud something something, or something to that effect) is the thing that adds the topping to the html cake you will be serving. it is the thing that covers up the burned bits and makes it not look like you don't want to eat it.

Much like good icing it is also a tricky art to get right, I assume anyway as I do not really bake.

Create an empty text file called style.css and copy the following text into it.

body {
	font-family: 'Arial', sans-serif;
	line-height: 1.5;
	max-width: 600px;
	margin: auto;
	background-color: white;

header {
	font: lighter calc(.025 * (300vw)) 'Arial', sans-serif;

table {
	width: 100%;

tr:nth-child(even) {
	background-color: lightgray;

img {
	max-width: min(600px, 100%);

Once again, knowledge is power so I am going to explain what you are looking at in the section below, but only briefly as there is a lot. You still don't need to read it for this to work but you know what they say, you cant ice a crap cake without reading the blinking recipe2.

Now it is action time, it is time to start writing an adventure!

Create another text file named You will write your adventure here in markdown.

Pandoc uses its own Extended Markdown Syntax which includes all of the usual markdown with a few nice additions.

I will show you the basics of markdown as your write an adventure in the sections below.

Shuffle your tarot cards (if you don't have a deck to hand you can use this card picker) and lets get going.

The title of your adventure

Draw a card from a deck. Look at the art on the card, its name and its value.

What is a suitable name for the adventure being depicted in the card?

Maybe you drew The Tower and the title "Oh crap, that tower has had it mate, totally wrecked!".

First we need to come up with the title of your adventure.

How do you put this title on the page then?

One of the special features of pandoc is that it allows you to have special named fields that are then inserted into your html. If you remember the title tags from our template.html it contains the text $title$. This is a special flag for pandoc which will replace any occurrence of $title$ with your adventures title.

There's a special block of text (called yaml) that you place at the start of your markdown, it contains metadata like the title and author. Copy and paste the following into the top of your and replace the place holder text with your own.

title: Whatever the title of your adventure ends up being.
creator: You

Your adventures introduction

Draw another card. Use the art, name and value of this card along with the first card you drew as inspiration for what your adventure is about.

Think about what event these cards are depicting, how it relates to the title you got from the first card, and how the players fit into this whole affair.

Your adventure needs an introduction, a couple of paragraphs about what the flip is going on; and that introduction needs a heading before it.

Paragraphs are easy, you just put a whole big ol' empty line between two chunks of text. The heading3 on the other hand is created as such:

# This is a title

Write a catchy headline for your introduction and then write a couple of short paragraphs outlining the situation.

The Hex Map!

Did I not mention that this adventure has a hex map with six noteworthy locations for the players to visit.

For this we will need to include this image on the page:

A hex map showing six locations that you can visit among some blank spaces.\

Save the above image to the folder where you created the files earlier, giving it a sensible name.

Add a section heading for the hex map in your markdown file, the heading can be what you like, and then include the image on the page. Copy the line below into your markdown file leaving a blank line between it and the heading, and change the file name to the one you saved the image as.

![A hex map showing six locations.](./filename.png "")\ 

The above line you just copied is one of the ways that you can insert an image using markdown4.

The locations on the hex map.

Draw six more cards and look at each.

Each of these cards is a location on the hex map. Use the image on the card, its value and its name to inform what the players will find in this location.

Oh yeah, that's right, there are six locations to visit on the map.

Let us format a nice table to put each location in.

There are several ways to do a table with pandoc but here I will show you one.

location   Description
---------  ---------------------------------- 
1          Here is the first location that
           the players encounter.

2          Here is the second location.

3          A third location for them to
           explore. I think you get the
           idea of how this works now.

This is therest of your text.

You should now fill in the table with short descriptions of the six locations that you drew earlier5.

If you need to add a lot of extra detail about the encounter then you can add a new heading under the table for each and fill in more detail there. You remember headings and paragraphs from earlier, right?

Adding some random encounters.

Draw a number of cards for whatever dice it is you wish to roll for them. 6 for a d6,12 for a d12, and so on.

Refer to the cards suit for the type of encounter it will be.

Swords are combat encounters. Wands are magical encounters. Coins have a chance of gaining treasure. Cups are environmental encounters. Major arcana are fantastical beings.

For each card look at what type of encounter that card represents, then look at the cards art and value to determine what the encounter is.

Add a heading for this section and then format your encounters into a table6, just like you did before.

Let us convert this already.

OK, lets create that html and epub output shall we?


Open your terminal and navigate to the directory where you have been creating your files in.

Then run the the following to make pandoc turn your markdown into html.

pandoc --template template.html -o index.html

This command will take your and convert it into html, insert it into place in the template.html, and then output the whole thing to a file called index.html7

You should now be able to open the index.html file in your web browser and see the fruits of your labour.


And now for the epub output.

pandoc -o adventure.epub --css style.css

This will take your and output it as adventure.epub. The --css flag here makes it so that the style.css file you wrote earlier is used as your books css style instead of the rather drab default one.

That is it, the end.

Now you should have a micro adventure in both html and epub format, you created it yourself.

This is, of course a very quick crash course in how to do this. Creating content for the web can be a very big subject, css by itself is several books worth. The upside is that you only need to learn the bits that you need to make something work, so that's more manageable, isn't it?

Anyway, if you want to know more about the metadata options for ebooks that allow you to specify cover images and such the pandoc website has you covered.

If you want a full rundown of the markdown syntax that pandoc supports that is there too.

Finally if you wish to learn a bit more about web dev then w3school is a good place to start out.

You have also now been armed with the tools to be able to grow this adventure into a bigger one, or something else entirely.

About me

Hi, I am James Chip. I make a few ttrpg things and write software. If you enjoyed this you can check out my other stuff on my website.

  1. The first line tells the browser it is loading is an html file, and the next line tells it to expect it to be in the English language.

    Next we open the head section.

    The head section is the meta data part of a html file. It contains data about the data that the browser is going to display. The next few lines display the title in the windows top bar, do some magic that makes the text look good on mobile and loads a style sheet that will make it all look acceptable, before we close the head section again.

    Next we open the body section of the page.

    The body section is where the actual content that you are displaying will be placed.

    First we have a header to display our page title on the screen as part of the content.

    Next we open the main section, this is the part where the bulk of your content should be. Screen readers look for this section to begin reading.

    The next line, which is just simply "$body$", is a special line that is used by pandoc. When we run pandoc it will look for this line in the template file, remove it and then replace it with the html converted from your markdown file. Fancy!

    The last things we do is close the main and body sections. ↩︎

  2. The first section is the body style.

    If you remember from the html we wrote earlier the body holds all of the content you want on the screen. This section sets the font and line spacing, sets the max width of the content to 600 pixels so that it doesn't feel too wide to read and sets the margin so that the content is nicely centred on the screen.

    The header section sets the font big and thin for the title to be displayed.

    The next two sections define how tables will be displayed, which is very important because ttrpg creators love a good table.

    The last section, img, defines how images are displayed. It makes it so that they fit nicely in the content width and resize as needed.

    There is a lot more detail to css and you can do some really cool layout things with it but for this we only need the basics. ↩︎

  3. A section heading starts with a # followed by a space and then the text of the heading. A single # produces the biggest heading but you can also produce sub headings by adding more.

    # Headder
    ## Sub Headder
    ### Sub Sub Headder
    #### Sub Sub Sub Headder

    All the way up to six # in a row. Seven is too many and you will be Wise to avoid trying that many, I will not be held accountable for what happens if you do. ↩︎

  4. The ! at the start tells us that this is an image, not a link. Links and images in markdown use almost the same syntax so this ! at the start lets the parser know that this is an image and not a link.

    The text between the square brackets will be used as the images alt text.

    The text between the regular brackets is the location of the image we wish to show. the "./" before the image name just means that the browser will start its search in the sites root, this is not mandatory but I always like to include it.

    The empty "" after the image will be used as the images title. It is blank here but you can put whatever you like in it.

    Here is the odd bit that you might want to take note of though. There is a single forward slash at the end of the line, this is a non breaking space.

    Why is it here?

    Well, buckle up as this is quite the thing.

    If an image is included in the middle of a paragraph then it is displayed as a regular image on the page.

    If however an image is the only thing present in the paragraph pandoc does not treat it as a regular image, it treats it instead as a figure.

    When pandoc uses a figure it uses the alt text you gave it as the caption and displays it under the image. This is fine, but not what we want here, we just want a regular image not a figure. The way you work around this is by making sure that the image is not the only thing in the paragraph, hence the non breaking space at the end. This way pandoc sees that there is other content in the paragraph and displays a regular image, and there is no text to show on the screen to get in the way.

    Read more about images in pandoc markdown here. ↩︎

  5. The table I have shown you how to make is a simple one that allows for multiple lines in a table cell.

    It must start and end with an unbroken line of dashes that span the whole width of the table.

    The column headings have rows of dashes under them separated by spaces. These can be as long or short as you like but any content in that column must fit fit within that width. For example:

    This content is too wide

    Should be:

    is too wide

    One last note is that you must leave a blank line after your table, before the rest of your text. If you don't leave this line then your table wont be formatted properly. ↩︎

  6. If you don't want to format this as a table you could also format it as a numbered list like this:

    1. First item.
    2. Second item.
    3. Guess what.

    Note, the number has to be followed by a dot. As an aside, If you wish to create a bullet point list just have each line start with an asterisk. ↩︎

  7. When you load a website the first thing a browser looks to load, unless it is told otherwise, is a file called index.html. Index.html is nearly always the first page that you see whenever you load any regular website. I have chosen it here for historical reasons, but you could change it to anything. ↩︎