如何创建具有未知数量输入参数的新引用函数?

如何创建具有未知数量输入参数的新引用函数?

我目前正在撰写硕士论文,我的导师要求段落末尾的引用如下所示:(作者 1,年份 1,作者 2,年份 2,作者 N,年份 N)

由于我是 LaTeX 新手,到目前为止,我仅根据输入作者的数量手动创建了不同的新命令,如下所示:

\newcommand\citepara[1]{(\citeauthor{#1}, \citeyear{#1})}
\newcommand\citeparatwo[2]{(\citeauthor{#1}, \citeyear{#1},\citeauthor{#2}, \citeyear{#2})}
\newcommand\citeparathree[3]{(\citeauthor{#1}, \citeyear{#1},\citeauthor{#2}, \citeyear{#2},\citeauthor{#3}, \citeyear{#3})}

(并且自然可以继续这样做)

不过我希望有办法解决这个问题,以便同一个命令可以接受多个输入参数,并且仍然以上述格式输出。如果给 \citepara 提供了多个输入参数,则现在会打印 (Author1, Author2, Year1, Year2),这是不可接受的。

文献课程是本地大学的版本 - 但它基于回忆录课程。

答案1

这是一个通用循环命令,针对项目列表重复执行循环体。

% \applyto{..loop body..}{..list of items..}
\newcommand\applyto[2]{\def\doxloop{#1}\expandafter\xloop#2\relax}
\newcommand\xloop[1]{\ifx\relax#1\else\doxloop{#1}\expandafter\xloop\fi}

在您的例子中,循环主体由两个命令组成。第一个命令,\inter在任意两个引用之间生成一个逗号,第二个命令,\citepara将一个项目作为参数并负责排版引用。该命令\citeparas执行循环;它是最终使用的那个。

\newcommand\citepara[1]{\citeauthor{#1}, \citeyear{#1}}
\newcommand\inter{}
\newcommand\citeparas[1]%
  {\def\inter{\def\inter{, }}%
   (\applyto{\inter\citepara}{#1})%
  }

使用示例:

\citeparas{{einstein}}
\citeparas{{einstein}{latexcompanion}}
\citeparas{{einstein}{latexcompanion}{knuthwebsite}}

在此处输入图片描述

\begin{filecontents}{test.bib}
@article{einstein,
    author =       "Albert Einstein",
    title =        "{Zur Elektrodynamik bewegter K{\"o}rper}. ({German})
        [{On} the electrodynamics of moving bodies]",
    journal =      "Annalen der Physik",
    volume =       "322",
    number =       "10",
    pages =        "891--921",
    year =         "1905",
    DOI =          "http://dx.doi.org/10.1002/andp.19053221004"
}

@book{latexcompanion,
    author    = "Michel Goossens and Frank Mittelbach and Alexander Samarin",
    title     = "The \LaTeX\ Companion",
    year      = "1993",
    publisher = "Addison-Wesley",
    address   = "Reading, Massachusetts"
}

@misc{knuthwebsite,
    author    = "Donald Knuth",
    title     = "Knuth: Computers and Typesetting",
    url       = "http://www-cs-faculty.stanford.edu/\~{}uno/abcde.html",
    year      = "2017"
}
\end{filecontents}
\documentclass{article}
\usepackage{natbib}
\bibliographystyle{abbrvnat}

% \applyto{..loop body..}{..list of items..}
\newcommand\applyto[2]{\def\doxloop{#1}\expandafter\xloop#2\relax}
\newcommand\xloop[1]{\ifx\relax#1\else\doxloop{#1}\expandafter\xloop\fi}

\newcommand\citepara[1]{\citeauthor{#1}, \citeyear{#1}}
\newcommand\inter{}
\newcommand\citeparas[1]%
  {\def\inter{\def\inter{, }}%
   (\applyto{\inter\citepara}{#1})%
  }

\begin{document}
\citeparas{{einstein}}

\citeparas{{einstein}{latexcompanion}}

\citeparas{{einstein}{latexcompanion}{knuthwebsite}}

\bibliography{test}
\end{document}

答案2

提供稍快输入的另一种解决方案:

\documentclass[]{memoir}

\makeatletter
\newcommand{\@@citepara}[1]{\citeauthor{#1}, \citeyear{#1}}
\newcommand{\@citepara}{}
\def\@citepara|#1,#2|{%
    \ifx&#1&%
    \else\expandafter\@@citepara{#1}\fi%
    \ifx&#2&%
    \else, \expandafter\@citepara|#2|\fi%
}
\newcommand{\citepara}[1]{(\@citepara|#1,|)}
\makeatother

\begin{document}
\noindent
\citepara{1}\\
\citepara{1,2}\\
\citepara{1,2,3}\\
\citepara{1,2,3,4}\\
\citepara{1,2,3,4,5}\\
\citepara{1,2,3,4,5,6}\\
\citepara{1,2,3,4,5,6,7}\\
\citepara{1,2,3,4,5,6,7,8}\\
\citepara{1,2,3,4,5,6,7,8,9}\\
\end{document}

替换上面代码的\newcommand{\@@citepara}[1]{\citeauthor{#1}, \citeyear{#1}}输出\newcommand{\@@citepara}[1]{\textbf{#1}, #1}如下:

结果

相关内容