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 a previous question I asked how to generate multiple saveboxes in a loop. The answer build around csname and the part inside csname is rather long and I need the name several times (create the box, fill the box, get properties and use it). Therefore I would like to shorten this. I tried

\makeatletter
...
\@namedef{saveBox}{<what was inbetween \csname \endcsname>}
...
\expandafter\newsavebox\@nameuse{saveBox}
...
\makeatother

which is not working for me. A short background information on the inner workings/general intended use would be a bonus.


The awnser leaves me with one issue, I can't get the \def version to work with a direct version, see example for clarification:

\def\floatRow@currentSaveBox{floatRow@savebox\alph{floatRow@rowImageCount}}
%\expandafter\newsavebox\csname\floatRow@currentSaveBox\endcsname   %works
\expandafter\newsavebox\csname{}floatRow@savebox\alph{floatRow@saveboxCount}\endcsname  %gives mising number error

I assume that my separation of \commandName and the string floatRow@savebox is wrong. Here is a MWE:

\documentclass{report}
\begin{document}
\newcounter{c}
\def\currentSBox{prefix\alph{c}}
\expandafter\newsavebox\csname\currentSBox\endcsname
\expandafter\savebox\csname\currentSBox\endcsname{dummy}
\expandafter\usebox\csname\currentSBox\endcsname
\expandafter\usebox\csname{}prefix\alph{c}\endcsname
\end{document}
share|improve this question
2  
I suggest to take a look into the etoolbox package. It provides a much cleaner and more complete interface for the construction of command sequences without using kernel primitives. –  Daniel Jul 31 '13 at 22:15
    
\@nameuse{saveBox} needs two expansions to give you the name \saveBox (\expandafter\expandafter\expandafter\newsavebox\@nameuse{saveBox}) but that won't work either: \newsavebox will complain: ! LaTeX Error: Command \saveBox already defined. –  cgnieder Jul 31 '13 at 22:15
    
Maybe you can explain a bit what it really is you want to achieve? –  cgnieder Jul 31 '13 at 22:16
    
@cgnieder this is my attempt at writing code to automatically solve the issue from here: tex.stackexchange.com/q/125675/19326. For that I need a macro which generates saveboxes for every image on the row and store it there. Then I can calculate the scales needed hoepfully write them to an aux file and apply them in the next pass. This is for the first step, creating and writing stuff to saveboxes. Do you need to see the corresponding code mess (you have been warnder ;) ) or is there a general explanation for the intended use? –  ted Jul 31 '13 at 22:20
    
@cgnieder: also why does \@nameuse require two expansions? –  ted Jul 31 '13 at 22:21

1 Answer 1

up vote 6 down vote accepted

Let's look at what is happening here. The construct

\@namedef{saveBox}{<what was inbetween \csname \endcsname>}

is defining \saveBox as a macro with replacement text <what was inbetween \csname \endcsname>. That's because \@namedef is defined as

#1->\expandafter\def\csname #1\endcsname

That means that what it does is first convert #1 (saveBox in your case) into a control sequence (\saveBox here), the apply \def. So it's become the same as doing

\def\saveBox{<what was inbetween \csname \endcsname>}

This is a useful-enough thing to do, but in the current case isn't actually what you want!

The second line

\expandafter\newsavebox\@nameuse{saveBox}

is going to fail badly for several reasons, as comments already mention. \@nameuse is a wrapper around \csname ...\endcsname, and so with only one expansion you get to

\newsavebox\csname saveBox\endscsname

which tries to define \csname as a new box!. If we do two expansions we get to

\newsavebox\saveBox

which is still wrong as you've already defined \saveBox as a macro.

Based on the linked question, what you seem to want is more of the form

\def\my@name{MyString\@alph\count@}
\expandafter\newsavebox\csname\my@name\endcsname
...
\expandafter\usebox\csname\my@name\endcsname

i.e. to save the form of the name in a macro and reuse that.


You may wonder what \@nameuse is for, as it seems to make things more not less complex (\@namedef is handy). This is at least partly historical: when LaTex2e was written, tokens were very 'expensive', so the saving of \@nameuse (one token) over \csname ...\endcsname (two tokens) was worth making when you look at all of the uses in the kernel. Today, that's much less important, although there is an argument that

\def\foo#1{% Some function
  ...
  \@nameuse{my@#1}%
}

is clearer than

\def\foo#1{% Some function
  ...
  \csname my@#1\endcsname
}

as it shows up that something is being used rather than say defined by name.


Using \@namedef is more common, as it allows easy construction of 'on the fly' names. For example, we can imagine storing some user input:

\newcommand{\mycommand}[2]{%
  \@namedef{mycommand@store@#1}{#2}%
}

This might then say be used to save some user information: I'll use e-mail addresses but it could be anything

\mycommand{Joe Bloggs}{joe.blogs@some.domain}

If you have a bigger set up doing this, say storing several pieces of data about several 'keys', then using \@namedef keeps things a lot more readable than using \expandafter\def\csname .... \mycommand{A. N. Other}{another@place.com}

share|improve this answer
    
Is there a way I can make tex show me the expansions step by step? Also, can you please give an example were \@namedef is usefull? –  ted Aug 1 '13 at 8:34
    
Also, if you don't mind could you give me a hint for the updated bottom part of my question, I can't get the def version working if I want to use the "direct" approach (no def, everything inbetween the csname-part –  ted Aug 1 '13 at 8:54
    
@ted In your addition to the question, the 'direct' example uses a different counter name to the one in the \def. I suspect that one of these is simply not defined: can you check (or provide a full MWE)? –  Joseph Wright Aug 1 '13 at 9:27
    
@ted You can use the trace package to control printing of tracing information, or simply can add \tracingall for a reasonably complete listing. (The trace package prints even more info than \tracingall.) –  Joseph Wright Aug 1 '13 at 9:33
    
I added an MWE (or rather M`not`WE) in my question at the bottom. –  ted Aug 1 '13 at 10:07

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.