从 \author 定义 \lastname

从 \author 定义 \lastname

是否可以读取非常简单的声明中的空白\author?我知道期望这样的事情非常稳定地工作是危险的,但对于有限的用例,我希望能够在文档标题中打印作者的姓氏,并且我希望使机制尽可能简单和标准。

我希望用户定义以下内容:

\author{First Last}

然后,包将读取空格后的文本并First Last自动定义以下内容:

\lastname{Last}

我知道如果有中间名或首字母,或者如果有多个作者,任何解决方案都可能失败。我现在的问题不仅与我最初的用例有关,还与对我来说有趣的问题有关。

答案1

这适用于作者:

\documentclass{article}
\makeatletter
\newcommand{\getlastpart}[2]{\@getlastpart#1#2 \@nil}
\def\@getlastpart#1#2 #3\@nil{%
  \expandafter\ifx\space#3
   \gdef#1{#2}%
   \expandafter\@gobble
  \else
   \expandafter\@firstofone
  \fi
   {\@getlastpart#1#3 \@nil}%
}
\def\author#1{\gdef\@author{#1}\getlastpart\lastname{#1}}
\makeatother
\begin{document}
\author{John Smith}
\lastname

\author{John X. Smith}
\lastname

\author{Smith}
\lastname

\end{document}

但在实际文档中通常会定义许多作者,这当然会造成阻碍。

您可以轻松检查输出是否

史密斯
史密斯
史密斯

如果作者的姓氏由两个或多个部分组成,则应输入为

\author{Brian {Hamilton Kelly}}

使用 LaTeX3 轻松实现:

\documentclass{article}

\usepackage{xparse}

\makeatletter
\def\author#1{\gdef\@author{#1}\getlastpart\lastname{#1}}
\makeatother

\ExplSyntaxOn
\NewDocumentCommand{\getlastpart}{mm}
 {
  \seq_set_split:Nnn \l_tmpa_seq { ~ } { #2 }
  \seq_pop_right:NN \l_tmpa_seq #1
 }
\ExplSyntaxOff

\begin{document}
\author{John Smith}
\lastname

\author{John X. Smith}
\lastname

\author{Smith}
\lastname

\author{Brian {Hamilton Kelly}}
\show\lastname

\end{document}

答案2

使用xstring包裹:

\documentclass{article}
\usepackage{xstring}

\makeatletter
\newcommand\lastname[1]{%
  \author{#1}\StrBehind{\@author}{ }[\last]\last}
\makeatother

\begin{document}

\lastname{ Mozart}
\lastname{Philip Glass}
\lastname{{Johann Sebastian} Bach}

\end{document}

在此处输入图片描述

注意 ; 参数的语法\lastname,特别是,如果只给出姓氏,则必须在前面加上空格。

相关内容