Jesteś w: Start / Przedsięwzięcia/Projects / TeX Pearls / 2009 Pearls / stephen-hicks / bachotex2009-stephen-hicks-pearl1.tex


TeX document icon bachotex2009-stephen-hicks-pearl1.tex — TeX document, 2 KB (2248 bytes)

Zawartość pliku

%%% inlinedef: a general recursive token scanner with callbacks

% There have been several discussions about uses of \expandafter
% that border on the ridiculous, with as many as fifteen in a row
% found in actual TeX input files!  Additionally, trying to expand
% past macro parameters #1 causes problems because there is no
% guarantee that #1 is a single token.  It would instead be nice
% to insert something right before a single token we want to expand
% far in advance.  A slightly more general problem is to scan tokens
% in the input stream while preserving spaces and grouping.


  \ifcat\noexpand\foo\space \let\next\dospace\fi
  \ifcat\noexpand\foo\bgroup \let\next\trygroup\fi
  \ifcat\noexpand\foo\relax \try{&\meaning\foo}\fi
\def\try#1{\ifcsname #1\endcsname\xa\let\xa\next\csname #1\endcsname\fi}
\def\dospace{\toks0\xa{\the\toks\xa0 \space}\xa\scan\unspace}
\long\def\normal#1{\toks0\xa{\the\toks0 #1}\scan}


% We can set up a few callbacks, e.g. \END to end scanning, and
% \EXPAND to expand the next token:


% And now we can get arbitrary tokens from the input stream into \toks0
% using

\scan foo {bar \EXPAND\baz} \baz \END
\message{\the\toks0} % foo\space {bar\space !}\space \baz

% This can be made more general in several ways: if we don't check
% \ifcat\noexpand\foo\relax then we can execute callbacks on arbitrary
% tokens, including spaces and grouping symbols.  Of course this slows
% things down quite a bit further, which brings me to the main
% disadvantage with this approach: it takes about 25 times as long
% than a simple string of \expandafter's, and is therefore not
% suitable for inner loops.  But the code it allows us to write, as
% long as efficiency isn't important, is much more readable.