3

After the question Macro for a code translator, I followed the advice of polgab and used the pgf parser module.

I was very disappointed when I reached the point of trying to parse a blank space. I tried different things and at first, I did not find something good. I read the question Parsing text letter by letter and found that was a problem for other people.

I finally found a solution, but don't understand why it works :

\documentclass{minimal}
\usepackage{pgf}
\usepgfmodule{parser}

\pgfparserdef{myparser}{initial}{the letter a}{b}
\futurelet\mystrangemacro{ }
\pgfparserdef{myparser}{initial}{\meaning\mystrangemacro}{a}
\pgfparserdef{myparser}{initial}{alignment tab character &}{\pgfparserswitch{final}}
\begin{document}
\pgfparserparse{myparser}a a aa aa a&
\end{document}

And I get as expected : bababbabbab.

But why is it working ? I tried many different things, and finally tried to use futurelet and it works ! But if I understand the definition of futurelet, my code has no sense..

Thank you for your answers !

1 Answer 1

6

Your \futurelet construction is just an inventive way of defining a command name to be \let to a blank space. LaTeX already has a token \@sptoken with same definition.

> \mystrangemacro=blank space  .
l.7 \show\mystrangemacro

? 
> \@sptoken=blank space  .
l.9 \show\@sptoken

LaTeX uses the construct

\def\:{\let\@sptoken= } \:  % this makes \@sptoken a space token

which is perhaps similarly obscure.

The reason why you have to do something is that space characters are normally skipped after command names so don't make tokens at all, and even if you succeed in making a space token the \let construction discards space tokens so that white space is optional around the optional = sign in

 \let\a  =  \b

so if you want to say

\let\mytoken = "a space character"

you have to get a space token there in a way that is not discarded.

\futurelet\mystrangemacro{ }

first \lets \mystrangemacro to the token after the brace which is the space token (clever bit there is that \futurelet really takes the next token, it does not discard space) then it executes the following tokens which are a harmless (in vertical mode) { } which does nothing leaving \mystrangemacro to be defined to be a space token. (Actually it is badly named as it is not defined to be a macro, but to be an unexpandable space token, but that's just a name.)

3
  • Thank you very much for your explanations. I did not understand why I can't find a solution with let or def. Now it is clear !
    – Xoff
    Jul 21, 2012 at 14:57
  • "LaTeX uses the construct \def\:{\let\@sptoken= } \: %" A space is not discarded but is tokenized when following something that got tokenized as a control symbol token, e.g., \:. Thus this is a nice way of getting two explicit space tokens in a row whereof only the first one is discarded by \let. As \@firstofone is defined in LaTeX I wonder why not \@firstofone{\let\@sptoken= } %. This way one wouldn't need to define \:. Or, relying on usual lccodes, \lowercase{\let\@sptoken= } %. Aug 1, 2021 at 13:01
  • 1
    @UlrichDiez I think the code is older than \@firstofone (which was added at 2e) Leslie could have use lowercase as you say, but didn't. Aug 1, 2021 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.