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 !

Xoff
  • 1,691

1 Answers1

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.)

David Carlisle
  • 757,742
  • 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 '12 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= } %. – Ulrich Diez Aug 01 '21 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. – David Carlisle Aug 01 '21 at 17:57