8

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{{[email protected]}{[email protected]}{[email protected]}}

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
4
  • 3
    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. Commented Mar 30, 2021 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 <[email protected]>}? I would like the email addresses in monospace, so this way an author would have to add that formatting themselves: \author{John Smith \texttt<[email protected]>}
    – bp99
    Commented Mar 30, 2021 at 7:49
  • 1
    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. Commented Mar 30, 2021 at 7:58
  • Ah, how silly of me. Fair enough, that syntax is much better!
    – bp99
    Commented Mar 30, 2021 at 13:30

3 Answers 3

4

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\author#1{\@emailfalse\g@addto@macro\@author{\@@author#1}}
\def\email#1{\if@email\g@addto@macro\@author{\\&#1}\else\g@addto@macro\@author{&#1}\@emailtrue\fi}

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

\makeatother

\author{Me Myself}
\email{[email protected]}
\email{[email protected]}

\author{Someone Else}
\email{[email protected]}

\author{Yet Another}
\email{[email protected]}
\email{[email protected]}

\author{Last One}
\email{[email protected]}

\begin{document}

\maketitle

\end{document}

enter image description here


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

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

\def\author#1{%
   \g@addto@macro\@author{%
      \@authorsep#1%
      \gdef\@emailsep{&\gdef\@emailsep{\\&}}%
   }%
}
\def\email#1{\g@addto@macro\@author{\@emailsep\texttt{#1}}}

\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{[email protected]}
\email{[email protected]}

\author{Someone Else}
\email{[email protected]}

\author{Yet Another}
\email{[email protected]}
\email{[email protected]}

\author{Last One}
\email{[email protected]}

\begin{document}

\maketitle

\end{document}

enter image description here

2
  • 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
    Commented Mar 30, 2021 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 :-) Commented Mar 30, 2021 at 8:02
4

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 @{}}
  \seq_mapthread_function:NNN
    \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{[email protected]}

\author{Jane Smith}
\email{[email protected]}

\author{George Hastings}
\email{[email protected]}

\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{[email protected]}
\affiliation{University of Somewhere}

\author{Jane Smith}
\email{[email protected]}
\affiliation{University of Elsewhere}

\author{George Hastings}
\email{[email protected]}
\affiliation{University of Duckistan, Department of Duckology, and 
University of Another Place, Department of Long Names with No Meaning}

\printauthors

\end{document}

enter image description here

4
  • 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
    Commented Mar 30, 2021 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
    Commented Mar 30, 2021 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
    – egreg
    Commented Mar 30, 2021 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
    Commented Mar 30, 2021 at 18:11
3

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

\documentclass{article}

\makeatletter
\def\@author{\@gobble}
\def\author#1{\g@addto@macro\@author{\\#1&}}
\def\email#1{\g@addto@macro\@author{ \texttt{<#1>}}}
\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{[email protected]}
\email{[email protected]}
\author{Jane Smith}
\email{[email protected]}
\begin{document}

\maketitle

\section{Intro}
\vdots
\end{document}
2
  • Oooh, the \def\@author{\@gobble} trick is also interesting.
    – campa
    Commented Mar 30, 2021 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... Commented Mar 30, 2021 at 8:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .