1

Is there something analogous to the assert command offered by various programming languages to assert certain conditions?

In particular I am looking for a way to outfit my .tex files with assertions about the engine used (e.g. LuaLaTeX or PDFLaTeX). I know I can use ifluatex to check for it being used, but that still requires me to use a rather verbose notation of what I want (besides, I still haven't figured out how to throw an error and show a message of my choice).

So just to clarify: I am looking for a primitive like assert that will cause an error if the assertion isn't satisfied and will not do anything otherwise. The only other question regarding assertions which I could find was this one, but the answers dodge that and instead provide solutions tailored to the question. I am looking for a generic way to assert certain conditions, though.

  • 2
    The ifxetex package offers \RequireXeTeX which raises an error. Unfortunately ifluatex doesn't seem to have a counterpart. – Henri Menke Feb 23 '19 at 22:16

2 Answers2

4

The usual way to detect LuaTeX is to check for the \directlua primitive before loading the documentclass or packages. To raise an error use \errmessage. After the error, I call \@@end to terminate the LaTeX run and prevent the user from continuing by just pressing enter.

\ifdefined\directlua\else
  \errmessage{LuaTeX is required to typeset this document}
  \csname @@end\expandafter\endcsname
\fi
\documentclass{article}
\begin{document}
Hello
\end{document}
$ pdflatex test.tex 
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2018-12-01>
! LuaTeX is required to typeset this document.
l.2 ...uaTeX is required to typeset this document}

? 
 )
No pages of output.
Transcript written on test.log.
Henri Menke
  • 109,596
2

You can make a file called assert.tex like

\RequirePackage{ifxetex,ifluatex}

\makeatletter
\newif\if@assert
\newcommand\assert[1]{%
  \@asserttrue
  \csname assert@#1\endcsname
  \if@assert\else
    \@latex@error{Assert failed: #1}{This document requires #1}%
    \expandafter\@@end
  \fi
}
\@onlypreamble\assert

\newcommand{\def@assert}[2]{\@namedef{assert@#1}{#2}}

\def@assert{xetex}{\ifxetex\else\@assertfalse\fi}
\def@assert{luatex}{\ifluatex\else\@assertfalse\fi}
\def@assert{a4paper}{%
  \ifdim\paperheight=297mm
    \ifdim\paperwidth=210mm
    \else
      \@assertfalse
    \fi
  \else
    \@assertfalse
  \fi
}

\makeatother

and put it in a location searched by TeX engines. I added three assertions by way of example.

If your file has the form

\input{assert}

\documentclass{article}

\assert{luatex}
\assert{a4paper}

\begin{document}

Hello world!

\end{document}

then processing it with pdflatex or xelatex would stop with

! LaTeX Error: Assert failed: luatex.

Processing it with lualatex will stop with

! LaTeX Error: Assert failed: a4paper.

Adding a4paper to the document class options will make the document compilable with lualatex.

This doesn't check for the argument to be a valid assertion; an unknown one will be treated as if it is satisfied.

egreg
  • 1,121,712
  • Thanks, and if I understand it correctly, this still will not allow you to check an arbitrary condition without adjusting assert.tex, right? – 0xC0000022L Feb 24 '19 at 21:51
  • 1
    @0xC0000022L Yes, you have to code anything you need to assert. The package iftex codes some for engines, but otherwise this is virgin territory. – egreg Feb 24 '19 at 21:53