76

Pandoc uses Tex as an intermediary step when generating PDF, so I thought asking this question on the Tex part of StackExchange may be the right place. If not, please let me know, and I will delete it.

How do you specify that Pandoc should use a specific header and footer when generating a PDF from Markdown?

Currently I use the following to create my doc from the command line:

pandoc -s -V geometry:margin=1in --number-sections -o doc.pdf doc.mkd

This gives a lovely result with numbered sections.

What I would like to do, is to include a header and footer on each page. How do I go about it?

The extensions mechanism, e.g. pandoc_title_block may hold the key, but how do you use it?

Lastly (as a bonus), is there some way to create a title page for a document using pandoc?

2
  • 2
    One option would be writing a new template file and including it via the --template option. You could also add all the titling code you need there.
    – DG'
    Oct 16, 2013 at 14:04
  • In case you just want something that can be compiled and don't want to manually specify your template, just use --standalone Mar 30, 2017 at 23:02

2 Answers 2

108

With pandoc 1.12.x and it’s new YAML metadata capabilities you could add all the information and all LaTeX-code you need in your markdown document like this:

---
title: Test
author: Author Name
header-includes: |
    \usepackage{fancyhdr}
    \pagestyle{fancy}
    \fancyhead[CO,CE]{This is fancy}
    \fancyfoot[CO,CE]{So is this}
    \fancyfoot[LE,RO]{\thepage}
abstract: This is a pandoc test . . . 
...

# This is a test

Lorem ipsum....

That way you don't have to modify the template, simply calling pandoc doc.md -o doc.pdf will suffice.

enter image description here


If you want more control, you can add new metadata like this:

---
title: Test
author: Author Name
header: This is fancy
footer: So is this
geometry: margin=1in
abstract: This is a pandoc test . . . 
...

# This is a test

Lorem ipsum....

To make this work, you have to modify the template (pandoc -D latex > template.latex) accordingly:

% filename: template.latex

\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$lang$,$endif$$if(papersize)$$papersize$,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$}
\usepackage[T1]{fontenc}

% -----------------------
% Using abstracts
\usepackage{abstract}

% -----------------------
% Using fancy headers and footers
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhead[CO,CE]{$header$}
\fancyfoot[CO,CE]{$footer$}
\fancyfoot[LE,RO]{\thepage}

\usepackage{lmodern}
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\usepackage{fixltx2e} % provides \textsubscript
% use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
  \usepackage[utf8]{inputenc}
$if(euro)$
  \usepackage{eurosym}
$endif$
\else % if luatex or xelatex
  \ifxetex
    \usepackage{mathspec}
    \usepackage{xltxtra,xunicode}
  \else
    \usepackage{fontspec}
  \fi
  \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
  \newcommand{\euro}{€}
$if(mainfont)$
    \setmainfont{$mainfont$}
$endif$
$if(sansfont)$
    \setsansfont{$sansfont$}
$endif$
$if(monofont)$
    \setmonofont[Mapping=tex-ansi]{$monofont$}
$endif$
$if(mathfont)$
    \setmathfont(Digits,Latin,Greek){$mathfont$}
$endif$
\fi
% use microtype if available
\IfFileExists{microtype.sty}{\usepackage{microtype}}{}
$if(geometry)$
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
$endif$
$if(natbib)$
\usepackage{natbib}
\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}
$endif$
$if(biblatex)$
\usepackage{biblatex}
$if(biblio-files)$
\bibliography{$biblio-files$}
$endif$
$endif$
$if(listings)$
\usepackage{listings}
$endif$
$if(lhs)$
\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
$endif$
$if(highlighting-macros)$
$highlighting-macros$
$endif$
$if(verbatim-in-note)$
\usepackage{fancyvrb}
$endif$
$if(tables)$
\usepackage{longtable}
$endif$
$if(graphics)$
\usepackage{graphicx}
% Redefine \includegraphics so that, unless explicit options are
% given, the image width will not exceed the width of the page.
% Images get their normal width if they fit onto the page, but
% are scaled down if they would overflow the margins.
\makeatletter
\def\ScaleIfNeeded{%
  \ifdim\Gin@nat@width>\linewidth
    \linewidth
  \else
    \Gin@nat@width
  \fi
}
\makeatother
\let\Oldincludegraphics\includegraphics
{%
 \catcode`\@=11\relax%
 \gdef\includegraphics{\@ifnextchar[{\Oldincludegraphics}{\Oldincludegraphics[width=\ScaleIfNeeded]}}%
}%
$endif$
\ifxetex
  \usepackage[setpagesize=false, % page size defined by xetex
              unicode=false, % unicode breaks when used with xetex
              xetex]{hyperref}
\else
  \usepackage[unicode=true]{hyperref}
\fi
\hypersetup{breaklinks=true,
            bookmarks=true,
            pdfauthor={$author-meta$},
            pdftitle={$title-meta$},
            colorlinks=true,
            citecolor=$if(citecolor)$$citecolor$$else$blue$endif$,
            urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,
            linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$,
            pdfborder={0 0 0}}
\urlstyle{same}  % don't use monospace font for urls
$if(links-as-notes)$
% Make links footnotes instead of hotlinks:
\renewcommand{\href}[2]{#2\footnote{\url{#1}}}
$endif$
$if(strikeout)$
\usepackage[normalem]{ulem}
% avoid problems with \sout in headers with hyperref:
\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
$endif$
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
\setlength{\emergencystretch}{3em}  % prevent overfull lines
$if(numbersections)$
\setcounter{secnumdepth}{5}
$else$
\setcounter{secnumdepth}{0}
$endif$
$if(verbatim-in-note)$
\VerbatimFootnotes % allows verbatim text in footnotes
$endif$
$if(lang)$
\ifxetex
  \usepackage{polyglossia}
  \setmainlanguage{$mainlang$}
\else
  \usepackage[$lang$]{babel}
\fi
$endif$
$for(header-includes)$
$header-includes$
$endfor$

$if(title)$
\title{$title$}
$endif$
$if(subtitle)$
\subtitle{$subtitle$}
$endif$
\author{$for(author)$$author$$sep$ \and $endfor$}
\date{$date$}

\begin{document}
$if(title)$
\maketitle
$endif$

$for(include-before)$
$include-before$

$endfor$
$if(toc)$
{
\hypersetup{linkcolor=black}
\setcounter{tocdepth}{$toc-depth$}
\tableofcontents
}
$endif$
%-----------------------------------
% Adding the abstract

$if(abstract)$
\begin{abstract}
$abstract$
\end{abstract}
$endif$

$body$

$if(natbib)$
$if(biblio-files)$
$if(biblio-title)$
$if(book-class)$
\renewcommand\bibname{$biblio-title$}
$else$
\renewcommand\refname{$biblio-title$}
$endif$
$endif$
\bibliography{$biblio-files$}

$endif$
$endif$
$if(biblatex)$
\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$

$endif$
$for(include-after)$
$include-after$

$endfor$
\end{document}

This is also the place to create a title page. As you can see, the template is nothing but a LaTeX document with some $variables$, so it should be easy to customize to your liking.

Now just call pandoc with the template option:

pandoc -s -N --template=template.latex doc.md -o doc.pdf

You can find the documentation for templates here: https://pandoc.org/MANUAL.html#templates

8
  • 1
    Thanks – I didn't know about the YAML metadata. I noticed that by adding toc: yes I can achieve the --toc command line argument. I wasn't able to recreate the --number-sections argument in the same way though, and wondered why, and if there is a way to do this?
    – Benjohn
    May 27, 2015 at 12:49
  • 1
    @Benjohn this is probably a new question . . . but try numbersections: yes. You can printout the template with pandoc -D latex to figure the variable names.
    – DG'
    May 27, 2015 at 18:16
  • 3
    tried using this in both the ways specified for pandoc v 1.18 but did not get footer or header
    – krv
    Dec 6, 2016 at 6:01
  • 1
    How can we use header-includes from the command line for LaTeX? Dec 24, 2016 at 17:24
  • 1
    You can use the option--include-in-header=FILENAME
    – DG'
    Dec 26, 2016 at 13:30
6

header-includes in a separate .yaml file

In the eternal quest to separate format from content, one can simply create a separate header-includes.yaml file:

---
header-includes: |
    \newcommand{\j}{{\text{j}}}
    \newcommand{\e}[1]{\,{\text{e}}^{#1}}
...

Then, run pandoc (preferably from a makefile) as follows:

pandoc header-includes.yaml doc.md -o doc.pdf

This has the advantage that the header-includes will always be interpreted as Pandoc Markdown, unless specified otherwise. This comes handy when the output format is in a different format. For example, LaTeX macros in the header-includes will continue to have an effect on LaTeX math, even when the output format is HTML.

pandoc header-includes.yaml doc.md -o doc.html

The argument --include-in-header=FILENAME, as suggested elsewhere in a comment, does not offer this mixed format scope. It simply copies and pastes the code in the header of the output format template.

Another great example of this behaviour is given here.

1
  • 1
    Where does the actual header text go though? Jan 15, 2021 at 20:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .