# How to pass a control-sequence as an argument to a macro that expects whitespace after the argument?

Consider the following macro definition:

\def\mac#1 .{}


Is there a way to pass \mac a control-sequence as an argument? I don't see how it can be done, because the TeX scanner will "swallow" all whitespace after the control-sequence, and the TeX "core" won't be aware that there once was whitespace there.

For instance, the following attempt:

\def\mac#1 .{}%
\mac\relax .%
\bye


results in the error message:

Runaway argument?
\relax .
! Forbidden control sequence found while scanning use of \mac.
<inserted text>
\par
<to be read again>
\bye
l.3 \bye


You can surround the argument by braces. Those braces will not become part of the argument:

\def\mac#1 .{\message{[[#1]]}}%
\mac{\relax} .%
\bye


Applying an empty group {} after the macro will allow the subsequent space to be recognized.

\documentclass{article}
\def\mac#1 .{\detokenize\expandafter{#1}}
\begin{document}
\mac\relax{} .
\end{document}


As Harald notes, the empty group will, however, be part of the argument here.

Here's a way to avoid the empty group

\documentclass{article}
\usepackage[T1]{fontenc}
\def\mac#1 .{\detokenize\expandafter{#1}}
\begin{document}
\expandafter\mac\expandafter\relax\space.
\end{document}


• What is \mac's argument? – Evan Aad Aug 20 '17 at 16:06
• Won't that include the braces in the argument? I think \mac{\relax} . is the correct answer. – Harald Hanche-Olsen Aug 20 '17 at 16:07
• @EvanAad Oops. I wasn't thinking of the argument (I revised) – Steven B. Segletes Aug 20 '17 at 16:09
• @HaraldHanche-Olsen My mistake. I have revised. But yes, the empty braces will be included in the argument. – Steven B. Segletes Aug 20 '17 at 16:09
• @EvanAad The essense of this answer depends in no way on LaTeX. – Harald Hanche-Olsen Aug 20 '17 at 17:09

You have to tokenize in the correct order, for example

\def\mac#1 .{}%
\long\def\firstofone#1{#1}
\firstofone{\mac\relax} .%
\bye