我的 google-fu 终于让我失望了...我正在尝试编写一个包,它允许你\addauthor{name, email}
多次说,并正确格式化标题页。以下是我的麻烦的一个简单例子:
% FILE: sd.sty
\ProvidesPackage{sd}
\newcounter{authors}
\newcommand{\@authors}{\@empty}
\newcommand{\@authorsnoemail}{\@empty}
\def\addauthor#1{\@addauthor#1\@nil}
\def\@addauthor#1,#2\@nil{%
\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}
然后我尝试
% FILE: main.tex
\documentclass{article}
\usepackage{sd}
\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}
输出是
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
我的问题是“我怎样才能正确地进行计数器比较,以便分隔符仅插入第二作者及以上的位置?”
(我包含了这两个列表,因为出于某种原因,删除一个可以使其正常工作...我怀疑我对 s 做错了什么\expandafter
)
答案1
先处理初始情况可能更容易。我还添加了一个额外的内容#3
以删除逗号后面的任何空格。
% 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}
答案2
你没有扩展条件,它放在里面\@authors
照原样:如果你\makeatletter\show\@authors\makeatother
按照这些\addauthor
行做,你会得到
> \@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.
这显然不是你想要的。
这是一个解决方法;为了比 David 更现代,我以 LaTeX3 形式呈现它:
\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}
输出如下:
我不认为语法
\addauthor{A. Name, [email protected]}
非常好,我更喜欢
\addauthor{A. Name}{[email protected]}
所以我为第二种语法提供了 的定义\betteraddauthor
。请注意,使用的“内部”宏是相同的。
答案3
以下只是使用了较少的字符,并使用了插入的空格,但没有将其删除。这只适用于您建议的输出,它需要空格。
\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}