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.

Is there a way to add an index to a command? For example:

\newcounter{count}
\loop<condition>
  \def\var\Roman{count}{some data}
\repeat

The \var\Roman{count} should become the variable \varI, \varII, \varIII and so on.

Background: I need to get some data from external files and store it into variables (which I will later use to create a document). Normally every \varI should be the same as every \varII, but I need to check whether it really is the case or not. If not I should return a warning or error.


Solution for the first problem is in the comments, but I have a second problem.

Suppose I wrote this:

\newcommand\addindex[3]{  % #1 as name of var, #2 as index and #3 as content
  \expandafter\def\csname #1\Roman{#2}\endcsname{#3}  % thanks to egreg
}

\newcounter{count}
\loop\unless\ifnum\value{count}=5
  \stepcounter{count}
  \addindex{var}{count}{\arabic{count}}
\repeat

All \var<index> have now as value 5, because they are defined as \arabic{count}, and not their value at the moment. Adding \expandafter before \arabic{count} does not seem to work for some reason...

share|improve this question
2  
\@namedef{var\romannumeral\c@count}{some data} –  David Carlisle Jul 20 '12 at 11:59
1  
Or \expandafter\def\csname var\Roman{count}\endcsname{...} –  egreg Jul 20 '12 at 12:50
    
Thanks again egreg, I'm starting to like you :p @DavidCarlisle: thanks, but in that way I have to use TeX counters instead of LaTeX counters. I prefer the LaTeX way :) –  Didii Jul 20 '12 at 13:12
    
Also, is there a way to read them again using another loop? I can't seem to find out how for the moment... –  Didii Jul 20 '12 at 13:12
    
Figured it out, I could just use the \csname environment again :) –  Didii Jul 20 '12 at 13:23

1 Answer 1

up vote 6 down vote accepted

The method is quite simple, but I add a trick that can be useful in your application:

\newcounter{tempcount} % for temporary usage

\newcommand\addindex[4][]{% #2 as name of var, #3 as index and #4 as content
  \csname#1def\expandafter\endcsname\csname #2\Roman{#3}\endcsname{#4}%
}

Now we want to define \varI, \varII, \varIII and \varIV to expand to some text:

\setcounter{tempcount}{0}

\loop\ifnum\value{tempcount}<4
  \stepcounter{tempcount}
  \addindex{var}{tempcount}{some text}
\repeat

If instead you want that \varI expands to 1 and so on, here's the role of the optional argument:

\setcounter{tempcount}{0}

\loop\ifnum\value{tempcount}<4
  \stepcounter{tempcount}
  \addindex[e]{var}{tempcount}{\arabic{tempcount}}
\repeat

By passing e as the optional argument, what's executed is \csname edef\endcsname, that is \edef that expands completely the replacement text before doing the definition. With no optional argument only \def is used.

A more efficient definition would be of \vari, \varii and so on (with lowercase roman numbers):

\newcommand\addindex[4][]{% #2 as name of var, #3 as index and #4 as content
  \csname#1def\expandafter\endcsname\csname #2\roman{#3}\endcsname{#4}%
}

It's more efficient because \Roman{tempcount} has to scan each character in the expansion of \roman{tempcount} and change it to its uppercase counterpart, while \roman{tempcount} expands to \romannumeral\c@tempcount using the TeX primitive \romannumeral, which is quite fast.

share|improve this answer
    
Why is the \expandafter needed? I'm currently searching what it exactly does, but can't seem to find it easily.. –  Didii Jul 23 '12 at 9:54
1  
The \expandafter last before \endcsname is necessary so that the following \csname is processed before TeX forms the token \def or \edef. So when the counter's value is 1, for instance, what TeX will see is \def\varI. Without the \expandafter it would see \def\csname varI\endcsname which is wrong. –  egreg Jul 23 '12 at 10:55
    
I finally found a question which answers that :). Thanks. –  Didii Jul 24 '12 at 9:06

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.