You got LaTeX in my Markdown!

Tuesday, October 21, 2014

Working title: You got Markdown in my LaTeX!

I hate writing documents in Microsoft Word and Apple Pages. I spend way too much time fiddling with formatting, page layout, and typesetting before everything looks the way I want it. And writing math equations, even with Word's GUI equation editor, is tedious and takes too much clicking. I'm a programmer—just let me use LaTeX's equation format instead!

tl;dr If you want to write documents in Markdown, embed LaTeX, and generate PDFs, use Pandoc.
Skip down to Kung Fu Pandoc to get started!

So just use LaTeX, they said. It'll be fun, they said.

I like typesetting tools, and I like LaTeX... with reservations. Some of my complaints:

  • The boilerplate needed to get a TeX document up and running is pretty massive.
  • LaTeX is a pain in the ass to write. There is so much character overhead behind basic formatting.
  • Holy reserved characters, Batman! Here are things you can't write in LaTeX without escaping:
# $ % ^ & _ { } ~ \

It's not like I'd ever want to use a dollar sign in my budget report or an underscore in my C code.

  • If you don't escape a character properly, you'll probably get a syntax error. LaTeX's syntax errors are cryptic and terrifying:

Wouldn't it be nice if...

This semester, I tried to write an assignment for class and found out my LaTeX build chain in Sublime broke. Instead of trying to troubleshoot it, I started thinking about what I'd like to use instead.

Here's why I love LaTeX:

  • It lets me write equations quickly. Its equation syntax makes sense to me, and it's easy to steal import equations from Wikipedia pages.
  • It's a typesetting program, not a WYSIWYG. No more screwing around with weird margin sliders and page layout tools and header settings: simply throw in your text, edit the settings once, and watch all your text reflow into place.
  • It's easy to generate a PDF from a LaTeX file.

Here's why I prefer Markdown as a language to write formatted text:

  • It's SUPER lightweight. **bold**, *italic*, ```inline code` ``.
  • GitHub-flavored Markdown is super cool. It adds support for syntax-highlighted code blocks and tables! I like it so much I built a tool to generate Markdown tables from CSV files.
  • You probably already know its syntax if you use GitHub or Reddit frequently.

I asked myself: "Self, wouldn't it be great if there were a typesetting tool that let you write documents in Markdown, embed LaTeX where you needed it, and generate PDFs?" And it turns out that already exists.

Kung-Fu Pandoc

If you need to convert files from one markup format into another, pandoc is your swiss-army knife.

John MacFarlane, author of pandoc

We'll use this Swiss Army knife called Pandoc to compile and export our Markdown-LaTeX docs. Let's try it out!

Install Pandoc and LaTeX

You'll need Pandoc and pdfTeX installed. If you can run pandoc and pdflatex from a terminal, you're probably good to go.

If you're on a Mac, install Pandoc using Homebrew (brew install pandoc) and install MacTeX using their .pkg installer.

Get Your Source Doc

Here's a sample Markdown-plus-LaTeX document you can try to compile. Save that file somewhere as example.md.

Compile Your Doc

Here's the command I used to compile example.md —> example.pdf:

pandoc -o example.pdf example.md

See? It's that easy. Now open your PDF and you should see something like this:

Markdown as PDF

Awesome. You're one step closer to well-documented world domination.

Automate That Ish with Sublime Text's Build Systems

Great! Now you can build Pandoc Markdown docs manually from the command line.

If you use Sublime Text like me, you might use the Build command (F7 or Cmd+B) to build and run your scripts. When I used LaTeXTools, I got really used to checking how my LaTex looked when it was rendered by hitting Cmd+B. The LaTeX build command rendered my source document and opened a PDF viewer with the results.

I duplicated this in Sublime Text. Here's how you can too!

Create a new Sublime-Build file

Sublime-Build files tell Sublime Text how you want to build a document when you hit Ctrl-B.

Create a new Sublime-Build file by selecting Tools —> Build System —> New Build System...

You'll get a document named untitled.sublime-build that looks like this:

{
    "shell_cmd": "make"
}

Write Your Pandoc Build Command

Replace the contents of your new document with the following:

{
    "shell_cmd": "pandoc -o \"$file.pdf\" \"$file\" && open -a Preview \"$file.pdf\"",
    "selector": "text.html.markdown",
    "path": "/usr/texbin:$PATH"
}

Then change a few things:

If you're not on a Mac, remove the open -a command.

open -a Preview \"$file.pdf\"" is just for Macs—it opens the rendered file in Preview.app.
If you're not on a Mac, strip off the && characters and everything after them. Your shell_cmd will look like this:

{
    "shell_cmd": "pandoc -o \"$file.pdf\" \"$file\"",
    ...

Remove the path setting if you don't want it. Easier: just leave it in.

I found my Sublime install couldn't find pdflatex unless I added this directory to the build system's path directly. You can probably leave it in—it shouldn't do any harm as long as Sublime can find pdflatex.

Save Your New Build Command

The default save location will be Sublime Text 3/Packages/User. Save the file you just created into that directory as Markdown to PDF.sublime-build.

Set "Build System" to "Automatic"

Select Tools —> Build System —> Automatic to ensure Sublime picks your new Markdown build system.

Build a Markdown File!

Open the example.md file you downloaded earlier in Sublime, then hit F7 or Cmd-B. The Sublime Text console should open as it starts compiling your document, then print something like this when it's done:

[Finished in 2.4s]

Check the directory holding example.md and look for a brand-new example.md.pdf file!

You did it! I am very proud of you.

Bonus Round: Custom LaTeX Templates

You're a cool guy who knows cool stuff. Want to make your LaTeX docs even cooler? Add your own custom template.

Say I hate the default LaTeX monospace font and I want to add \usepackage{inconsolata} to fancy up my code blocks. Here's how I can do that:

  • Save a LaTeX template somewhere on my computer
  • Edit that template and add the LaTeX packages I want
  • Ask Pandoc to use that template every time I compile my documents

Get a LaTeX template

I used this default.latex template provided by jgm. Seems to work great!

I saved mine as ~/.pandoc/default.latex because I think that's where Pandoc templates usually go.

Edit that template

At line 134, I added some text to remind me where I can safely put \usepackage commands, as well as my custom command:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ADD YOUR \usepackage{...} COMMANDS HERE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\usepackage{inconsolata}

Make Pandoc use that template

I edited my shell_cmd inside my .sublime-build file from the following:

"shell_cmd": "pandoc -o \"$file.pdf\" \"$file\" && open -a Preview \"$file.pdf\"",

I added a command-line argument pointing Pandoc to my default template as shown:

"shell_cmd": "pandoc --template=\"/Users/mplewis/.pandoc/default.latex\" -o \"$file.pdf\" \"$file\" && open -a Preview \"$file.pdf\"",

Now Pandoc uses my new template and makes my typewriter text not suck. Hooray!

I'd love to hear what you think about this post. Email me!