For my template I want to create possibility to define a number of authors and automatically create a respective number of variables/commands which save the name of any author and make it able to print them later. The code has to be in the preamble.
For creating different variables/commands of the kind \varname{...} which can be printed with \printvarname, I, rather randomly, found the following code here on tex.SE which works fine:
\makealetter
\newcommand{\NewVariable}[1]{%
\expandafter\newcommand\csname #1\endcsname[1]{\@namedef{@#1}{##1}}
\@namedef{@#1}{}
\expandafter\newcommand\csname print#1\endcsname{%
\ifthenelse{\equal{\csname @#1\endcsname}{}}{}{\csname @#1\endcsname}}
}
\makeatother
Now I want to create a loop which automatically creates a predefined number of these commands of the syntax \authorone, \authortwo etc. For the definition of the numbers of authors I use a simple command: \newcommand{\setauthors}[1]{\def\numauthors{#1}}. One problem seems to be that a commandname can't take integers, but i need integers to define the number of authors. So i use the fmtcount package to convert them into words.
I tried different approaches from this website (foreach, @for, xintFor), but couldn't get one to work properly.
Here is a MWE with some approaches. I commented my test loops and added a simple example how it should be used:
\documentclass[%
]{article}
\usepackage[T1]{fontenc}
\usepackage{ifthen}
\makeatletter % command to set multiple persistent variables with content
\newcommand{\NewVariable}[1]{%
\expandafter\newcommand\csname #1\endcsname[1]{@namedef{@#1}{##1}}
@namedef{@#1}{}
\expandafter\newcommand\csname print#1\endcsname{%
\ifthenelse{\equal{\csname @#1\endcsname}{}}{}{\csname @#1\endcsname}}
}
\makeatother
\usepackage{pgffor}
\usepackage{fmtcount} % to convert integers in words: e.g. 1 into one
\usepackage{xinttools}
\newcommand{\setauthors}[1]{\def\numauthors{#1}}
\setauthors{3} %set number of authors
%\foreach \x in {1,...,\numauthors}{%
% \NewVariable{author\numberstringnum{\x}}
% }
%\xintFor #1 in {\xintSeq{1}{\numauthors}} \do {\NewVariable{author\numberstringnum{#1}}}
% also tried the starred version \xintFor*
%\makeatletter % I know the definition of a range from 1 to \numauthors is not correct, its just a placeholder
%@for\authorcount:1,...,\numauthors\do{\NewVariable{author\numberstringnum{\authorcount}}}
%\makeatother
\NewVariable{authorone} % example for defined variable/command and how it should work
\authorone{Jimmy Buckets}
\begin{document}
\printauthorone
\end{document}
There seem to be much more variants of loops from other packages (also expl3 versions, which I understand even less), but I would prefer a solution with a minimum on required extra packages. Nevertheless, in the end it's important that it works. The future user should only add a number to \setauthors and fill out the generated author variables. All other stuff should be automated. It may also be an option to asign the authornumber to an array first...
I guess it's an expansion problem of the nested commands (NewVariable, numberstring..., loop). Unfortunately, the expansion sequence/order still remains a sealed book for me, because it differs so much from most programming languages I'm (a little bit) used to.
EDIT
To use @Alans great answer including the orcid. The expl3 command \cs_new_protected:Nn \l_lukeflo_get_orcid:n for creating a valid Orcid works better using a pre-defined command for getting the Orcid link including the symbol:
\usepackage{orcidlink}
\newcommand{\orcidid}[1]{\orcidlink{#1}\space\href{https://orcid.org/#1}{#1}}
...
\cs_new_protected:Nn \l_lukeflo_get_orcid:n {
\tl_set:Nx \l_tmpa_tl {\seq_item:Nn \l_lukeflo_orcid_seq {#1}}
\orcidid{\l_tmpa_tl}\par
}
Otherwise, href will add an unnecessary .pdf extension to the link. See my comments below Alans answer.
I am already grateful for your help



expl3sequence or property lists would likely be a simpler implementation. – Alan Munn Jun 07 '23 at 20:51\foreachdoes every iteration in a local scope, so macro-definitions won't survive outside\foreach. – Ulrich Diez Jun 07 '23 at 21:54