Sunday, March 12, 2017

How to install Pandoc in Docker and convert Markdown to PDF

Pandoc is described as the Swiss Army knife of document converters. Following are my notes describing how to combine Docker and Pandoc, with a bit of Perl, to implement a command line utility that converts from one format to another (in this case, Markdown to PDF).

Note: Following assumes that you already have a working instance of Docker and that you can either: configure Docker to run as a normal user or can configure sudo to allow the user to run Docker.

Steps:

1) Create a working directory and navigate into it:

  mkdir work
  cd work

2) Pull in J. A. Gregory's Dockerfile by running:

  wget https://github.com/jagregory/pandoc-docker/blob/master/Dockerfile

3) Create the Docker container by running:

  docker build -t pg/pandoc .

Note the period at the end. The above will take a few minutes to build so take a bio break, make a cup of coffee, or do something else that takes about 5 minutes.

4) In a "/bin" directory (I use /home/tim/bin and have added that to my $PATH), create a file called "md2pdf", containing the following:

  #!/usr/bin/perl
  
  $src=$ARGV[0];
  $tgt=$ARGV[1];
  
  # declare the output
  $format = "latex";
  
  # edit the following to tweak your output
  $margin="-V geometry:margin=1in";
  $toc = "--toc";
  
  # following should all be on a single line
  # use "sudo docker..." if your Docker can't be called by 
  # a normal user
  system("sudo docker run -v `pwd`:/source pg/pandoc $toc \
    $margin -f markdown -t $format $src -o $tgt");

In the above, "-v `pwd`:/source" allows you to convert a Markdown file in whichever directory you happen to be working in, when calling pandoc. Effectively, you're temporarily linking your current working directory to the "/source" folder in the container.

5) Make "md2pdf" executable by running:

  chmod a+x md2pdf

In the above, the $margin variable redefines the margins for the output. Without the declaration, the output's margins are a bit excessive. The $toc variable causes the output to have a table of contents. If you use that, you'll probably also want to use \newpage or \pagebreak in your Markdown code, to trigger a new-page in the output.

6) Test your instance by creating a file called "mine.md", containing:

  \newpage
  # This is a test
  Just want to see if this works

    #sample code
    blah blah

  Hopefully it worked.

7) Test the file conversion by running:

  md2pdf mine.md mine.pdf

8) Open the new file in Google Chrome or your favorite PDF reader.

Sources: