Better Markdown for Writers

2 minute read

TLDR; you can find the templates I use for writing at my writing repository.


My very first writings were done in Org-mode for Emacs. org-mode is a beat of a format for the Emacs text editor. With it, you can take notes, track time, organize projects, make to-do lists, and write blog posts.

I loved working with org-mode. But, since no one uses it, I had to convert my lovely org files into Markdown or Word to get a review or share a publishable package.

The conversion itself was fine. Pandoc is quite capable of parsing org files. The nag was that I had two juggle org and Markdown formats in my head. Too many times, I found myself adding org directives in Markdown and wondering why it didn’t work. Eventually, I decided to ditch org and move to Markdown for good.

Org-mode includes

The thing I loved most about org (for writing, at least) was its ability to use includes. I can add an #+INCLUDE directive, and Emacs/pandoc would expand the contents of that file into the main document. For example, with org, I could do this:

* My Title

Check out this awesome code:

#+INCLUDE: "./example.js" src javascript

Having code in separate files makes it very easy to copy/paste the text into tools like Grammarly or Hemingway Editor.

Adding includes to Markdown

Markdown, unfortunately, does not have includes. With meant that I had to mix code and text on the same file. I didn’t want to do that. Was there any way of adding includes to Markdown?

After some Googling around, I found m4, a macro processor that has an include directive. To use this feature on Markdown, we must first change the default quotation marks by adding this at the top of the main Markdown file:

changequote(`{{', `}}')

This enables me to write my code sample on a separate file, e.g., example.js:

```javascript
console.log("Hey!")
```

And expand its contents by adding this line in my main Markdown file:

include({{example.js}})

To render the expanded Markdown, we call m4 like this:

m4 -E -I./ main-post.md > expanded-post.md

The -I argument points to the include folder. So, this:

changequote(`{{', `}}')

# My Title

Check out this awesome code:

include({{example.js}})

Renders as:

# My Title

Check out this awesome code:

```javascript
console.log("Hey!")
```

Putting everything together

Over time, I put together small Makefiles that use this technique in conjunction with pandoc to convert my flavor of Markdown into plain Markdown, Word, or plain text. You can check the templates I use in my writing repository.

Happy writing!

-Tommy

Tags:

Updated: