使用xparse
它可以很容易地在每次出现标记时拆分列表。在我的 MWE 中,我设置了一个新命令,\mylist
其中我传递了两个以 分隔的名称\and
。xparse
脚本在标记处拆分列表\and
并将两个名称输出到彼此之下。
是否有可能将此脚本与\@author
宏一起使用。我想\author{}
在命令中逐个打印传递给的作者\maketitle
。为了确保 LaTeX 可以正常使用我以前使用的 author-command,我不想使用示例代码(在 MWE 下方)。
平均能量损失
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\mylist{>{\SplitList{\and}}m}
{
\ProcessList{#1}{\insertitem}
}
\newcommand\insertitem[1]{#1\\}
\begin{document}
\noindent \emph{Authors:}\\
\mylist{John Doe \and Jane Doe}
\end{document}
作者示例
...
\RenewDocumentCommand\author{>{\SplitList{\and}}m}
...
\author{John Doe \and Jane Doe}
...
数数
我设置了一个计数器并1
为每个项目添加,所以最后我知道有多少作者被传递给了列表。然后我用条件检查计数器的值是否大于 1。这样我就可以决定是否Author
应该Authors
在名字前输出。目前这不起作用,因为我需要结果前数组已定义。如果我可以使用默认的 LaTeX\author
命令,则不会出现此问题,因为\author
命令已在序言中填充。然后\maketitle
shoulr 会打印出 MWE 中显示的作者。
\documentclass{article}
\usepackage{xparse}
\RenewDocumentCommand\author{>{\SplitList{\and}}m}
{
\ProcessList{#1}{\insertitem}
}
\newcounter{numberOfAuthors}
\newcommand\insertitem[1]{%
#1%
\newline%
\addtocounter{numberOfAuthors}{1}
}
\makeatletter
\newcommand\checkIfGreatherThan{%
\ifnum\c@numberOfAuthors>1
\noindent There are \thenumberOfAuthors\ authors given. The output should be \emph{Authors:}
\else
\noindent There is only one author given. The output should be \emph{Author:}
\fi}
\makeatother
\begin{document}
\noindent \emph{Authors:}\\
% uncomment one of the two commands to test
% \author{John Doe \and Jane Doe}
% \author{John Doe}
\checkIfGreatherThan
\end{document}
答案1
由于和\author
都是\@author
“易失性”宏,即\let
在\relax
使用之后\maketitle
,最好将参数的内容存储\author
到另一个宏中,然后再进行评估。
这个\and
宏很“复杂”,因为它实际上是关闭一个tabular
环境并启动另一个环境。我决定重新定义\and
以扩展,
并使用该expl3
宏\seq_set_from_clist:Nx
,以便将列表拆分为单个名称。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_generate_variant:Nn \seq_set_from_clist:Nn {No,Nx}
\NewDocumentCommand{\myinternalsplitter}{m}{%
\group_begin:
\seq_set_from_clist:Nx \l_tmpa_seq {#1}% Split the expanded list, i.e. `\and` will place `,`
\int_compare:nNnTF { \seq_count:N \l_tmpa_seq } = {1} {% Count the number of items
\displayauthorhead
}{
\displayauthorshead
}
\seq_map_inline:Nn \l_tmpa_seq {\insertitem{##1}}% Display the list with `\insertitem
\group_end:
}
\ExplSyntaxOff
\makeatletter
\let\latex@@author\author
\RenewDocumentCommand{\author}{m}{%
\latex@@author{#1}% Use the old command
\gdef\@@authorlist{#1}%
}
\NewDocumentCommand{\displayauthorhead}{}{%
Author:
}
\NewDocumentCommand{\displayauthorshead}{}{%
Authors:
}
\NewDocumentCommand\mylist{}{%
\begingroup
\def\and{,}
\edef\@authorlist{\@@authorlist}
\myinternalsplitter{\@authorlist}
\endgroup
}
\makeatother
\newcommand\insertitem[1]{%
#1
}
\author{John Doe \and Jane Doe \and John Hannibal Smith \and B.A. Baracus}
\begin{document}
\title{Foo}
\mylist%
\maketitle
\end{document}
答案2
正如您将这个问题链接到另一个具有类似范围的您可以使用我在那里采用的相同技术来解决它(分隔参数)作为替代xparse
:
\documentclass{article}
\usepackage{xpatch}
\makeatletter
\newcounter{authors}
\stepcounter{authors}
\def\@author{\textit{Author\ifnum\theauthors>1s\fi:}\\}
\def\split@and#1\and#2{%
\g@addto@macro\@author{#1\\}%
\ifx#2\@nil\else
\stepcounter{authors}%
\expandafter\split@and\expandafter#2\fi
}
\def\author#1{\split@and#1\and\@nil}
\makeatother
\title{title}
\author{John Doe}%\and Jane Doe}
\begin{document}
\maketitle
\end{document}