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 pagecurrfile— resolves the template's directory at compile time, used to locate the logo filefilehook— required bycurrfile
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.