kaffesky-markdown-templates/convertion_templates_pandoc/template_pdf-via-xelatex/template_first-skyfritt-example.md
2026-03-27 12:21:04 +01:00

6.4 KiB

template_first-skyfritt-example.tex

Pandoc template for generating PDFs via XeLaTeX. Produces a document with a title page, table of contents, Roboto font, A4 format, 2.5 cm margins, and page numbering.


Requirements

  • Pandoc
  • A TeX Live installation with XeLaTeX
  • Homebrew (for installing fontconfig)
  • Roboto and Roboto Mono fonts

macOS Installation

1. Install Homebrew (if not already installed)

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

2. Install Pandoc

brew install pandoc

3. Install MacTeX / TeX Live

Download and install MacTeX from https://tug.org/mactex/, or install the lighter BasicTeX:

brew install --cask basictex

After installation, open a new terminal session so that /Library/TeX/texbin is on your PATH.

4. Update tlmgr and install LaTeX packages

sudo tlmgr update --self

sudo tlmgr install \
  titlesec \
  tocloft \
  booktabs \
  tools \
  fancyhdr \
  parskip \
  float \
  listings \
  fancyvrb \
  caption \
  hyperref \
  xcolor \
  fontspec \
  geometry \
  babel \
  pgf \
  currfile \
  filehook
  • pgf — provides TikZ, used to draw the vertical colour bar on the title page
  • currfile — resolves the template's directory at compile time, used to locate the logo file
  • filehook — required by currfile

5. Install fontconfig

fc-list and fc-cache are needed for font verification and are not included on macOS by default:

brew install fontconfig

6. Install fonts

Download Roboto and Roboto Mono from Google Fonts and install them into ~/Library/Fonts/:

curl -L "https://fonts.google.com/download?family=Roboto" -o roboto.zip && \
curl -L "https://fonts.google.com/download?family=Roboto+Mono" -o roboto-mono.zip && \
unzip roboto.zip -d ~/roboto && \
unzip roboto-mono.zip -d ~/roboto-mono && \
cp ~/roboto/static/*.ttf ~/Library/Fonts/ && \
cp ~/roboto-mono/static/*.ttf ~/Library/Fonts/ && \
fc-cache -f -v

Clean up:

rm -rf roboto.zip roboto-mono.zip ~/roboto ~/roboto-mono

7. Verify fonts are available to XeLaTeX

fc-list | grep -i roboto

You should see several lines listing the Roboto and Roboto Mono font files. If nothing appears, double-check that the .ttf files are present in ~/Library/Fonts/.

8. Verify LaTeX packages are installed

kpsewhich titlesec.sty tocloft.sty fancyhdr.sty caption.sty

Each line should return a file path. If any are blank, install the missing package individually:

sudo tlmgr install <packagename>

Usage

Add a YAML front matter block to the top of your Markdown file:

---
title: "My Document"
subtitle: "An optional subtitle"
author: "Jane Doe"
date: "March 2026"
description: "An optional blurb shown at the bottom of the title page."
---

Then compile with:

pandoc input.md -o output.pdf \
  --pdf-engine=xelatex \
  --template=./path/to/template_first-skyfritt-example.tex \
  --shift-heading-level-by=-1 \
  -V templatedir=./path/to/template_first-skyfritt-example.tex

Why -V templatedir=...?

The template includes a logo image (skyfritt-logo_borderless.pdf) referenced by filename only. XeLaTeX resolves bare filenames relative to the working directory where pandoc is invoked — not the template's own directory. Passing -V templatedir= tells the template where to look for the logo, so it is found regardless of which directory you run pandoc from.

The value should be the directory containing the template and logo files, e.g.:

-V templatedir=./convertion_templates_pandoc/template_pdf-via-xelatex

Why --shift-heading-level-by=-1?

Pandoc's article class maps #\section, ##\subsection, and so on. If your Markdown has a single # Document Title at the top followed by ## 1. Introduction, ## 2. …, etc., the title ends up as "Section 1" in the TOC and all real sections become subsections 1.1, 1.2, …

Passing --shift-heading-level-by=-1 shifts every heading up one level before rendering:

Markdown Without flag With flag
# \section (appears in TOC) promotes to document title — invisible in body
## \subsection \section
### \subsubsection \subsection

The # heading is absorbed as the top-level title and removed from the body, so your real sections (##) become proper \section entries.

Section numbering

By default the template suppresses LaTeX auto-numbering (secnumdepth = 0), because headings written as ## 1. Introduction already carry their own numbers. Letting LaTeX add its own would produce double-numbering like 1 1. Introduction.

If you prefer LaTeX to number sections automatically (and write headings without embedded numbers, e.g. ## Introduction), pass --number-sections:

pandoc input.md -o output.pdf \
  --pdf-engine=xelatex \
  --template=./path/to/template_first-skyfritt-example.tex \
  --shift-heading-level-by=-1 \
  --number-sections \
  -V templatedir=./path/to/template_first-skyfritt-example.tex

You can also control the depth of numbering with the secnumdepth metadata variable:

---
title: "My Document"
secnumdepth: 2   # number sections and subsections only
---

Fonts used

Role Font Source
Main text Roboto https://fonts.google.com/specimen/Roboto
Monospace Roboto Mono https://fonts.google.com/specimen/Roboto+Mono

Both fonts are open source and licensed under the Apache License 2.0.


Troubleshooting

xelatex: createProcess: find_executable: failed XeLaTeX is not installed or not on your PATH. Install MacTeX or BasicTeX and open a new terminal session.

The font "Roboto" cannot be found The font is not installed. Follow step 6 above.

File 'titlesec.sty' not found A required LaTeX package is missing. Run the tlmgr install command in step 4.

No counter 'none' defined A known pandoc + longtable bug. The template includes a fix for this — make sure you are using the latest version of template_first-skyfritt-example.tex.

fc-list: command not found fontconfig is not installed. Run brew install fontconfig.