# \expandafter and counters not playing nicely

My google-fu has finally failed me... I'm trying to write a package that will allow you say \addauthor{name, email} several times and have the title page properly formatted. Here is a minimal example of my troubles:

% FILE: sd.sty
\ProvidesPackage{sd}
\newcounter{authors}
\newcommand{\@authors}{\@empty}
\newcommand{\@authorsnoemail}{\@empty}
\expandafter\def\expandafter\@authorsnoemail\expandafter{%
\@authorsnoemail%
\ifnum\value{authors}>0, \fi%
#1}
\expandafter\def\expandafter\@authors\expandafter{\@authors%
\ifnum\value{authors}=0 \else ; \fi%
#1 - #2}
\stepcounter{authors}}
\newcommand{\ane}{\@authorsnoemail}
\newcommand{\auth}{\@authors}


and then I try

% FILE: main.tex
\documentclass{article}
\usepackage{sd}

\begin{document}
\begin{tabular}{ll}
Expected: & 1, 2, 3 \\
Got: &  \ane\\
Expected: & 1 - 1@1; 2 - 2@2; 3 - 3@3 \\
Got: & \auth \\
\end{tabular}
\end{document}


And the output is

Expected: 1, 2, 3
Got:      , 1, 2, 3
Expected: 1 - 1@1; 2 - 2@2; 3 - 3@3
Got:      ; 1 - 1@1; 2 - 2@2; 3 - 3@3


My question is "How can I do the counter comparison properly, so that the divider will only be inserted at the second author and above?"

(I included both lists since for some reason removing one makes it work... I suspect I'm doing something wrong with the \expandafters)

-

It's probably easier just to deal with the initial case first. I also added an extra #3 to lose any white space after the comma.

% FILE: sd.sty
\ProvidesPackage{sd}
\newcounter{authors}
\let\@authors\@empty
\let\@authorsnoemail\@empty
\ifx\@authors\@empty
\def\@authorsnoemail{#1}%
\def\@authors{#1 - #2#3}%
\else
\expandafter\def\expandafter\@authorsnoemail\expandafter{%
\@authorsnoemail, #1}%
\expandafter\def\expandafter\@authors\expandafter{%
\@authors; #1 - #2#3}%
\fi
\stepcounter{authors}}
\newcommand{\ane}{\@authorsnoemail}
\newcommand{\auth}{\@authors}

-
Perfect -- thanks! @egreg 's answer below explains why this works (problem was with the expansion of \ifnum). I still haven't gotten around to LaTeX3, so I like this solution. I'm also getting rid of the counter, since it served no other purpose. – Felipe Dec 15 '12 at 6:24

You're not expanding the conditional, which is put inside \@authors as is: if you do \makeatletter\show\@authors\makeatother after the \addauthor lines, you get

> \@authors=macro:
->\@empty \ifnum \value {authors}=0 \else ; \fi 1 -  1@1\ifnum \value {authors}
=0 \else ; \fi 2 -  2@2\ifnum \value {authors}=0 \else ; \fi 3 -  3@3.


which is obviously not what you want.

Here's a way out; just to be more modern than David, I present it in LaTeX3 form:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\addauthor}{ >{ \SplitArgument { 1 } { , } } m }
{
}

{
\sd_addauthor:nn { #1 } { #2 }
}

\NewDocumentCommand{\ane}{ }
{
\seq_use:Nnnn \g_sd_authors_noemail_seq { ,~ } { ,~ } { ,~ }
}
\NewDocumentCommand{\auth}{ }
{
\seq_use:Nnnn \g_sd_authors_seq { ;~ } { ;~ } { ;~ }
}

{
\seq_gput_right:Nn \g_sd_authors_seq { #1 ~ - ~ #2 }
\seq_gput_right:Nn \g_sd_authors_noemail_seq { #1 }
}
\seq_new:N \g_sd_authors_seq
\seq_new:N \g_sd_authors_noemail_seq

\ExplSyntaxOff

\begin{document}
\begin{tabular}{ll}
Expected: & 1, 2, 3 \\
Got: &  \ane\\
Expected: & 1 - 1@1; 2 - 2@2; 3 - 3@3 \\
Got: & \auth \\
\end{tabular}
\end{document}


Here's the output:

I don't think that the syntax

\addauthor{A. Name, a.name@x.y.z}


is so good and I'd prefer

\addauthor{A. Name}{a.name@x.y.z}


so I've provided the definition of \betteraddauthor for the second syntax. Notice that the "internal" macro used is just the same.

-

The following just uses fewer characters and uses the inserted space without zapping it. This only works because of your suggested output, which requires the space.

\documentclass{article}
\makeatletter
\newcounter{authors}
\newcommand{\@authors}{}
\newcommand{\@authorsnoemail}{}
\protected@edef\@authorsnoemail{\@authorsnoemail%
\ifnum\value{authors}>0, \fi%
#1}%
\protected@edef\@authors{\@authors%
\ifnum\value{authors}>0; \fi%
#1 -#2}%
\stepcounter{authors}}
\newcommand{\ane}{\@authorsnoemail}
\newcommand{\auth}{\@authors}
\makeatother

\begin{document}
\begin{tabular}{ll}
Expected: & 1, 2, 3 \\
Got: &  \ane\\
Expected: & 1 - 1@1; 2 - 2@2; 3 - 3@3 \\
Got: & \auth \\
\end{tabular}
\end{document}

-
\xdef will cause troubles if an input like \addauthor{\textbf{1}, 1@1} is given (I don't know if it is to be expected, though) – clemens Dec 14 '12 at 23:44
@cgnieder: True. – Werner Dec 14 '12 at 23:54
Use \protected@edef, not \xdef: if an author's name has accents you'll be in big troubles. Also, but it is in the original code, why \@authors and \@authorsnoemail are not initialized as empty? The set with the empty set as element is not empty. ;-) – egreg Dec 14 '12 at 23:59
@egreg: Agreed. I thought it may have been, originally, to test in an \ifx. I've removed it. – Werner Dec 15 '12 at 0:35