Creating Timelines in Markdown

On day 5 of my 30 days of world-building, I share my hack for creating timelines in pure markdown, HTML and CSS.

Creating Timelines in Markdown

A few years ago, I bought Aeon Timeline to help me plot out a big novel whose plot spanned nearly 18 months. I was particularly attracted to its support for Scrivener projects. However, it never lived up to that promise. I found it overly complicated, buggy and the Scrivener sync was problematic. After persisting for close to a month, I gave up and went back to using spreadsheets.

Spreadsheets, while great for managing data are positively awful as a publishing medium — even Apple's Numbers app, which is about a million times better looking than Excel. I can't see myself displaying a PDF created from a spreadsheet.

Around the same time, I started creating a Markdown-based world-building workflow. I wondered if I could use markdown for creating timelines. The challenge, of course, is that neither markdown nor HTML has a native timeline capability, so I'd have to build one. That in itself isn't too hard, but I wanted the markdown document to be pure markdown — no HTML, no cheating div containers, no javascript.

Markdown

Markdown is a plain-text, lightweight syntax that allows you to write semantically without messing around with formatting. I like it for its simplicity, portability and robustness.

The original Markdown spec, however, is quite sparse and doesn't represent every possible HTML element. For this, you need to use a 'flavour', or dialect of markdown that adds support for more elements. The most popular flavour is GitHub Flavoured markdown, while a close second is MultiMarkdown. I use the latter because it's compatible with Scrivener, but the differences are slight. This solution also works with Python Markdown, albeit with Extras installed.

To create my timeline, I opted to use the little-used HTML definition list element. Definition lists are sufficiently structured that we can co-opt them into duty.

MultiMarkdown supports the creation of definition lists using the syntax as follows.

1066
: September. Harald Hardrada, King of Norway, invades England
: October. William of Normandy defeats and kills Harold II at Hastings.

1070
: William the Conqueror subdues the north of England
: First Norman stone castle is built in Wales.

1076
: 'Revolt of the Earls' ends with the execution of Waltheof, Earl of Northumbria.

1077
: Bayeux Tapestry illustrating the Battle of Hastings is completed.

1085
: Domesday Book is instituted to survey the English lands of William the Conqueror.

1086
: Landholders swear loyalty to William the Conqueror at Salisbury.

1087
: William the Conqueror dies at Rouen, Normandy.

1087
: William II is crowned at Westminster Abbey.

This syntax, I think you'd agree, is both easy to write and easy to read. Here's the resulting HTML, as rendered by MultiMarkdown.

<dl>
<dt>1066</dt>
<dd> September. Harald Hardrada, King of Norway, invades England</dd>

<dd> October. William of Normandy defeats and kills Harold II at Hastings</dd>

<dt>1070</dt>
<dd> William the Conqueror subdues the north of England</dd>

<dd> First Norman stone castle is built in Wales</dd>

<dt>1076</dt>
<dd> &#8216;Revolt of the Earls&#8217; ends with the execution of Waltheof, Earl of Northumbria</dd>

<dt>1077</dt>
<dd> Bayeux Tapestry illustrating the Battle of Hastings is completed</dd>

<dt>1085</dt>
<dd> Domesday Book is instituted to survey the English lands of William the Conqueror</dd>

<dt>1086</dt>
<dd> Landholders swear loyalty to William the Conqueror at Salisbury</dd>

<dt>1087</dt>
<dd> William the Conqueror dies at Rouen, Normandy</dd>

<dt>1087</dt>
<dd> William II is crowned at Westminster Abbey</dd>
</dl>

Definition lists, aren't too different from your typical ordered, or unordered HTML lists, behaving similarly in the browser. The top-level element DL. The DT element represents the title, then one or DD elements for the description. I'm my example, the title (DT) is the year, while I use each description (DD) as an event within the year.

Here's how it looks in plain HTML in a my browser.

Unstyled definition list
Unstyled definition list

Styling through CSS

The magic comes with CSS, the lightweight language used to style HTML documents.

First off, I'll set some basic parameters for the DL container.

dl {
    list-style-type: none;
}

This directive tells the browser not to add bullet points to the definition's child elements.

Next, I'll style what comes before the definition list and its titles (yes, I know that sounds weird) using the dl and dd before pseudo-selector.

dl:before {
    content: ' ';
    background: #d4d9df;
    display: inline-block;
    position: absolute;
    left: 29px;
    width: 2px;
    height: 100%;
    z-index: 400;
}

dl > dt:before {
    content: ' ';
    background: white;
    display: inline-block;
    position: absolute;
    border-radius: 50%;
    border: 3px solid #5e0900; /* was #22c0e8 */
    left: 20px;
    width: 20px;
    height: 20px;
    z-index: 400;
}

This code creates the overall timeline effect I'm going for by creating white circles joined with lines between each DT element.

Finally, I'll tweak the position of the elements to compensate for the timeline, by adding some margin and padding.

dl >dt, dl > dd {
    margin: 6pt 0; /* was 20px */
    padding-left: 60px;
}

How it looks

To give it that ye olde fantasy look, I've also added a parchment texture background, which works quite well with the rusty brown colours I used for the text and circle.

Here's the finished result, shown in Safari. Not too shabby, methinks.

Final timeline, created with markdown, HTML and CSS
Final timeline, created with markdown, HTML and CSS

Concluding thoughts

Okay, so I doubt there are many people in the world looking for this solution. Even so, I think it works quite well. If you find Aeon Timeline too complicated, this is much simpler. If you don't like using proprietary tools and prefer writing in markdown, this is free and open source. If you use a spreadsheet but want to share something more aesthetic with your readers or players, this can do the trick.

Okay, so that's 5 days done, 25 to go.