\expandafter and counters not playing nicely

enter image description here

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
\def\addauthor#1{\@addauthor#1\@empty\@nil}
\def\@addauthor#1,#2#3\@nil{%
  \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}

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
 }

\NewDocumentCommand{\betteraddauthor}{ m 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 { ;~ } { ;~ } { ;~ }
 }

\cs_new_protected:Npn \sd_addauthor:nn #1 #2
 {
  \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


\addauthor{1, 1@1}
\addauthor{2, 2@2}
\betteraddauthor{3}{3@3}

\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:

enter image description here

I don't think that the syntax

\addauthor{A. Name, [email protected]}

is so good and I'd prefer

\addauthor{A. Name}{[email protected]}

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.

enter image description here

\documentclass{article}
\makeatletter
\newcounter{authors}
\newcommand{\@authors}{}
\newcommand{\@authorsnoemail}{}
\def\addauthor#1{\@addauthor#1\@nil}
\def\@addauthor#1,#2\@nil{%
  \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
\addauthor{1, 1@1}
\addauthor{2, 2@2}
\addauthor{3, 3@3}

\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}