我找到了一个关于如何制作作者列表的解决方案,其中最后一位作者前面有“and”,如以下代码所示:
\newcommand\MidSep{, }% separator for two elements, not the last two (for citeauthorlist and citetlist)
\newcommand\LastSep{ and }% separator for last two elements
\newcommand\citetlist[1]{%
\let\last@elem\relax
\let\last@sep\relax
\@for\@list:=#1\do{%
\ifx\last@elem\relax\else
\ifx\last@sep\relax
\def\last@sep{\LastSep}% the separator between the last two elements should is "and"
\else\MidSep % the separator between two elements (not the two last) is a comma
\fi
\citet{\last@elem}%
\fi
\let\last@elem\@list
}% the last element of the list:
\ifx\last@elem\relax\else
\last@sep\citet{\last@elem}%
\fi
}
输出为:作者 A (2011);作者 B (2012) 和作者 C (2013)
我想要相同的,但是对于\citep
。我希望有:(作者 A,2011;作者 B,2012 和作者 C,2013)。
我正在使用natbib
包和IEEEtranSN
参考书目样式
答案1
您可以使用以下修改的代码:
\usepackage[round]{natbib}
\makeatletter
\newcommand\MidSep{; }% separator for two elements, not the last two (for citeauthorlist and citetlist)
\newcommand\LastSep{ and }% separator for last two elements
\newcommand\citetlist[1]{%
\begingroup%
\let\NAT@open@orig\NAT@open\let\NAT@open\relax\NAT@open@orig
\let\NAT@close@orig\NAT@close\let\NAT@close\relax%
\def\NAT@spacechar{, }%
\let\last@elem\relax
\let\last@sep\relax
\@for\@list:=#1\do{%
\ifx\last@elem\relax\else
\ifx\last@sep\relax
\def\last@sep{\LastSep}% the separator between the last two elements should is "and"
\else\MidSep % the separator between two elements (not the two last) is a comma
\fi
\citet{\last@elem}%
\fi
\let\last@elem\@list
}% the last element of the list:
\ifx\last@elem\relax\else
\last@sep\citet{\last@elem}%
\fi%
\NAT@close@orig\endgroup%
}
\makeatother
我的测试文件产生以下输出:
梅威瑟:
\documentclass[convert={density=300},varwidth,border=10pt]{standalone}
\usepackage[round]{natbib}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@book{test,
author={John Smith},
title={TITLE},
year={2011},
publisher={...},
}
@book{test1,
author={Theodor Fontane},
title={Zaubefloete},
year={1000},
publisher={...},
}
@book{test2,
author={Wolfgang Goethe},
title={Irgendwas},
year={1000},
publisher={...},
}
\end{filecontents*}
\makeatletter
\newcommand\MidSep{; }% separator for two elements, not the last two (for citeauthorlist and citetlist)
\newcommand\LastSep{ and }% separator for last two elements
\newcommand\citetlist[1]{%
\begingroup%
\let\NAT@open@orig\NAT@open\let\NAT@open\relax\NAT@open@orig
\let\NAT@close@orig\NAT@close\let\NAT@close\relax%
\def\NAT@spacechar{, }%
\let\last@elem\relax
\let\last@sep\relax
\@for\@list:=#1\do{%
\ifx\last@elem\relax\else
\ifx\last@sep\relax
\def\last@sep{\LastSep}% the separator between the last two elements should is "and"
\else\MidSep % the separator between two elements (not the two last) is a comma
\fi
\citet{\last@elem}%
\fi
\let\last@elem\@list
}% the last element of the list:
\ifx\last@elem\relax\else
\last@sep\citet{\last@elem}%
\fi%
\NAT@close@orig\endgroup%
}
\makeatother
\begin{document}
\citetlist{test,test1,test2}
\bibliography{\jobname.bib}
\bibliographystyle{plainnat}
\end{document}
答案2
无需重新发明轮子,这里有一组 LaTeX3 命令。
\documentclass{article}
\usepackage[authoryear,round]{natbib}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_mariose_cites_seq
\seq_new:N \l_mariose_citecommands_seq
\cs_new_protected:Npn \mariose_citelist:nnn #1 #2 #3
{% #1 = delimiter, #2 = cite command, #3 = list
\seq_set_split:Nnn \l_mariose_cites_seq { , } { #3 }
\seq_clear:N \l_mariose_citecommands_seq
\seq_map_inline:Nn \l_mariose_cites_seq
{
\seq_put_right:Nn \l_mariose_citecommands_seq { #2 { ##1 } }
}
\seq_use:Nnnn \l_mariose_citecommands_seq {~and~} {#1~} {~and~}
}
\NewDocumentCommand{\citetlist}{m}
{
\mariose_citelist:nnn { , } { \citet } { #1 }
}
\NewDocumentCommand{\citeplist}{m}
{
(\mariose_citelist:nnn { ; } { \citeboth } { #1 })
}
\ExplSyntaxOff
\NewDocumentCommand{\citeboth}{m}{\citeauthor{#1},~\citeyear{#1}}
\begin{document}
\citetlist{Knuth:BAMSN-1-337,Lamport:LDP86,Goosens:LC94}
\citeplist{Knuth:BAMSN-1-337,Lamport:LDP86,Goosens:LC94}
\bibliographystyle{plainnat}
\bibliography{/usr/local/texlive/2013/texmf-dist/bibtex/bib/beebe/texbook1}
\end{document}
因为\citeplist
我基本上使用\citeauthor{<key>}~\citeyear{<key>}
。
一个简单的概括允许\citetlist*
并\citeplist*
显示完整的作者列表:
\documentclass{article}
\usepackage[authoryear,round]{natbib}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_mariose_cites_seq
\seq_new:N \l_mariose_citecommands_seq
\cs_new_protected:Npn \mariose_citelist:nnn #1 #2 #3
{% #1 = delimiter, #2 = cite command, #3 = list
\seq_set_split:Nnn \l_mariose_cites_seq { , } { #3 }
\seq_clear:N \l_mariose_citecommands_seq
\seq_map_inline:Nn \l_mariose_cites_seq
{
\seq_put_right:Nn \l_mariose_citecommands_seq { #2 { ##1 } }
}
\seq_use:Nnnn \l_mariose_citecommands_seq {~and~} {#1~} {~and~}
}
\NewDocumentCommand{\citetlist}{sm}
{
\IfBooleanTF{#1}
{\mariose_citelist:nnn { , } { \citet* } { #2 }}
{\mariose_citelist:nnn { , } { \citet } { #2 }}
}
\NewDocumentCommand{\citeplist}{sm}
{
\IfBooleanTF{#1}
{(\mariose_citelist:nnn { ; } { \citeboth* } { #2 })}
{(\mariose_citelist:nnn { ; } { \citeboth } { #2 })}
}
\ExplSyntaxOff
\NewDocumentCommand{\citeboth}{sm}
{%
\IfBooleanTF{#1}
{\citeauthor*{#2},~\citeyear{#2}}
{\citeauthor{#2},~\citeyear{#2}}%
}
\begin{document}
\citetlist{Knuth:BAMSN-1-337,Lamport:LDP86,Goosens:LC94}
\citeplist{Knuth:BAMSN-1-337,Lamport:LDP86,Goosens:LC94}
\citetlist*{Knuth:BAMSN-1-337,Lamport:LDP86,Goosens:LC94}
\citeplist*{Knuth:BAMSN-1-337,Lamport:LDP86,Goosens:LC94}
\bibliographystyle{plainnat}
\bibliography{/usr/local/texlive/2013/texmf-dist/bibtex/bib/beebe/texbook1}
\end{document}