# How can I store variables in lists and make use of them?

This question is clearly related to How can I store variables and iterate over them?.

I'm sorry to ask such a close one, but I really don't understand the answer in plain TeX by David Carlisle.

Basically, I'd like to make a template in LaTeX, compatible with plain LaTeX/pdfLaTeX (no lua code), with as few dependencies as possible, that would allow me to get personal information this way:

\adduser{John Doe}{UK}


And output something like that:

John Doe(a), M.Dupont(b), M. Martin(b, c), Jan Jansen(d), Matti Meikäläinen(d, e)

a: UK

b: France

c: Belgium

d: Netherlands

e: Finland

I'm sure this is possible, but in plain LaTeX, this seems very difficult. Any idea?

-
The problem is that I did not understand it. I'm reading some doc about TeX right now (namely TeX by topic), but I'm lost. I'm used to C, Python, Go, GNU Octave, a bit of Fortran, but TeX, I just can't get it. The template is due tomorrow that's why I'm in a hurry, otherwise, I'd just take the time to learn it properly (and that's what I'm planning to do, but for tomorrow, it seems I'm screwed). –  Gael Feb 12 at 17:48
I tried it and it worked well... But when I try to change something, it just breaks... –  Gael Feb 12 at 17:50
Actually, I just need to understand how the code provided by David stores the values and how he gets them back... I can split the code and identify where he does that... When I read \def\xdo##1{\advance\count0 by 1 Input \the\count0 \space is: '##1'. }, I know what it does (extract the variable from the stack and display it instead of the ##1 token) but I really don't understand how which is really frustrating. –  Gael Feb 12 at 18:03
Would a full answer here therefore be a walkthrough of David's approach? If so, I guess we can get him to give one ;-) –  Joseph Wright Feb 12 at 18:04
Yes, that would be great! –  Gael Feb 12 at 18:06

Although there are some similarities with the other question, there are enough differences in the specifics that the code looks rather different. I added some comments this time:-)

\documentclass{article}

% 8bit encoded letters
\usepackage[latin1]{inputenc}

% a counter for locations
\newcounter{places}
\renewcommand\theplaces{\alph{places}}

% use @ in code
\makeatletter
% initialise the lists
\def\userplaces{}

% #1 is person #2 is comma separated list
% It is harder and against LaTeX syntax rules
% to do as suggested and to have a variable number of
% brace groups.
% add a comma if not the first
%
% add the name and the start of the list of letters
% \@gobble will eat a comma before the first
%
% loop through a comma separated list
\@for\@tmp:=#2\do{%
% If we haven't seen this country before
% increment the counter
% Add the counter and the place name to the userplaces list
\expandafter\ifx\csname place@\@tmp\endcsname\relax
\stepcounter{places}%
\protected@edef\userplaces{\userplaces\par\theplaces: \@tmp}%
\expandafter\edef\csname place@\@tmp\endcsname{\theplaces}%
\fi
% now get the letter stored for this place and add it to the list
\@tmpb}
% add the closing )
}
\makeatother

\begin{document}

\userplaces

\end{document}

-
I really need to learn TeX. Thank you David, you were really helpful. As an additional question, is there any specific reference about the TeX language that you would recommend ? –  Gael Feb 12 at 20:19
Little typo: \makeatoother -> \makeatother. (I would change it myself but I don't have the necessary privilege to make single-character edits.) –  John Wickerson Apr 18 at 9:40
@JohnWickerson thanks (thus revealing I edited the code after posting, note to self: don't do that:-) –  David Carlisle Apr 18 at 10:43

The following solution allows you to submit more than one user name when calling \adduser. It will also sort the user names and place indices.

\documentclass[12pt]{article}
\usepackage{catoptions}
\makeatletter
\newcounter{placecnt}
\def\printplaces{}
\def\printusers{\noindent\userlist\def\userlist{}}
\def\auxuserlist{}
\def\cptxappto#1#2{\protected@edef#1{#1#2}}
\def\cptalphasortcommalist#1#2{%
\begingroup
\def\sort@tempa{}%
\cptdocommalist*#1{%
\cptxappto\sort@tempa{{\unexpanded{##1}}}%
}%
\cptalphasort\sort@tempa#2%
\def#1{}%
\cptdosisolist*\sort@tempa{%
\cptxappto#1{\ifx#1\@empty\else,\fi\unexpanded{##1}}%
}%
\postgroupdef#1\endgroup
}

\begingroup
\catcode\~=13
% #1= comma separated list of persons.
% #2= comma separated list of affiliations/places.
\def\userlist{}%
\let\sav@nobreakspace~%
\let~\relax
\cptdocommalist{#1}{%
\ifcsname thisuserplaces@\detokenize{##1}\endcsname\else
\csn@edef{thisuserplaces@\detokenize{##1}}{}%
\cptxappto\auxuserlist{\ifx\auxuserlist\@empty\else,\fi##1}%
\fi
\cptdocommalist{#2}{%
\ifcsname thisplaceid@\detokenize{####1}\endcsname\else
\stepcounter{placecnt}%
\cptxappto\printplaces{%
\endgraf\noindent
\textsuperscript{\alph{placecnt}}\unskip####1%
}%
\csn@edef{thisplaceid@\detokenize{####1}}{\alph{placecnt}}%
\fi
\edef\am@tempa{\@nameuse{thisplaceid@\detokenize{####1}}}%
\edef\am@tempb{\@nameuse{thisuserplaces@\detokenize{##1}}}%
\xifinsetTF{,\am@tempa,}{,\am@tempb,}{}{%
\aftercsname\cptxappto{thisuserplaces@\detokenize{##1}}{%
\ifx\am@tempb\@empty\else,\fi\am@tempa
}%
}%
}%
}%
\cptalphasortcommalist\auxuserlist<%
\cptdocommalist*\auxuserlist{%
\edef\am@tempa{\@nameuse{thisuserplaces@\detokenize{##1}}}%
\cptalphasortcommalist\am@tempa<%
\cptxappto\userlist{%
\ifx\userlist\@empty\else, \fi
##1\unskip\textsuperscript{\am@tempa}%
}%
}%
\let~\sav@nobreakspace
\undefcs\sav@nobreakspace
}
\endgroup
\makeatother

% Note repeated entry of M. Martin for the same and different locations:
\adduser{M.~Martin, John Doe}{UK, Germany}
`