Jesteś w: Start / Przedsięwzięcia/Projects / TeX Pearls / 2007 Pearls / marcin-wolinski / bachotex2007-marcin-wolinski-pearl3.tex

bachotex2007-marcin-wolinski-pearl3.tex

TeX document icon bachotex2007-marcin-wolinski-pearl3.tex — TeX document, 1 KB (1750 bytes)

Zawartość pliku

%%% Multiple expansions triggered with a single \expandafter

% This pearl (coded on October 18, 1996) is the most useless one I could think
% of. Nonetheless it is an example of a really curious expansion of macros.

% Let us imagine that we have a list of non-space tokens and we want to assign
% this list to a token register without expanding the tokens and in reversed
% order.  Here is a simple macro that reverses a list in an expand-only way:

\def\afterfi#1#2\fi{\fi#1}

\def\reverse#1{\reverseX{}#1\stopreverse}
\def\stopreverse{\noexpand\stopreverse}

\def\reverseX#1#2{\ifx\stopreverse#2%
    \afterfi{#1}%
  \else
    \afterfi{\reverseX{#2#1}}%
  \fi}

% Now we can write

\message{\reverse{abcdefg}}

% and \TeX\ will respond with writing 'gfedcba' on the terminal.

% To put the result of reversing the list 'abc\foo def\bar ghi' in
% a token register we do the following:

\toks0=\expandafter{\if0\reverse{abc\foo def\bar ghi0}}\fi
\showthe\toks0

% With the use of \expandafter we introduce a single expansion to the region
% where expansion is suppressed.  The token being expanded is the \if.  To
% expand an \if \TeX\ needs to find next two non-expandable tokens to compare
% them.  The first token is {\tt 0}, but then \TeX\ sees the macro \reverse. So
% the macro gets expanded. An interesting feature of \reverse is that no
% non-expandable tokens are emitted until the list is fully reversed. So only
% then \TeX\ stops expansion. The first non-expandable token \TeX\ will see is
% the second 0, which we have devilishly inserted at the end of the list.  At
% this point the condition turns out to be true and the next tokens get
% assigned as contents to the token register.

\end