Syntax Highlighting in LaTeX with minted

This post serves as an introduction to minted, a pygments-based syntax highlighter for LaTeX. Adding pygments to LaTeX streamlines so many things. The post provides a few examples of things you can do with minted, details the installation process, and covers some basic security.

Code

Overview

The easiest way to present code in LaTeX is to use the verbatim environment. It's quick, it preserves formatting, and it requires no set up. It's also very bland. Its ease of use comes at the cost of basically all the context clues well-formatted and styled code can provide.

The next step up (or rather many steps up) is the listings package. Out the box, it supports a broad range of languages. It's eminently configurable. You can define new languages yourself, add different keywords, and style to your heart's content. It's very good at being straightforward. Moving beyond its predefined scopes (or easily discoverable internet styles) is a challenge, though, because parsing and tokenizing code in LaTeX is just about as hard and ridiculous as it sounds.

minted has become a solid competitor. It uses the pygments project to parse and highlight. You've probably seen pygments in action already. It's a beast of an application that can do just about anything you want re: syntax highlighting. minted isn't quite as flexible, but it does have access to most of the pygments features. Recognizable styles, a massive library of lexers, and simple customization through Python make minted, by way of pygments, a veritable utility knife.

There's a bit more to the listings vs. minted debate. Essentially it boils down to where you want to customize. Personally, I feel like a general-purpose scripting language used in all areas of tech is a stronger contender than a typesetting system many of my peers have struggled to learn. I don't know, though (and if I'm wrong, I'd love to hear about it). At its core, TeX tokenizes everything. I'm just not sure that it can achieve the same level of regex wizardry that goes into some of the pygments code.

Installing

minted requires a few things to get up and running.

Python

You'll need Python to get started. Pygments needs >=2.6 or >=3.3, depending on your version of Python. You can lazily install both with any trouble. For example, via dnf,

$ sudo dnf install python{2,3}

pip

Next you'll need pip, a wonderful package manager for Python. It's ridiculously easy to install. Rather than install it globally (i.e. to /usr/bin), we're going to install it locally via the --user flag.

If you don't (e.g. modern RHEL derivatives, I think), you'll have to get creative. This is the easiest route:

$ sudo dnf install 'texlive-*'...Install >5779 Packages

Total download size: >2.4 GInstalled size: >3.8 GIs this ok [y/N]:

If, like me, you're running an SSD on a budget, the easiest isn't very convenient. Maybe you just don't feel like warehousing all of TeX Live to snag 16 dependencies. If you're not going to install everything, you need to figure out what you have to install. dnf/yum makes this somewhat trivial. If you're stuck with dpkg/dpkg-query, the discovery will be much more involved (but also I think you can run tlmgr so there's that).

minted

-shell-escape

Because minted relies on an external application (pygments) to highlight, it can't just run in a tiny, neatly contained environment. TeX essentially exposes streams but, by default, access to the operating system is locked down. -shell-escape neatly sidesteps those restrictions, but it doesn't come without risk. Just like anything else, it's probably not a great idea to provide shell access until you understand what's going on. Don't download random things off the internet and execute them blindly. Don't run in superuser mode all the time. You know, basic stuff.

This is what happens when you try to run minted without -shell-escape. Notice at the beginning that external actions are limited (restricted \write18 enabled). The document will not compile (even without -halt-on-error).

Chances are you're not actually building from the CLI every time. You've probably got an editor with some build commands stored. Don't add -shell-escape to all of your build profiles. It's a pain to toggle custom builds off and on, but having to rebuild your system after an attack is worse. Look for something like User Builds, Custom Commands, or the like.

Useful features

You've already seen how simple it is to add code to a tex file. minted also makes it easy to include external source code without worrying about getting it to play well with your editor. The \inputminted macro lets you load any file while specifying the lexer.

Styles:~~~~~~~* default: The default style (inspired by Emacs 22).* emacs: The default style (inspired by Emacs 22).* friendly: A modern style based on the VIM pyte theme.* colorful: A colorful style, inspired by CodeRay.* autumn: A colorful style, inspired by the terminal highlighting style.* murphy: Murphy's style from CodeRay.* manni: A colorful style, inspired by the terminal highlighting style.* monokai: This style mimics the Monokai color scheme.* perldoc: Style similar to the style used in the perldoc code blocks.* pastie: Style similar to the pastie default style.* borland: Style similar to the style used in the borland IDEs.* trac: Port of the default trac highlighter design.* native: Pygments version of the "native" vim theme.* fruity: Pygments version of the "native" vim theme.* bw:

* vim: Styles somewhat like vim 7.0* vs:

* tango: The Crunchy default Style inspired from the color palette from the Tango Icon Theme Guidelines.* rrt: Minimalistic "rrt" theme, based on Zap and Emacs defaults.* xcode: Style similar to the Xcode default colouring theme.* igor: Pygments version of the official colors for Igor Pro procedures.* paraiso-light:

* arduino: The Arduino® language style. This style is designed to highlight the Arduino source code, so exepect the best results with it.* rainbow_dash: A bright and colorful syntax highlighting theme.* abap:

You can preview any of the styles by visiting the pygments demo and trying out a highlighter. Once pygments has parsed the code, you'll be able to change the style at whim.

If you want to use the same style throughout your document, minted makes that simple too. The \newminted macro defines a configuration for a specific language, e.g. python. It can then be used as an environment in place of minted by appending code to the end, e.g. pythoncode.

You can use the same logic with \inputminted via \newmintedfile. Rather than defining a new environment, \newmintedfile creates a new macro. It has an optional name parameter to make things easier (otherwise the macro is called \<language>file).