A Table of Contents Generator for Ulysses and MarkdownXL

I do all my writing in Ulysses. I also like to keep all of my files in its library. Since I started using it, the idea of having individual files scattered about my computer is just plain barbaric. The cost of this trade off is that if Ulysses doesn’t support a feature, I have to add raw HTML into the files. Normally this isn’t much of a problem. A bit HTML set off with ~~ isn’t distracting.

Markdown is great for writing text, but as a human-readable HTML front end its features are limited. It’s also the best generic text format that I’ve found. The one overwhelming advantage of markdown is that it’s easy to remember. It’s also the native language of Ulysses.1

Between markdown, HTML, and Ulysses, there’s no native way to create a a table of contents. There’s not even a recognized standard. Maybe in the future Ulysses2 might add this. But for now it’s something that has to be added manually. So with little a bit of scripting I came up with a workable solution.

TOC generator

This is a simple script that takes markdown and returns it with a table contents added. It also adds in the needed anchor links so the navigation actually works.

Usage is simple. Just pipe in the markdown text and point the output to a new file.

cat myfile.md | toc-md.rb > newfile.md

Or you can do it all on the Mac’s clipboard and not use an intermediate file. This is a neat one-liner. (Make sure to copy as markdown.)

pbpaste | toc-md.rb | pbcopy

Then in Ulysses, select all of the text on the sheet. Then paste in the text generated by the script. Make sure to use paste from -> markdown.3

The Script

This script will indent the TOC items using tabs instead of spaces. This is for Ulysses compatibility. Change the "\t" to " " for regular markdown.

Sample input:

# Main Title

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque
quis laoreet libero. Phasellus quis justo sed ligula consectetur
molestie quis ac diam.

## Subhead One

Phasellus rhoncus orci vitae felis porttitor blandit. Curabitur
metus felis, pulvinar sed imperdiet ut, fermentum tristique lectus.
Nullam sit amet orci id ligula pellentesque sodales. 

### Sub-subhead Two

Morbi facilisis felis a nisl vestibulum, non faucibus enim varius.
Fusce at auctor sapien. Nunc mauris mauris, tempus ut sagittis quis,
bibendum ornare nulla.

Sample output:

# Table of Contents
- [Main Title](#main-title)
    - [Subhead One](#subhead-one)
        - [Sub-subhead Two](#sub-subhead-two)

# Main Title
<a name="main-title"></a>

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque
quis laoreet libero. Phasellus quis justo sed ligula consectetur
molestie quis ac diam.

## Subhead One
<a name="subhead-one"></a>

Phasellus rhoncus orci vitae felis porttitor blandit. Curabitur
metus felis, pulvinar sed imperdiet ut, fermentum tristique lectus.
Nullam sit amet orci id ligula pellentesque sodales. 

### Sub-subhead Two
<a name="sub-subhead-two"></a>

Morbi facilisis felis a nisl vestibulum, non faucibus enim varius.
Fusce at auctor sapien. Nunc mauris mauris, tempus ut sagittis quis,
bibendum ornare nulla.

This works for me, I hope someone else finds it useful.


  1. Ulysses uses MarkdownXL as it’s internal format, but what’s shown on the screen is plain-old vanilla markdown.
  2. The navigation panel pulls out the headings but there’s no way to export it.
  3. This is the command below the regular paste command in the Edit menu.