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.

I would like to define a number of related commands by using the counter in a for-loop.

For example, I want to define 26 commands like this:

\newcommand{\calA}{{\cal A}}
\newcommand{\calB}{{\cal B}}
...

I've been searching for a while (and have in fact learned quite a bit), but have still not found the answer. Here's my latest attempt (it uses the forloop package):

\newcounter{ct}
\forLoop{1}{26}{ct}{
    \expandafter\newcommand\expandafter%
    {\csname cal\Alph{ct}\endcsname}%
    {{\cal \Alph{ct}}}
}

All 26 commands are created, but are all defined as {\cal Z}. I guess {\cal \Alph{ct}} is only expanded after the loop has completed.

How can I accomplish my goal? And how does it work?

share|improve this question
    
There's a related question here: tex.stackexchange.com/q/48/86 (I'm pretty sure we've had an even closer one, but I can't find it right now). –  Loop Space May 23 '12 at 11:50
add comment

6 Answers

up vote 11 down vote accepted

You don't say which package you got your loop macro from. This just uses the \loop in LaTeX (originally from plain TeX)

> \calA=\long macro:
->\mathcal {A}.
l.18 \show\calA

? 
> \calZ=\long macro:
->\mathcal {Z}.
l.20 \show\calZ

produced from

\documentclass{article}

\makeatletter

\def\foo#1{%
\expandafter\newcommand\csname cal#1\endcsname{\mathcal{#1}}}

\count@=0
\loop
\advance\count@ 1
\edef\y{\@Alph\count@}%
\expandafter\foo\y
\ifnum\count@<26
\repeat



\show\calA

\show\calZ

\stop
share|improve this answer
    
I was using the forloop package. I aded this information to my question. –  mhelvens May 23 '12 at 10:38
    
Your answer seems to work fine! But I'd like to know how it works, and why my code doesn't work (this sort of code is a bit new to me). Preferably I'd like to see it done with a more LaTeXy for-loop as well, if you'd be so kind. :-) –  mhelvens May 23 '12 at 10:48
    
I've mixed your code and mine into a more LaTeXy solution, and put it down as a separate answer. Thanks! –  mhelvens May 23 '12 at 11:04
    
well I can't say much about yours as I commented you didn't provide a MWE or say where the macro came from. I may comment on mine later but have to attend to the day job for a bit:-) –  David Carlisle May 23 '12 at 11:25
add comment

Update 5 Jun 2012:

Today the LaTeX3 team changed some internal function names of the type \prg_. The function \prg_stepwise_inline:nnnn will be renamed to.

So if you use the newest version of expl3 you have to use \int_step_inline:nnnn instead of \prg_stepwise_inline:nnnn. The syntax is the same. For more details have a look at the announcement:

Deprecated functions: \prg_.. functions and x-type expansion based on \pdfstrcmp


To complete the list I want to provide a solution with expl3. Therefor you can use the function \prg_stepwise_inline:nnnn with the following syntax:

\prg_stepwise_inline:nnnn {<starting point>}
                          {<step>}
                          {<end point>}
                          {<code>}

For your request I used:

\documentclass[]{article}
\usepackage[utf8]{inputenc}
\usepackage{expl3}
\ExplSyntaxOn
\prg_stepwise_inline:nnnn {1 } { 1 } { 26 } 
 { 
 \cs_new:cpn { cal \int_to_Alph:n { #1 } } { \mathcal{ \int_to_Alph:n { #1 } } }
 }
\ExplSyntaxOff

\begin{document}

\ExplSyntaxOn
\prg_stepwise_inline:nnnn {1 } { 1 } { 26 } 
 { 
  $\use:c{ cal \int_to_Alph:n { #1 } }$
 }
\ExplSyntaxOff
\end{document} 

enter image description here

share|improve this answer
add comment

Aha, no TikZ related answers! Unacceptable....

You can also use the pgffor module of the PGF/TikZ package externally. This also gives you a chance to iterate over letters directly. I have used the ensuremath to use it directly but you can remove that and the corresponding \noexpand. See When not to use \ensuremath for math macro? for more info on that.

\documentclass{article}
\usepackage{pgffor}
\foreach \x in {A,...,Z}{%
\expandafter\xdef\csname cal\x\endcsname{\noexpand\ensuremath{\noexpand\mathcal{\x}}}
}
\begin{document}
\calP\calG\calF / \calT\calI\calK\calZ
\end{document}

enter image description here

I fear that I'll have a tattoo out of this in the end.

EDIT Provided by Andrew Stacey

A XeLaTeX solution with even fancier calligraphy and correct capitalization

\documentclass{article}
\usepackage{unicode-math}
\setmathfont{xits-math.otf}
\usepackage{pgffor}
\AtBeginDocument{
\foreach \x in {A,...,Z}{%
\expandafter\xdef\csname cal\x\endcsname{\noexpand\ensuremath{\csname mscr\x\endcsname}}
}
\foreach \x in {a,...,z}{%
\expandafter\xdef\csname cal\x\endcsname{\noexpand\ensuremath{\csname mscr\x\endcsname}}
}
}
\begin{document}
\calP\calG\calF / \calT\cali\calK\calZ
\end{document}

enter image description here

share|improve this answer
    
I like the simplicity of that syntax. But I'm getting errors. I ran your exact code, and got a lot of ! Missing number, treated as zero. –  mhelvens May 23 '12 at 12:07
    
That's interesting I can compile without any problems. You can add \listfiles in your preanble and check the version of PGF/TikZ package components in the log messages. I have 2.10. –  percusse May 23 '12 at 12:10
    
v2.00 here. I guess that must be it? I'll try and find a newer version. –  mhelvens May 23 '12 at 12:12
    
It seems to be more tricky than a single .sty file. In the end I think I'll stick with the \forLoop solution. It works, and seems to be more widely supported. Thanks! –  mhelvens May 23 '12 at 12:20
    
What I meant was that the forloop package is installed in TexLive, which all my colleagues use. Apparently that particular version of pgffor is not. –  mhelvens May 23 '12 at 12:31
show 1 more comment

Based on the answer of David Carlisle, I've altered my own solution as follows:

\newcommand{\defcal} [1]{\expandafter\newcommand\csname cal#1\endcsname{{\cal #1}}}
\newcounter{ct}
\forLoop{1}{26}{ct}{
    \edef\letter{\Alph{ct}}
    \expandafter\defcal\letter
}

The trick seems to be to create the \defcal command, then use \edef, as well as \expandafter, so its argument is expanded first.

share|improve this answer
2  
Please, don't use the deprecated syntax {\cal A}, but rather \mathcal{A}. –  egreg Jun 5 '12 at 20:27
add comment

The forloop package defines two commands \forloop (preferred usage) and \forLoop (deprecated).

The definition of forloop is

\forloop[⟨step⟩]{⟨counter⟩}{⟨initial value⟩}{⟨condition⟩}{⟨code⟩}

But it's not the problem here. Your problem comes from the expansion of \Alph{ct}. A lot of answers are fine, here I use something like percusse and you can see you can use \forloop instead of \foreach

But I disagree with :

They're a bit more readable, and the forloop package does seem widely

because if you compare percusse's answer with my answer, I don't see what is more readable. Now in this case, I think it's better to do like David and to avoid \forloop

\documentclass[]{article}
\usepackage[utf8]{inputenc}
\usepackage{forloop}
\makeatletter 
\let\FOR\@for
\let\NAMEUSE\@nameuse   
\makeatother

\begin{document}

\newcounter{ct} 
\forloop{ct}{1}{\value{ct} < 27}{%
\expandafter\xdef\csname cal\Alph{ct}\endcsname{%
\noexpand\ensuremath{\noexpand\mathcal{\Alph{ct}}}}
}

\FOR\letter:={A,L,T,E,R,M,U,N,D,U,S}\do{% 
\NAMEUSE{cal\letter}}

\end{document} 

Pub !

enter image description here

share|improve this answer
add comment

These types of constructs are better done, either through LaTeX2e, kernel commands and constructs, hard core TeX or with a package such as etoolbox (or LaTeX3).

In this case I would prefer the following approach.

Firstly define a command that will define the other commands. Let us call it \commandfactory.

  \def\commandfactory#1{%
     \expandafter\def\csname cal#1\endcsname{\mathcal{#1}}}

We will need a new counter to keep track of the iteration and to provide the "letters" for the command.

   \newcounter{ctr}

The easiest looping structure in this case will be Knuth's \loop..\repeat construct. Finally, the MWE.

\documentclass{article}
\makeatletter

\def\commandfactory#1{%
   \expandafter\def\csname cal#1\endcsname{\mathcal{#1}}}

\newcounter{ctr}
\loop
  \stepcounter{ctr}
  \edef\X{\@Alph\c@ctr}%
  \expandafter\commandfactory\X
\ifnum\thectr<26
\repeat

\begin{document}
\setcounter{ctr}{0}
\loop
  \stepcounter{ctr}
   $\@nameuse{cal\@Alph\c@ctr}$, 
\ifnum\thectr<26
\repeat

\end{document}

Why I normally prefer such approach is that it uses constructs that are very common in packages and the kernel (i.e, you use common paradigms) and is easy to find information. People sometimes object to hybrid TeX/LaTeX commands, but hey, the important thing is for your code to work.

share|improve this answer
    
Thanks for your answer. It seems to be the same as David's answer. :-) It was quite helpful, but I do tend to prefer the somewhat higher-level constructs. They're a bit more readable, and the forloop package does seem widely supported. –  mhelvens May 23 '12 at 11:12
    
@mhelvens They are very similar, i just prefer not to use \count@1, advance etc. Wanted to illustrate a reasonable hybrid and I didn't like \expandafter\newcommand. –  Yiannis Lazarides May 23 '12 at 18:30
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.