Jesteś w: Start / Przedsięwzięcia/Projects / TeX Pearls / 2006 Pearls / hans-hagen / bachotex2006-hans-hagen-pearl1.tex

bachotex2006-hans-hagen-pearl1.tex

TeX document icon bachotex2006-hans-hagen-pearl1.tex — TeX document, 2 KB (2472 bytes)

Zawartość pliku

%%% Hans Hagen: \lccode builds a hash table

% Wybo Dekker (NTG) asked on the TEX-NL list how to construct a macro where in
% the name a `1' would be replaced by an `A'. This involves a conversion and
% TeX does not ship with that many straightforward conversion features. His
% approach involved the \char primitive but failed for the (maybe not that
% obvious) reason that this primitive results in a character node and in
% expansions (as in an \edef) remains as it is: a reference to a specific
% character (slot) in the font used at the moment when it is applied.
%
% \Name{test}{1}{Hello}
% \Name{test}{2}{World!}
%
% \testA\ \testB % this should give: Hello World!
%
% A rather convenient way to remap characters is using the \lccode or \uccode
% primitives in combination with \lowercase or \uppercase. The following
% solution is a bit optimized in the sense that we expand the temporary
% variable before we end the group. An alternative is to define \temp globally
% and to omit the first \expandafter. Watch how we apply \lowercase to the
% whole definition; using the \lowercase inside an \edef would not work.
% Instead of using a loop an dsome calculations, we directly assign the codes.
% The 0/J case is an exception anyway.

\long\def\Name#1#2#3%
 {\bgroup
  \lccode`1=`A \lccode`6=`F
  \lccode`2=`B \lccode`7=`G
  \lccode`3=`C \lccode`8=`H
  \lccode`4=`D \lccode`9=`I
  \lccode`5=`E \lccode`0=`J
  \lowercase{\def\temp{#2}}%
  \expandafter\egroup\expandafter\def\csname#1\temp\endcsname{#3}}

\Name{test}{1}{Hello}
\Name{test}{2}{World!}

\testA\ \testB

% Of course we don't need such a remapping at all, which is demonstrated by the
% alternative posted by Piet van Oostrum at TEX-NL:

\long\def\Name#1#2#3%
 {\expandafter\def\csname #1\ifcase#2\relax\or A\or B\or C\or
    D\or E\or F\or G\or H\or I\or J\or K\fi\endcsname{#3}}

% A better variant is the following. This one takes care of the zero case:

\long\def\Name#1#2#3%
 {\expandafter\def\csname #1\ifcase#2 J\or A\or B\or C\or D\or
    E\or F\or G\or H\or I\else#2\fi\endcsname{#3}}

% The next one is even better because it also takes care of non digits:

\long\def\Name#1#2#3%
 {\expandafter\def\csname#1\ifx#20J\else\ifcase0#2\or A\or B\or
    C\or D\or E\or F\or G\or H\or I\else#2\fi\fi\endcsname{#3}}

% Now we can say:

\Name {test} {0} {zero}
\Name {test} {1} {one}
\Name {test} {x} {xxx}

\testJ \testA \testx

\end