Tip: Check for Pandoc in LaTeX

Marvin Gülker · 20.06.2021

It is possible to check in a LaTeX document whether it is being processed by Pandoc.

Kategorien: LaTeX, Software

Occasionally it is necessary to check within a LaTeX document whether it is being processed by an “ordinary” LaTeX processor like pdflatex or lualatex or by Pandoc. This is not easy, because Pandoc does not provide an identifying macro which one could check for from within the LaTeX document. There however exists a possibility that uses LaTeX booleans, which only recently gained support by Pandoc and which is be outlined below.

Abstract idea

The idea is to have Pandoc process a preparatory document immediately before the actual main LaTeX document. This preparatory document defines a LaTeX boolean, which can then be queried in the main document. In order to have the main document still be processable by ordinary LaTeX (and not crash due to an undefined boolean) it is necessary to define this boolean (negatively) in the main document as well. Since that would normally cause Pandoc to also (re)define the boolean negatively, it is necessary to construct this in such a way that it is only executed by LaTeX. For this, one can leverage \providecommand. This slightly less known LaTeX command defines a command only if it has not yet been defined. Whether Pandoc simply ignores this command (because it does not know about which commands are defined or not) or whether it executes it correctly I cannot say, but it yields the desired effect: if the preparatory document defines the command, it will not be redefined by the definition in the main document.

Practical application

These rather abstract thoughts can be implemented as follows. First, the preparatory document pandoc-pre.tex is created, which will only be given to Pandoc later on, not to LaTeX:

\newcommand\defpandocbool{
  \newif\ifrunsinpandoc
  \runsinpandoctrue}

This defines the new command \defpandocbool, but does not execute it yet. Once executed, it will create a new LaTeX boolean called runsinpandoc and set that one to true. LaTeX’s syntax for creating new booleans with \newif is slightly irritating (and probably the reason why the ifthen package was created), but explanations can be found online.

The main document should then have the following in the preamble:

\providecommand\defpandocbool{
  \newif\ifrunsinpandoc
  \runsinpandocfalse}
\defpandocbool{}

Since a “normal” LaTeX run without Pandoc does not have \defpandocbool available, it will be initially defined by \providecommand. When Pandoc runs, however, the command exists and will not be redefined (or Pandoc ignores \providecommand, which has the same result). This definition sets the boolean to false. \defpandocbool is then immediately called. If LaTeX runs, the runsinpandoc boolean thus is false, if Pandoc runs, it is true.

With this established, it is only required to check the boolean whenever the document should behave differently depending on the processor. This is achieved by the following construct:

\ifrunsinpandoc
Executed with Pandoc
\else
Executed with normal \LaTeX{}.
\fi

Thus, the main document might look as follows:

\documentclass[a4paper,english,11pt]{scrartcl}
\usepackage{babel}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\providecommand\defpandocbool{
  \newif\ifrunsinpandoc
  \runsinpandocfalse}
\defpandocbool{}

\begin{document}
\title{Test}
\author{John Doe}
\date{\today}
\maketitle{}

This will always be included.

\ifrunsinpandoc
The document was processed by Pandoc.
\else
The document was processed by ordinary \LaTeX{}.
\fi

\end{document}

The document may then processed either by LaTeX:

$ pdflatex test.tex

Or by Pandoc, in which case it is important to give pandoc-pre.tex as the first file to process:

$ pandoc pandoc-pre.tex test.tex -o result.html

Result

It might be slightly complicated, but it is possible without resorting to external tools like M4 to check whether the current LaTeX document is processed by Pandoc or not.