6

I am trying to write a macro creting automatically a certain number of saveboxes. Therefore I would like to use the concatination of the value of a string and a counter to name the saveboxes. I tried the following and latex complains "Missing Contorl sequence inserted" every time I try to use it.

\newcounter{saveboxCount}
\newsavebox{MyString\alpha{saveboxCount}}
ted
  • 3,377
  • 1
    The main problem with your use of \newsavebox is that it requires a control sequence rather than just a string. Hence the use of \csname ...\endcsname to construct the control sequence. – Werner Jul 31 '13 at 20:32
  • @Werner: I noticed that for newsavebox it works if I add the backslash \, however I have issues with actually using the box later. – ted Jul 31 '13 at 20:36

2 Answers2

8

The following will create saveboxes \MyStringa to \MyStringz:

\makeatletter
\count@=0
\loop\ifnum\count@<26
  \advance\count@\@ne
  \expandafter\newsavebox\csname MyString\@alph\count@\endcsname
\repeat
\makeatother

It's also simple (even simpler) with expl3:

\usepackage{expl3}

\ExplSyntaxOn

% loop from 1 to 26, #1 denotes the current value in the cycle
\int_step_inline:nn { 26 }
 {
  \exp_args:Nc \newsavebox { MyString \int_to_alph:n { #1 } }
 }

\ExplSyntaxOff

With \exp_args:Nc we jump over \newsavebox and form a control sequence token from the braced argument before \newsavebox is actually performed.

In the log file we'll find something like

\MyStringa=\box46
\MyStringb=\box47
\MyStringc=\box48
[...similar lines...]
\MyStringy=\box70
\MyStringz=\box71

confirming that the allocations have been performed.

egreg
  • 1,121,712
  • why are you using \count@ instead of newcounter? Also any idea why I am seeing errors for \newcommand{\floatRow@resetList}? – ted Jul 31 '13 at 20:29
  • @ted: Is \floatRow@resetList already defined? – Werner Jul 31 '13 at 20:30
  • @Werner: no. I have no idea how to write a package but thought I found something I could work on, and wanted a namespace of my own, e.g. \floatRow@ (I think i should go for something else due to the package of that name), but for simplicity I started with just one tex file, so it is in my main document. – ted Jul 31 '13 at 20:34
  • @egreg: I did some research, you use a tex counter, while this article explained the reasons, I do not understand what @ translates to since count expects a number after all I know. WOuld you enlighten me on its meaning in the conjunction with count? – ted Jul 31 '13 at 21:00
  • @ is just part of the counter name that @egreg is using. In the context of \makeatletter the @ is treated just like any other letter of the alphabet – A.Ellett Jul 31 '13 at 21:15
  • @A.Ellett: I thought counters must be named by numbers, but aparently that is wrong?. – ted Jul 31 '13 at 21:39
  • @Werner: Turned out the @nameing issue came from an accidential inversion of makeatletter/makeatother, therefore I removed it from the question but since I can't edit my comments anymore I will leave it here. – ted Jul 31 '13 at 21:48
  • @ted \count@ is to be considered a scratch count register, for temporary usage. The @ is part of the name, since we're under \makeatletter. You can use \@tempcnta or \@tempcntb for the same purpose. – egreg Jul 31 '13 at 22:00
  • @egreg where can I find a good overview of special register names and special shortcuts (I assume \@ne is a shortcut for 1\relax? – ted Aug 01 '13 at 10:31
  • @ted \@ne comes from \chardef\@ne=1. All these registers and constants are explained in source2e.pdf – egreg Aug 01 '13 at 19:44
2

With xsavebox, boxes don't need to be declared but are created on the fly, and they are addressed by name, rather than by command:

\documentclass{article}

\usepackage{xsavebox}
\usepackage{pgffor}

\begin{document}

\noindent\foreach \idx in {a,b,...,z} {%
  \xsbox{myString \idx}{That's what I saved: \idx}%
}%
%
\foreach \idx in {a,b,...,z} {%
  \noindent\xusebox{myString \idx}\par
}

\end{document}

Pkg xsavebox allocates 2 TeX box registers in total:

\l_xsb_box=\box45
\l_xsb_raw_box=\box46
AlexG
  • 54,894