15

What I want to do is to shorten this \newcommand with a \foreach since this is just a very little part of what I will use.

\newcommand{\CC}{{\mathbb C}} % the set of complex numbers
\newcommand{\NN}{{\mathbb N}} % the set of natural numbers
\newcommand{\QQ}{{\mathbb Q}} % the set of rational numbers
\newcommand{\ZZ}{{\mathbb Z}} % the set of integer numbers
\newcommand{\DD}{{\mathbb D}} % the unit disk
\newcommand{\RR}{{\mathbb R}} % the set of real numbers
\newcommand{\TT}{{\mathbb T}} % the unit circle (the one dimensional torus)

I tried this but it gives an error saying that command \x is already defined. Any suggestions?

\usepackage{amssymb}
\usepackage{pgffor}
\foreach \x in {C,N,Q,Z,D,R,T}
{
\newcommand{\x\x}{{\matbb{\x}}}

};
  • Hello and Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. I believe that your question is just a special instance of the following one: http://tex.stackexchange.com/questions/48/how-can-i-specify-a-long-list-of-math-operators/361#361 – yo' Oct 19 '14 at 18:43
  • tohecz needs to get off his high horse – Reinhard Neuwirth Oct 22 '14 at 00:01

2 Answers2

14

You need to expand and let LaTeX know that you mean a control sequence

\documentclass{article}
\usepackage{amssymb}
\usepackage{pgffor}
\foreach \x in {C,N,Q,Z,D,R,T}{\expandafter\xdef\csname\x\x\endcsname{\noexpand\mathbb{\x}}}
\begin{document}
\foreach \x in {C,N,Q,Z,D,R,T}{$\csname\x\x\endcsname$}
\end{document}

enter image description here

percusse
  • 157,807
  • 1
    Could you possibly explain how this works (or reference relevant documentation)? – Jollywatt Aug 16 '18 at 08:35
  • @Jollywatt (late note, also for future readers) \expandafter \xdef \csname \noexpand are all TeX primitive, refer to TeXbook/TeX by topic for documentation. – user202729 Oct 26 '22 at 05:27
13

You're better served with expl3:

\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\makeabbrev}{mmm}
 {
  \yoruk_makeabbrev:nnn { #1 } { #2 } { #3 }
 }

\cs_new_protected:Npn \yoruk_makeabbrev:nnn #1 #2 #3
 {
  \clist_map_inline:nn { #3 }
   {
    \cs_new_protected:cpn { #2 } { #1 { ##1 } }
   }
 }
\ExplSyntaxOff

\makeabbrev{\mathbb}{#1#1}{C,N,Q,Z,D,R,T}

\makeabbrev{\mathcal}{c#1}{A,B,C}

\begin{document}

$\CC\DD\TT\cA\cB\cC$

\end{document}

The first argument to \makeabbrev is the math alphabet to use, the second argument is a template where #1 stands for the current item when examining the letters in the list given as the third argument.

enter image description here

So with the first call we define \CC to stand for \mathbb{C} and so on, with the second call we define \cA, \cB and \cC to stand for \mathcal{A} and so on.


Why doesn't your attempt work? For three reasons.

  1. Each cycle in \foreach is performed in a group, so a \newcommand in it will be immediately forgotten

  2. Even if \x\x were substituted with, say, CC in the first cycle before \newcommand starts its work, \newcommand{CC} would be illegal anyway.

  3. Even if you solved the first two problems, you'd still define \newcommand{\CC}{\mathbb{\x}} because \newcommand never expands its second argument.

egreg
  • 1,121,712