Within command definition peek at next command
The underlying TeX primitive to peek ahead is \futurelet
but that would not skip spaces, LaTeX wraps this in a space skipping loop as \@ifnextchar
which does a \ifx
test that the token is equal to the specified token so despite its name implying a "char" test, it can be used to test for any token.
For the particular case of \cmd
the space skipping is not needed, as no space tokens are made after a command name but if \cmd
took arguments and you needed to peek after \cmd{x}
then this \@futurelet
version comes in useful as it would skip spaces after the }
.
\documentclass{article}
\makeatletter
\newcommand{\cmd}{\@ifnextchar\nofoobar{\@gobble}{foobar}}
\makeatother
\newcommand{\nofoobar}{nofoobar}
\begin{document}
\cmd this should say foobar% prints foobar
\cmd\nofoobar this should not say foobar % does not print foobar
\cmd \nofoobar ideally this should also not say foobar % that is, spaces should be ignored
\end{document}
expl3
has a very powerful mechanism for peeking at the next token; you can optionally remove the next token or ignore spaces (or do both actions).
In this case you can use a function of the \peek_meaning
family:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\cmd}{}
{
\peek_meaning_remove:NF \nofoobar {foobar}
}
\quark_new:N \nofoobar
\ExplSyntaxOff
\begin{document}
\cmd (this should say foobar)% prints foobar
\cmd\hfill (this should say foobar)% prints foobar
\cmd\nofoobar (this should not say foobar) % does not print foobar
\cmd \nofoobar (ideally this should also not say foobar) % that is, spaces should be ignored
\end{document}
Here ignoring spaces is irrelevant because there is none in \cmd \nofoobar
, but there's also
\peek_meaning_remove_ignore_spaces:NF
and of course you can have the NTF
and NT
forms for specifying, respectively, different actions in the true and false cases or just an action for the true case.