9

The following is literally copied/pasted out of a *.tex file:

\newcommand{\bA}{\mathbf{A}}
\newcommand{\bB}{\mathbf{B}}
\newcommand{\bC}{\mathbf{C}}
\newcommand{\bD}{\mathbf{D}}
\newcommand{\bE}{\mathbf{E}}
\newcommand{\bF}{\mathbf{F}}
\newcommand{\bG}{\mathbf{G}}
\newcommand{\bH}{\mathbf{H}}
\newcommand{\bI}{\mathbf{I}}
\newcommand{\bJ}{\mathbf{J}}
\newcommand{\bK}{\mathbf{K}}
\newcommand{\bL}{\mathbf{L}}
\newcommand{\bM}{\mathbf{M}}
\newcommand{\bN}{\mathbf{N}}
\newcommand{\bO}{\mathbf{O}}
\newcommand{\bP}{\mathbf{P}}
\newcommand{\bQ}{\mathbf{Q}}
\newcommand{\bR}{\mathbf{R}}
\newcommand{\bS}{\mathbf{S}}
\newcommand{\bT}{\mathbf{T}}
\newcommand{\bU}{\mathbf{U}}
\newcommand{\bV}{\mathbf{V}}
\newcommand{\bW}{\mathbf{W}}
\newcommand{\bX}{\mathbf{X}}
\newcommand{\bY}{\mathbf{Y}}
\newcommand{\bZ}{\mathbf{Z}}

Is there a way to simplify this by using a for loop of some sort over A-Z?

Thanks!

7
  • 1
    What exactly do you intend to simplify? Is this what you're looking for: \renewcommand{\b}[1]{\mathbf{#1}}?
    – Count Zero
    Aug 6, 2012 at 21:14
  • @CountZero: edited to add: "looking for for loop"
    – user13546
    Aug 6, 2012 at 21:24
  • Looks similar to tex.stackexchange.com/questions/51353/…
    – Joseph Wright
    Aug 6, 2012 at 21:33
  • 7
    why do this? If you went \let\b\mathbf then you could use \b A so there is really no need to define 26 extra commands for this which just takes up TeX memory, and is slower. Aug 6, 2012 at 21:39
  • 1
    @DavidCarlisle: Isn't there some danger of conflicts with the approach you suggested?
    – Dror
    Aug 21, 2012 at 6:09

4 Answers 4

8
+200

Using the etoolbox package, you can do the following :

\RequirePackage{etoolbox}
\def\parser #1{\expandafter\def\csname b#1\endcsname{\mathbf{#1}}}
\forcsvlist{\parser}{A,B,C,D,E,F,G,H,I,J,K,L,M,O,P,Q,R,S,T,U,V,W,X,Y,Z}

Note that the list you give to \forcsvlist could really be anything (besides things containing commas of course).

This loops over the elements of the "comma separated values" list you give it and passes them one by one to the \parser macro which defines what you want.

The advantages of this method is that it is very compact and easily readable for the user. You can also change quite easily the operation you want to perform, the prefix or the list of strings concerned by your formatting. Also, the etoolbox will probably be loaded by another package anyway, so you don't load anything new.

The inconvenient is the same as in @DavidCarliste answer. It is quite slower for LaTeX to process. However, this effect will not show up until you have really a lot of elements to loop over.

10

As I mentioned in comments I wouldn't do this. But if I wanted to do it I'd probably do

\documentclass{article}

\makeatletter


\count@`\A
\loop
\lccode`\.\count@
\lowercase{\@namedef{b.}{\mathbf.}}%
\advance\count@\@ne
\ifnum\count@>`\Z\else
\repeat


\show\bA
\show\bC
\show\bZ

\stop
6

What you are doing there is not a recursion. Recursion means that a function (or macro in TeX for that matter) calls (i.e. expands to something containing) itself. You are simply repeating similar code and this certainly can be expressed by a loop.

Nevertheless, I don't think you gain much by this approach. Besides the \b A / \bA argument, David's code is certainly not a lot faster than your original one. Its not even significantly shorter.

I would simply put those 26 lines into a separate package. So just create a mathbfcmds.sty file (in your PATH):

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mathbfcmds}[2012/08/21]

\newcommand{\bA}{\mathbf{A}}
...

and in any TeX document you want to use it, you can do \usepackage{mathbfcmds}. This way you truly save some effort without obfuscating the code and it doesn't matter whether you add another hundred declarations of that kind.

4

You can use the pgffor package.

\documentclass{article}

\usepackage{pgffor}


\begin{document}\scrollmode


\makeatletter
\foreach \m in {A,B,C,D,E}
{
    \expandafter\protected@xdef\csname b\m\endcsname{\mathbf{\m}}
}
\makeatother

$\bA$
$\bD$
$\bC$
$\bE$
$\bB$
\end{document} 

The code simply uses a foreach to define the macros in a loop. To do this though one must properly expand the loop variable \m. It is a bit tricky because the \mathbf{\m} is hard to expand. One must use a \protected@xdef to make it work. (\xdef alone doesn't seem to work and \gdef doesn't seem to allow one to get the second \m expanded)

Note that this code blindly defines the macros which may already exist.

3
  • It is possible to write \foreach \m in {A...Z} ?
    – bodo
    Aug 21, 2012 at 7:29
  • @canaaerus No but I'm sure it would not be hard to generate a comma separated list of the alphabet. It would probably be easier to type it once and stick in in a macro somewhere and use the macro. Aug 21, 2012 at 7:40
  • 1
    @canaaerus: Yes, \foreach \m in {A,...,Z} works (note the commas). You can also use lower case letters, or a different step size ({a,c,...,z} will give a,c,e,...).
    – Jake
    Aug 21, 2012 at 9:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy