\csname 循环定义时出错

\csname 循环定义时出错

在下面的代码片段中,我尝试使用 TeX 编程来定义命令、\Ab等等。奇怪的是,我得到了错误。我犯了什么错误?我没有读过 TeXBook,所以这对我来说有点神奇。\Bb\CbMissing \endcsname inserted

\input repeat.tex

\repeat\for{charcode}\from{`A}\by{1}\to{`Z}\do{%
  \edef\letter{\char\charcode}
  \expandafter\gdef\csname\letter b\endcsname{{\bf \letter}}
}

\bye

答案1

\char是用于排版字符的不可扩展指令,它不会构造可用的字符标记\csname。你想要

\input repeat.tex

\repeat\for{xcharcode}\from{`A}\by{1}\to{`Z}\do{%
  \begingroup\lccode`\a\xcharcode\relax
  \lowercase{\endgroup
  \expandafter\xdef\csname a}b\endcsname{{\noexpand\bf \char\the\xcharcode\space}%
}}

\show\Qb

\bye

这使得

> \Qb=macro:
->{\bf \char 81 }.

repeat.tex请注意,调用其宏时,\repeat该名称已在现有普通(和乳胶)宏中使用,这确实很不幸,\loop因此加载该文件会破坏许多现有代码。您可以\loop在这里使用。

{\count0=`A
\loop
 \begingroup\lccode`\a\count0\relax
  \lowercase{\endgroup
  \expandafter\xdef\csname a}b\endcsname{{\noexpand\bf \char\the\count0 \space}}
 \ifnum\count0<`Z
 \advance\count0 1
 \repeat
}
\show\Qb

\bye

答案2

您的代码中存在很多问题。

  1. \edef\letter{\char\charcode}不会扩展任何内容,因为\charcode\count28,所以,和一起\char,它是不可扩展的;然后\csname\letter b\endcsname变成\csname\char\charcode b\endcsname,这是非法的。

  2. 即使那样可行,您也需要\xdef而不是\gdef,或者任何\Ab命令(假设\csname问题已解决)都会扩展为{\bf\letter}

事实上,它简单得多:

\input repeat.tex
\let\eijkhoutrepeat\repeat
\let\repeat\fi % restore the original meaning    

\eijkhoutrepeat\for{tmpcount}\from{`A}\by{1}\to{`Z}\do{%
  \begingroup\lccode`A\tmpcount
  \lowercase{\endgroup\expandafter\def\csname Ab\endcsname{{\bf A}}}
}
\show\Ab
\show\Zb    
\bye

输出为

This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012)
 restricted \write18 enabled.
entering extended mode
(./rep.tex (/usr/local/texlive/2012/texmf-dist/tex/generic/eijkhout/repeat.tex
Loading loop macro, version 0.93a)
> \Ab=macro:
->{\bf A}.
l.7 \show\Ab

? 
> \Zb=macro:
->{\bf Z}.
l.8 \show\Zb

? 
 )
No pages of output.

答案3

因为它们只有 26 个字母,所以有一个更简单的方法:

\def\definethem #1{\ifx #1\stop\else
                     \expandafter\def\csname #1b\endcsname{{\bf #1}}%
                     \expandafter\definethem\fi}

\definethem ABCDEFGHIJKLMNOPQRSTUVWXYZ\stop


\csname Ab\endcsname % or \Ab, by why should I make things simple?
\csname Bb\endcsname
\csname Cb\endcsname

\bye

ABC

相关内容