Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Is it possible to read the white space in a very simple \author declaration? I understand that it's dangerous to expect such a thing to work very stably, but for a limited use case, I would like to be able to print the author's last name in the document header, and I'd like to keep the mechanism as simple and standard as possible.

I'd like the user to define the following:

\author{First Last}

The package would then read the text after white space in First Last to define the following automatically:

\lastname{Last}

I understand any solution would likely break if there is a middle name or initial, for example, or if there are multiple authors. My question is now as much about my original use case as it is about what is to me an interesting problem.

share|improve this question
    
From the stringstrings package, \getaword{\author}{2}\edef\lastname{\thestring} should do it. –  Steven B. Segletes Mar 26 '13 at 22:38
    
Maybe you can define a command Author with an optional argument used to the last name. Something like \Author[Last]{Full Name}. –  Sigur Mar 26 '13 at 22:39
    
I thought about that, but in the end I decided it was no more elegant than having the user define the last name in a separate command altogether. –  James Clawson Mar 27 '13 at 15:04
add comment

2 Answers

up vote 7 down vote accepted

This works for one author:

\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}

but in real documents usually many authors are defined and this will of course choke.

You can check easily that the output is

Smith
Smith
Smith

An author whose last name is composed of two or more parts should be input as

\author{Brian {Hamilton Kelly}}

An easy implementation with 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}
share|improve this answer
    
It works perfectly! Certainly it will choke for multiple authors, but I'm working on a package for a field in which it's uncommon to have multiple authors. Ideally, the package would be a simple "drop-in" solution, so there'd be as few extra commands defined as possible. Whether or not this solution is one I end up following is another matter, since I don't want to cause more problems than I solve; nevertheless, it's very helpful to see how one would go about doing this. Thank you! –  James Clawson Mar 27 '13 at 15:03
add comment

A possibility using the xstring package:

\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}

enter image description here

Notice the syntax for the argument of \lastname; in particular, if only the last name is given, a space must be pre-pended.

share|improve this answer
    
I'm a little confused by how I'd call it. If I define \author before the \begin{document} command, I wouldn't later be able to call \lastname to drop into a header, would I? It may just be my unfamiliarity with xstring that's confusing me, though it does look promising. In any event, I've gotten egreg's solution (above) to work well in my package. –  James Clawson Mar 27 '13 at 15:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.