Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In following snippet I try to use TeX programming to define commands \Ab, \Bb, \Cb and so on. Strangely, I get Missing \endcsname inserted error. What is my mistake? I hadn't read TeXBook, so it is a bit of magic for me.

\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
share|improve this question
    
I think I'd have picked a variable name other than '\charcode' here: makes life a bit confusing. Your problem is that \char<number> does not expand to the letter specified by <number>. Could you give more context so we can target what you actually need: there are various 'loop over all the letters' questions on the site already. –  Joseph Wright Mar 4 '13 at 17:30
add comment

3 Answers

up vote 10 down vote accepted

\char is a non expandable instruction to typeset a character, it doesn't construct a character token usable in \csname. You want

\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

which makes

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

Note that it is really unfortunate that repeat.tex calls its macro \repeat that name is used already in the existing plain (and latex) macro \loop so loading that file breaks a lot of existing code. You could just use \loop here.

{\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
share|improve this answer
    
Thanks! It works! Will google what this all means. –  KAction Mar 4 '13 at 17:38
add comment

There are many issues in your code.

  1. \edef\letter{\char\charcode} doesn't expand anything, because \charcode is \count28 and so, together with \char, it's unexpandable; then \csname\letter b\endcsname becomes \csname\char\charcode b\endcsname which is illegal.

  2. Even if that could work, you'd need \xdef and not \gdef, or any \Ab command (assuming the \csname problem has been solved) would expand to {\bf\letter}.

Actually, it's much simpler:

\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

The output is

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.
share|improve this answer
add comment

As they are only 26 letters, a simpler minded method:

\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

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.