How to Build LaTeX with Travis CI and Minted

How to Build LaTeX With Travis CI and Minted Featured Image

To be honest, this article is a bit of a rant piece, but I figured it could go to helping others. If you’re wondering how you could build LaTeX documents using Travis CI and Minted, you’ve come to the right place.

Table of Contents

Problem Description

In case you’re wondering how I came up with this predicament, I’m a PhD student, and I’ve just decided to start learning LaTeX because it seems useful. In the process, however, I’ve decided to tie in good software engineering principles like version control and continuous integration. As it turns out, the latter is very, very challenging.

In particular, I was looking for a way to generate LaTeX PDFs using Travis CI which is built right into GitHub. While that’s a challenge on its own, I took it upon myself to make things more interesting by adding a package, minted, which requires a few external dependencies. Namely, I needed Python access, the Pygments library, and shell access. As it turns out, this was more challenging than you’d think.

How to Build LaTex

Note: I wrote this tutorial back when Atom was my preferred editor. As of 2022, Atom is no longer maintained, so feel free to use a more modern text editor like VSCodeOpens in a new tab. and its latex pluginsOpens in a new tab.. Similarly, I used to use Travis CI and tend to prefer GitHub Actions these days. At some point, I will come back and rewrite this tutorial, but the general premise still sticks.

Normally, we can build LaTeX using any number of LaTeX tools. For me, that meant downloading MikTex and Perl on my Windows 10 machine. After that, I downloaded the LaTeX plugin for Atom, and I got to work.

To put it more formally, I used the following steps to get my Windows environment setup for LateX building:

  1. Download and install MikTexOpens in a new tab.
  2. Download and install Strawberry PerlOpens in a new tab.
  3. Download and install PythonOpens in a new tab.
  4. Download and install Atom (or a modern text editor like VSCode)
  5. Download and install latex package
  6. Check box in latex plugin settings for Enable Shell Script

After that, you should be able to get up and running. Of course, I may be missing some dependencies here and there as I already had some of these installed on my system.

With all the dependencies setup, the build workflow looks something like the following:

  1. Write and save document changes
  2. Go to Packages > LaTeX > Rebuild
  3. Profit

To be honest, it couldn’t really be easier once everything is installed. After all, MikTex handles the installing of packages you’re missing, so there’s LaTeX dependencies shouldn’t be an issue. Of course, let me know otherwise in the comments.

How to Automate LaTeX Build

Unfortunately, the method described above is impractical when it comes to Travis CI. After all, we’d like to be able to install all these components every build using the command line.

Luckily, there’s a community of LaTeX folks who work with continuous integration, so there are already several methods for continuous integration. That said, I had a lot of trouble getting up and running despite their efforts. If you’re looking for the world’s saddest list of commits, check out my pull request just to get the build workingOpens in a new tab.. In total, there were about 82 commits of which more than half were failing builds.

Of course, I don’t expect you to dig through my efforts. Instead, I want to provide you with the solution.

Travis YAML

With every Travis CI build, you need a YAML file to tell the server how to build your code. In this case, I’m using a YAML that looks like the following:

language: generic

# Dependency of the minted package
before_install:
  - sudo apt-get install python-pygments

install:
  - source ./texlive/texlive_install.sh

cache:
  directories:
    - /tmp/texlive
    - $HOME/.texlive

# Change working directory so including files will work
before_script: cd $TRAVIS_BUILD_DIR/assignment01/doc/

script:
  - pdflatex --shell-escape ./assignment01.tex

deploy:
  provider: releases
  api_key:
    secure: ${GITHUB_TOKEN}
  file:
    - ./assignment01.pdf
  skip_cleanup: true
  on:
    tags: true
    branch: master

notifications:
  email: false

Breaking this down, there are a few things to note. First, it’s important to be aware that we can’t specify a language as Travis CI doesn’t have native LaTeX build support. Instead, we have to go with a generic setup:

language: generic

With language setup out of the way, we can begin by running a before install command to pick up the Python Pygments package which aids in syntax highlighting:

before_install:
  - sudo apt-get install python-pygments

After that, we run another install command on a local shell script—more on that later:

install:
  - source ./texlive/texlive_install.sh

From there, we make sure to cache our install, so we don’t have to do it every build:

cache:
  directories:
    - /tmp/texlive
    - $HOME/.texlive

After the initial setup, we move into the working directory which happens to be a folder where my LaTeX file sits. Feel free to change this line to your needs:

before_script: cd $TRAVIS_BUILD_DIR/assignment01/doc/

Now that we’re in our working directory, we can safely build our PDF. This is the real magic of the build as we require a special option, -shell-escape, which allows us to access our python packages for syntax highlighting:

 script:
  - pdflatex --shell-escape ./assignment01.tex

At this point, everything else is just bonus. For instance, I’ve setup my YAML to deploy all the PDFs to the latest tagged release. You’ll need to populate the GITHUB_TOKEN with your own token.

deploy:
  provider: releases
  api_key:
    secure: ${GITHUB_TOKEN}
  file:
    - ./assignment01.pdf
  skip_cleanup: true
  on:
    tags: true
    branch: master

Finally, we turn off email notifications because those are annoying:

notifications:
  email: false

And, there we have it! A Travis CI YAML which gets the job done for automated builds.

Additional Build Scripts

In addition to this YAML, we’ll need a set of scripts which are used to setup LaTeX and the dependencies we need. Fortunately, I didn’t have to write these scripts as they were provided for me by our friends over at the travis-ci-latex-pdf repoOpens in a new tab.. For the sake of completeness, I’ve shared them below. Make sure to place all these files in the root of your repo under a directory called texlive:

texlive/texlive.profile

selected_scheme scheme-basic
TEXDIR /tmp/texlive
TEXMFCONFIG ~/.texlive/texmf-config
TEXMFHOME ~/texmf
TEXMFLOCAL /tmp/texlive/texmf-local
TEXMFSYSCONFIG /tmp/texlive/texmf-config
TEXMFSYSVAR /tmp/texlive/texmf-var
TEXMFVAR ~/.texlive/texmf-var
option_doc 0
option_src 0

texlive/texlive_packages

xcolor
fancyhdr
fancyvrb
makecmds
multirow
chngcntr
fvextra
upquote
lineno
ifplatform
xstring
framed
caption
collection-fontsrecommended
minted
oberdiek
etoolbox
float
booktabs

texlive/texlive_install.sh

#!/usr/bin/env sh

# Originally from https://github.com/latex3/latex3

# This script is used for building LaTeX files using Travis
# A minimal current TL is installed adding only the packages that are
# required

# See if there is a cached version of TL available
export PATH=/tmp/texlive/bin/x86_64-linux:$PATH
if ! command -v texlua > /dev/null; then
  # Obtain TeX Live
  wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
  tar -xzf install-tl-unx.tar.gz
  cd install-tl-20*

  # Install a minimal system
  ./install-tl --profile=../texlive/texlive.profile

  cd ..
fi

# Just including texlua so the cache check above works
tlmgr install luatex

# Install package to install packages automatically
tlmgr install texliveonfly

# Install babel languages manually, texliveonfly does't understand the babel error message
tlmgr install collection-langeuropean

# Common fonts with hard to debug errors if not found
#tlmgr install collection-fontsrecommended

# In the case you have to install packages manually, you can use an index of packages like
# http://ctan.mirrors.hoobly.com/systems/texlive/tlnet/archive/
# Or better, check https://www.ctan.org/pkg/some-package to see in which TeX Live package it is contained.

# Then you can add one package per line in the texlive_packages file
# We need to change the working directory before including a file
cd "$(dirname "${BASH_SOURCE[0]}")"
tlmgr install $(cat texlive_packages)

# Keep no backups (not required, simply makes cache bigger)
tlmgr option -- autobackup 0

# Update the TL install but add nothing new
tlmgr update --self --all --no-auto-install

Voila

At this point, we should have everything we need to launch a successful remote LaTeX build using Travis CI and Minted. If you have any problems or questions, feel free to reach out. That said, Thomas Schouten is the real expert. I recommend visiting their repoOpens in a new tab. at some point as there are several other ways to get things working.

At any rate, that’s all I have for now. Thanks again for stopping by!

Jeremy Grifski

Jeremy grew up in a small town where he enjoyed playing soccer and video games, practicing taekwondo, and trading Pokémon cards. Once out of the nest, he pursued a Bachelors in Computer Engineering with a minor in Game Design. After college, he spent about two years writing software for a major engineering company. Then, he earned a master's in Computer Science and Engineering. Today, he pursues a PhD in Engineering Education in order to ultimately land a teaching gig. In his spare time, Jeremy enjoys spending time with his wife and kid, playing Overwatch 2, Lethal Company, and Baldur's Gate 3, reading manga, watching Penguins hockey, and traveling the world.

Recent Posts