Tiny BSD-make Pipeline to Turn Org Files into PDFs

I keep a lot of course material in Org mode, and I wanted a one-liner to turn everything in a directory into PDFs. The result is a tiny BSD make file that I wrote on macOS and that works on any BSD-compatible make. Under the hood it uses Pandoc to convert .org → LaTeX and XeLaTeX (xelatex) to render the PDF.

Below I’ll share the Makefile, explain how it works, and point out the two knobs you’re most likely to touch: fonts and language (e.g., “Chapter” vs. “Kapitel”).

Why BSD make?

On macOS /usr/bin/make is BSD make. Many Makefile snippets on the internet assume GNU make features; this one doesn’t. If you can run make on macOS without installing anything, you’re good.

Prerequisites

  • Pandoc (e.g., via Homebrew: brew install pandoc)
  • A TeX distribution with XeLaTeX (e.g., MacTeX)
  • The fonts you intend to use installed in your OS (system font names, e.g., “Overpass”)

The Makefile

This version assumes no spaces in filenames (e.g., MyDoc.org is fine; My Doc.org is not). It uses a suffix rule (a “file builder”) so you can build all PDFs at once or a single target.

Please keep in mind: the Makefile has to contain tabs and not spaces! The full source of the Makefile included sample documents is here: org-pandoc-makefile.

# Makefile — Org → PDF (BSD make)
# SPDX-License-Identifier: MIT
# Copyright (c) 2025 Ulrich Habel <rhaen@pkgbox.de>


PANDOC?=pandoc
PDF_ENGINE?=xelatex
PANDOC_FLAGS?=-f org+task_lists
# Additional version to display TOC / please exchange with line above
# PANDOC_FLAGS?=-f org+task_lists --toc --number-sections --toc-depth=3

MAINFONT?=Overpass
SANSFONT?=${MAINFONT}
MONOFONT?=Overpass Mono

# Pass fonts through to Pandoc/LaTeX
PANDOC_VARS= \
  -V mainfont="${MAINFONT}" \
  -V sansfont="${SANSFONT}" \
  -V monofont="${MONOFONT}"

.SUFFIXES: .org .pdf

# File builder: .org -> .pdf
.org.pdf:
  @echo "Converting '$<' -> '$@'"
  @${PANDOC} ${PANDOC_FLAGS} \
    --pdf-engine="${PDF_ENGINE}" \
    ${PANDOC_VARS} \
    -o "$@" "$<"

.PHONY: all clean

# Build all .org files in the current directory
all:
  @set -e; \
  for f in *.org; do \
    [ -f "$$f" ] || continue; \
      ${MAKE} "$${f%.org}.pdf"; \
  done

# Remove PDFs corresponding to current .org files
clean:
  @set -e; \
  for f in *.org; do \
    [ -f "$$f" ] || continue; \
    rm -f "$${f%.org}.pdf"; \
  done
  @echo "Done."

Usage

  • Build everything in the folder
make
  • Build a single document

    make MyExample.pdf
    
  • Override default font selection

    make MAINFONT="Arial" MONOFONT="Menlo"
    

Fonts: what to change and why

The Makefile passes three variables to Pandoc/LaTeX:

  • mainfont → body text (e.g., “Overpass”)
  • sansfont → used where the template wants a sans-serif face
  • monofont → code/mono blocks

Because we use XeLaTeX, these names must match installed system fonts. If Pandoc can’t find the font, XeLaTeX will fall back (and your PDF might look different than expected). If you change only one thing in the header, it’s probably MAINFONT.

Language “Chapter” vs “Kapitel” (auto labels)

Pandoc’s LaTeX output uses language metadata to choose localized strings (via polyglossia with XeLaTeX). That’s why you may see “Chapter” in English or “Kapitel” in German without you writing those words anywhere.

You can control the language in two straightforward ways:

make PANDOC_FLAGS='-f org+task_lists -V lang=en-US'
# or
make PANDOC_FLAGS='-f org+task_lists -V lang=de-DE'

PANDOC_FLAGS

I found no meaningful way to change the pandoc headers within the org-file. Even exporting YAML options were not working. You could work with sidecar files; however that is something that I don’t need. Therefore you need to change the Makefile if required.

Troubleshooting

  • “Nothing to be done for all.”

There are no *.org files in the directory, or your PDFs are already up-to-date. Touch a file or run make clean.

  • Fonts aren’t applied.

Check that the font names are installed and spelled exactly as your OS lists them (Font Book on macOS).

  • I need spaces in filenames.

This minimal file builder focuses on simple names. If you truly need spaces, switch the all rule to a more robust loop or a find … -print0/xargs -0 approach and avoid per-file targets—BSD make doesn’t love whitespace in target names.

Advanced usage

You can specify alot of variables and settings in the header of your org-file and they’ll be picked up by pandoc during runtime. Please check the source code repository for examples of the pdf conversion and to see the complete org-file used to generate them.

Source Code Repository: org-pandoc-makefile

Enjoy - if you find bugs, please report them.