# User friendly array definition macro

I am working on a custom documentclass where there may be one or multiple authors in a document. Normally, one would simply specify \author{} and call some additional macros to set some special values, for example \email{} (a command defined in the class code).

Then, in the \maketitle macro defined in the class, I just do

{\Large\@author \texttt{<\@email>}}


This works well, but now I would like to extend the class’s functionality by letting users specify multiple authors and multiple emails (of course, their number should be the same). Here is a concept:

\documentclass{myclass}

\title{Glorious ducks}
\authors{{John Smith}{Jane Smith}{George Hastings}}
\emails{{john.smith@domain.tld}{jane.smith@domain.tld}{george.hastings@something.net}}


Then, \maketitle would contain something like this (pseudocode):

\begin{tabular}{ll}
\for \i in \len\@authors {
\@authors{i} & \@emails{i} \\
}


I do not need the syntax to be like in the example, it was just to show the concept.

One possible solution I found was using the arrayjobx package. I can supply a macro such as this in the class:

\newcommand\authors[1]{\newarray\@Authors\readarray{@Authors}{#1}}


then the user can do

\authors{John Smith & Jane Smith & George Hastings}


and \maketitle could somehow iterate over this array… but I don’t see a way in arrayjobx to get the length of the array, which renders this solution pretty much useless. I do not want to specify an array as well as it’s length as a user.

How would you solve this problem? I do not insist on using arrayjobx, a more ‘elegant’ (La)TeX solution is most welcome, if possible. Thank you.

To sum it up:

• users may either specify \author and \email to get a document with a single author
• or \authors and \emails to get a document with multiple authors that are listed in a tabular environment
• why separate \authors command rather than just allow more than one \author ? also I think it is easier for the author if you specify each email with each auther rather than two separate lists which need to match up. Mar 30 '21 at 7:41
• @DavidCarlisle good point, I thought about using \author multiple times. Your argument about including the emails with the author names is also valid, but do you mean simply like \author{John Smith <john.smith@domain.tld>}? I would like the email addresses in monospace, so this way an author would have to add that formatting themselves: \author{John Smith \texttt<john.smith@domain.tld>}
– bp99
Mar 30 '21 at 7:49
• no I just meant specify it with the author either \auther then \email as I just posted or as an optional argument \author[email]{name} Note you almost never need an indexed array syntax or an explicit loop in these things you just build up a list and execute it. Mar 30 '21 at 7:58
• Ah, how silly of me. Fair enough, that syntax is much better!
– bp99
Mar 30 '21 at 13:30

Honestly I wouldn't use such a syntax. I would prefer something like \author{xxx \and xxx \and xxx} but adding also emails would be non trivial. With your desired syntax the email list must be given in the same order as the author's list, which I find too complicated.

You can look into different classes to see how they handle things. This could be a starting point:

\documentclass{article}

\makeatletter

\newif\if@email
\@emailfalse
\def\@author{}
\def\@@author{\gdef\@@author{\\[1ex]}}

\def\maketitle{\begin{tabular}{ll}\@author\end{tabular}}

\makeatother

\author{Me Myself}
\email{me@myself.com}
\email{me.again@myself.com}

\author{Someone Else}
\email{someone@elses.mail}

\author{Yet Another}
\email{yet.another@service1.com}
\email{y.another@service2.com}

\author{Last One}
\email{last@one.mail}

\begin{document}

\maketitle

\end{document}


Or something similar without creating a new \if but redefining an \@emailsep at every call of \author

\begin{filecontents*}{myclass.cls}
\def\@author{}
\def\@authorsep{\gdef\@authorsep{\\[1ex]}}

\def\author#1{%
\@authorsep#1%
\gdef\@emailsep{&\gdef\@emailsep{\\&}}%
}%
}

\def\maketitle{%
\begin{center}
\large\bfseries\@title
\end{center}
\noindent
\begin{tabular}{@{}ll}
\@author
\end{tabular}%
}
\end{filecontents*}

\documentclass{myclass}

\title{Great Work}

\author{Me Myself}
\email{me@myself.com}
\email{me.again@myself.com}

\author{Someone Else}
\email{someone@elses.mail}

\author{Yet Another}
\email{yet.another@service1.com}
\email{y.another@service2.com}

\author{Last One}
\email{last@one.mail}

\begin{document}

\maketitle

\end{document}


• This looks fantastic, thank you! I agree that this syntax is a lot cleaner. I just thought it would be very hard to handle multiple \authors. I will see if I can decipher what this code does :-)
– bp99
Mar 30 '21 at 7:55
• +1 you just beat me to it, I nearly didn't post mine once I saw this but as i'd done it and the OP might like a couple of examples, I left it :-) Mar 30 '21 at 8:02

Separate gathering information from typesetting:

\documentclass{article}

\ExplSyntaxOn

\seq_new:N \g_bpclass_author_seq
\seq_new:N \g_bpclass_email_seq

\RenewDocumentCommand{\author}{m}
{
\seq_gput_right:Nn \g_bpclass_author_seq { #1 }
}
\NewDocumentCommand{\email}{m}
{
\seq_gput_right:Nn \g_bpclass_email_seq { #1 }
}

\NewDocumentCommand{\printauthors}{}
{
\par\noindent
\begin{tabular}{@{} l l @{}}
\g_bpclass_author_seq
\g_bpclass_email_seq
\bpclass_print_author:nn
\end{tabular}
}

\cs_new_protected:Nn \bpclass_print_author:nn
{
#1 % author name
&
\ttfamily #2 % email
\\[2ex]
}

\ExplSyntaxOff

\begin{document}

\author{John Smith}
\email{john.smith@domain.tld}

\author{Jane Smith}
\email{jane.smith@domain.tld}

\author{George Hastings}
\email{george.hastings@something.net}

\printauthors

\end{document}


The authors' names and emails are gathered in sequences and then used to make a tabular; but you can reuse the items in several other ways.

Of course this is only a skeleton, there are so many variations and there's possibly to accommodate affiliations and maybe multiple email addresses.

Here's another possibility, taking care of the affiliation.

\documentclass{article}

\ExplSyntaxOn

\seq_new:N \g_bpclass_author_seq
\seq_new:N \g_bpclass_affiliation_seq
\seq_new:N \g_bpclass_email_seq

\RenewDocumentCommand{\author}{m}
{
\seq_gput_right:Nn \g_bpclass_author_seq { #1 }
}
\NewDocumentCommand{\affiliation}{m}
{
\seq_gput_right:Nn \g_bpclass_affiliation_seq { #1 }
}
\NewDocumentCommand{\email}{m}
{
\seq_gput_right:Nn \g_bpclass_email_seq { #1 }
}

\NewDocumentCommand{\printauthors}{}
{
\noindent
\begin{minipage}{\textwidth}
\seq_map_indexed_function:NN \g_bpclass_author_seq \bpclass_print_author:nn
\end{minipage}
}

\cs_new_protected:Nn \bpclass_print_author:nn
{
\raggedright
#2 % author name
\\[0.5ex]
{
\small\itshape
\seq_item:Nn \g_bpclass_affiliation_seq { #1 } % affiliation
\\
}
{
\ttfamily\small
\seq_item:Nn \g_bpclass_email_seq { #1 } % email
\\
}
\bigskip
}

\ExplSyntaxOff

\begin{document}

\author{John Smith}
\email{john.smith@domain.tld}
\affiliation{University of Somewhere}

\author{Jane Smith}
\email{jane.smith@domain.tld}
\affiliation{University of Elsewhere}

\author{George Hastings}
\email{george.hastings@something.net}
\affiliation{University of Duckistan, Department of Duckology, and
University of Another Place, Department of Long Names with No Meaning}

\printauthors

\end{document}


• Thanks for the LaTeX3 solution :-) I always find such code with these new macros incredibly difficult to read, but of course that’s largely due to my inexperience.
– bp99
Mar 30 '21 at 13:33
• I have two more questions about this: (A) I actually have three pieces of information for each author, I just wanted to simplify the example. But with \seq_mapthread_function I can only map two sequences. Is there an elegant way to do map/thread several seqs? (B) If I were to use this expl3 code in my class would I be recommended to replace all ‘classic’ macros (such as \newcommand) with expl3 ones?
– bp99
Mar 30 '21 at 14:10
• @bp99 I feared that: the institution is obviously a necessary identification item. As I said, this is a skeleton, but without enough information on the intended usage, that's as much as I can do. You can map as many sequences as you want by taking one for indexing; check for \seq_map_indexed_function:NN Mar 30 '21 at 14:16
• Thank you for your update. It’s hard to decide between the ‘new’ expl3 based solution and the classic approach provided by others :-) By the way—not that it matters—, the third field I needed was a student ID, not affiliation. Mr. Hastings’s line made me chuckle though, thanks for that!
– bp99
Mar 30 '21 at 18:11

Oh this is more or less the same as campa just posted:-)

\documentclass{article}

\makeatletter
\def\@author{\@gobble}
\def\maketitle{{%
\par
\Large\noindent\textbf{\@title}\par
\smallskip
\large
\noindent\begin{tabular}{@{}ll@{}}% allow  more than one email
\@author{}%
\end{tabular}
\par
\bigskip}}
\makeatother

\title{Example}
\author{John Smith}
\email{js@example.com}
\email{j.smith999@example.org}
\author{Jane Smith}
\email{jane@example.com}
\begin{document}

\maketitle

\section{Intro}
\vdots
\end{document}

• Oooh, the \def\@author{\@gobble} trick is also interesting. Mar 30 '21 at 8:00
• @campa but you reminded me to put a {} guard in so it doesn't gobble the \end of \end{tabular} in the no-author case... Mar 30 '21 at 8:11