A Question About \futurelet
The \let
and \futurelet
primitives create implicit character tokens. Thus when does
\futurelet\foo\baz a
the token \foo
is an a
. It is not a macro which expands to an a
.
One can see this by using \show
and \meaning
:
\def\baz{\edef\test{\meaning\foo}\show\foo\show\test}
\futurelet\foo\baz a
You can do anything with \foo
that doesn't require an explicit character token. For example, if we do
\let\bgroup={
we can do
\hbox\bgroup <content>
but not
\def\foo\bgroup <definition>
One can use \meaning
to disect the text, for example if we know it's a letter
\def\baz{%
\edef\test{\meaning\foo}%
\edef\test{\expandafter\bazaux\test\stop}%
\show\test
}
\edef\bazaux{\def\noexpand\bazaux\detokenize{the letter }##1\noexpand\stop{##1}}
\bazaux
\futurelet\foo\baz a
(One could of course test first for this case.)
My LaTeX colleague, Christian Tellechea, as I was asking him about the limitations of implicit character tokens, quickly shot back a macro (using the listofitems
package) that he calls \implicittomacro#1
that takes an implicit token (limited to catcode 11 or 12) and turns it into a macro.
Thus, the MWE I posted at the end of my question becomes do-able with Christian's help. In it, the macro \fltest
uses \futurelet
to capture the undigested next token, and then can test it against a multiplicity of match characters at once (here, both x
and y
). This is cooler than a mere \ifx
test, which can only compare against a single token at a time.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{listofitems}
\def\implicittomacro#1{%
\def\next{\expandafter\implicittomacroi\meaning#1\implicittomacroi#1}%
\unless\ifcat a\noexpand#1%
\unless\ifcat.\noexpand#1%
\def\next{\errmessage{\string#1\space is not catcode 11 or
12}}%
\fi
\fi
\next
}
\expandafter\def\expandafter\implicittomacroi\expandafter
#\expandafter1\detokenize{er} #2\implicittomacroi#3{%
\def\implicittomacroii##1\implicittomacroii{\endgroup\def#3{##1}}%
\begingroup\endlinechar-1\everyeof{\noexpand}%
\expandafter\implicittomacroii\scantokens{#2\implicittomacroii}%
}
\def\fltest{\futurelet\xfl\pdecide}
\def\pdecide{%
\implicittomacro\xfl%
\setsepchar{x||y}% SEARCH FOR x or y AS THE NEXT CHARACTER
\readlist\mylist{\xfl}%
\ifnum\listlen\mylist[]>1\relax%
(Following undigested token is: \mylistsep[1])%
\else
(Following undigested token is NEITHER x nor y)%
\fi
}
\begin{document}
\fltest xyz
\fltest yzx
\fltest zxy
\end{document}