Tx · LaTeX & TikZ

How to Convert a LaTeX File to PDF with Python on Linux

Published By the 9to5Science editorial team

At a glance

  1. 1. Install LaTeX tools

    Install latexmk and a TeX distribution, such as the recommended LaTeX packages provided by Ubuntu.

  2. 2. Pass arguments safely

    Call latexmk with subprocess.run and a list of arguments; avoid building a shell command from user input.

  3. 3. Check the result

    Inspect the process exit code and confirm the PDF exists in the chosen output directory.

To create a PDF from a .tex file on Linux, Python can run a standard LaTeX command-line tool. A reliable choice is latexmk, which runs the necessary LaTeX passes and can also invoke tools such as BibTeX when needed.

The basic approach is to install the TeX tools, call latexmk with subprocess.run, and check whether compilation succeeded. You do not need to convert the LaTeX source into PDF using a Python-specific package.

Install the required tools on Ubuntu

Open a terminal and install latexmk and a TeX distribution:

sudo apt update
sudo apt install latexmk texlive-latex-recommended

This covers many common documents. Depending on your file, you may also need packages such as texlive-latex-extra, texlive-fonts-recommended, or a language-specific package. If compilation reports that a .sty file is missing, install the Ubuntu package that provides it, or install a broader TeX Live collection.

Check that the executable is available:

latexmk -v

Compile a file from Python

This script takes a .tex filename as its command-line argument, compiles it into a build folder beside the source, and reports errors if the compilation fails:

from pathlib import Path
import shutil
import subprocess
import sys

if len(sys.argv) != 2:
    raise SystemExit("Usage: python3 compile_tex.py document.tex")

source = Path(sys.argv[1]).resolve()
if not source.is_file():
    raise SystemExit(f"TeX file not found: {source}")

latexmk = shutil.which("latexmk")
if latexmk is None:
    raise SystemExit("latexmk is not installed or is not on PATH")

output_dir = source.parent / "build"
output_dir.mkdir(exist_ok=True)

command = [
    latexmk,
    "-pdf",
    "-interaction=nonstopmode",
    "-halt-on-error",
    "-file-line-error",
    f"-outdir={output_dir}",
    source.name,
]

result = subprocess.run(
    command,
    cwd=source.parent,
    text=True,
    capture_output=True,
)

if result.returncode != 0:
    print(result.stdout)
    print(result.stderr, file=sys.stderr)
    raise SystemExit(result.returncode)

pdf = output_dir / f"{source.stem}.pdf"
if not pdf.is_file():
    raise SystemExit(f"Compilation reported success, but no PDF was found at {pdf}")

print(f"Created: {pdf}")

Save it as compile_tex.py and run it like this:

python3 compile_tex.py report.tex

For a file at /home/sam/papers/report.tex, the expected PDF is /home/sam/papers/build/report.pdf. The output directory keeps generated files—such as auxiliary files and logs—separate from the source.

What the command options do

  • -pdf tells latexmk to produce a PDF using a PDF-capable LaTeX engine.
  • -interaction=nonstopmode lets compilation proceed through errors so they can be recorded in the log; it does not make a failed document successful.
  • -halt-on-error stops at the first LaTeX error rather than continuing through many cascading errors.
  • -file-line-error makes many LaTeX errors easier to locate by including a filename and line number.
  • -outdir=... selects the directory for the PDF and other generated files.

The cwd argument sets the working directory to the source file’s folder. This helps LaTeX find files referenced with relative paths, such as images or included .tex files. The script passes arguments as a list and leaves shell disabled, which is the safer default for subprocess calls. Paths containing spaces are handled without extra quoting.

A minimal test document

To check the installation, save this as report.tex:

\documentclass{article}
\begin{document}
Hello from LaTeX.
\end{document}

Run the Python script on it. If compilation succeeds, build/report.pdf should contain the text. This small test distinguishes a missing or broken TeX installation from errors in a larger document.

Common mistakes

Using pdflatex directly for a document that needs several passes. A single pdflatex run can make a PDF, but references, citations, and tables of contents may need repeated runs. latexmk handles the usual reruns automatically.

Assuming Python installs LaTeX. Python launches the compiler; it does not provide one. Install the TeX tools with your Linux distribution’s package manager and ensure the executable is on PATH.

Ignoring a nonzero exit code. A PDF file may exist from an earlier successful run even though the latest compile failed. Use the current process’s returncode and inspect the log output before treating the result as valid.

Invoking a shell string unnecessarily. Avoid code such as subprocess.run("pdflatex " + filename, shell=True). It can break on spaces and can expose shell-injection risks when filenames or arguments are untrusted. Pass a list of arguments, as in the example.

Expecting every document to work with the same engine. The example selects the PDF workflow commonly used with pdflatex. If your document requires XeLaTeX or LuaLaTeX—for example, for system fonts—select the matching latexmk engine option, such as -xelatex or -lualatex, and install the required engine and packages.

References

  1. latexmk — CTAN package page and documentation
  2. Python documentation: subprocess

Spotted an error? Send a correction. Read how we write and check articles in our editorial policy.