Creating PDF Documentation with Markdown, Pandoc, and Powershell
2 min read

Creating PDF Documentation with Markdown, Pandoc, and Powershell

Using Markdown is a great way to store documentation in source control. You can check in your documentation along with your issue code, and websites like GitLab and GitHub will automatically convert it to HTML.

But not everyone wants to browse your source control website to view documentation. Sometimes documentation needs to be distributed to team members or bosses. In that case you could keep a word document or text file, but word docs are binaries and are not ideal for version control, and text files just don't look great to distribute.

So use Markdown for everything. Keep your documentation in Markdown, convert it to a PDF using Pandoc, and automate the process using Powershell. I'll also show you how to easily add a date stamp to all of your PDFs. And at the very end there's a quick way to cheat if you're using Visual Studio Code.

Install Pandoc

Install Pandoc by downloading from https://pandoc.org/ or by using chocolatey.

Chocolatey makes it easy:
choco install pandoc

Or you can run the windows installer on the pandoc downloads page.

Install Miktex

Next you need to install Miktex. Miktex will allow you to include macros and scripts in your markdown that is processed by Pandoc. In our case we're using it to substitute the date and time in our documentation.

Install MiKTex from https://miktex.org/download

Follow the instructions at http://www.texts.io/support/0002/. Make sure to select "Install missing packages on the fly".

Restart your computer after installing MiKTex. The first time you run Pandoc at the command line it may take a little longer because it's downloading and installing updates. Make sure that you run from an Administrator prompt the first time.

Adding Timestamps to your Documents

Use the {{currentdate}} token at any spot that you want the current date inserted.

Author: Jason Murray
jason@catapultweb.com
last updated: {{currentdate}}

# Hello #
This is my documentation.

Use Powershell to convert Markdown Files to PDFs

We're using a lua script to insert the date. Create a text file called currentdate.lua and insert the script below.

The double dashes are comments. The return statement says that when the string {{currentdate}} is found that it should be replaced by the date using the format %m/%d/%Y %I:%M %p. You can change the {{currentdate}} token to whatever you like, and the date format can also be whatever you like.

-- Put the current date in place of the text {{currentdate}} anywhere in the document.
-- Adapted from here: https://pandoc.org/lua-filters.html#replacing-placeholders-with-their-metadata-value
-- https://pandoc.org/lua-filters.html
-- When using pandoc call like this pandoc --lua-filter=currentdate.lua
return {
  {
    Str = function (elem)
      if elem.text == "{{currentdate}}" then
        return pandoc.Str(os.date("%m/%d/%Y %I:%M %p"))
      else
        return elem
      end
    end,
  }
}

Convert Markdown to PDF

Here's how to create a PDF from markdown at the command line.

pandoc documentation.md --pdf-engine=xelatex -o documentation.pdf --lua-filter=currentdate.lua

The lua filter is what substitutes the current date for {{currentdate}}

We can use Powershell to create PDFs for every file in a directory:

$files = Get-ChildItem "C:\path\to\markdown\directory\"
foreach ($f in $files)
{
    pandoc $f.fullname --pdf-engine=xelatex -o join($f.basename,".pdf") --lua-filter=currentdate.lua
}

From there you can work the Powershell into a Post-Build event or execute it manually any time your documentation changes.

A Cheat that Cuts to the Chase

If you're using Visual Studio Code you can install an extension called Markdown Converter that will convert Markdown to PDF. It supports other substitutions such as {{author}}. But doing it with Pandoc is more fun and flexible. You can now write your own lua scripts following the format above.

Further Reading