4

I want to extract the last word of a sentence stored in a variable, e.g. \thevariable. Here is the minimal example.

\documentclass{article}

% Function to extract the last word of a sentence
\protected\def\TheLastWord#1{\xreverseit{}#1 \relax} 
\def\xreverseit#1#2 #3{%
\ifx\relax#3%
#2%
\expandafter\xthree
\fi
\xreverseit{#1 #2}#3}
\def\xthree#1#2#3{}

\newcommand\thevariable{The example sentence} % Store the sentence in a variable

\begin{document}

\TheLastWord{The example sentence} % Will print the last word 'sentence' -> CORRECT!

\TheLastWord{\thevariable} % Will just print the whole sentence: 'The example sentence' -> WRONG!

\end{document}

The code and the function\TheLastWord were picked up and modified from David Carlisle's excellent work as shown here.

As you can see with the minimal example, it works for text input (\TheLastWord{The example sentence}) but is failed when the input is a variable (\TheLastWord{\thevariable}) storing the same sentence.

What is the reason for this failure? How to modify the code to make it work with the variable input?

1
  • \expandafter\TheLastWord\expandafter{\thevariable}
    – egreg
    Mar 31 '15 at 16:39
5

When TeX finds

\TheLastWord{\thevariable}

it transforms it into

\xreverseit{}\thevariable•\relax

(the denotes a space token). Now the first argument to \xreverseit is empty, the second is \thevariable and the third is \relax, so TeX does

\ifx\relax\relax\thevariable\expandafter\xthree\fi\xreverseit{•\thevariable}\relax

Since the test returns true, \thevariable remains in the input stream and it is expanded; then \expandafter gets rid of the \fi and the input stream will have

\xthree\xreverseit{•\thevariable}\relax

that expands to nothing, by the definition of \xthree.


The moral of the story is that you have to expand \thevariable before \TheLastWord (or, more precisely, \xreverseit) enters into action.

Either you use

\expandafter\TheLastWord\expandafter{\thevariable}

or you change the code

\documentclass{article}

% Function to extract the last word of a sentence
\newcommand*\TheLastWord[1]{\expandafter\xreverseit\expandafter{\expandafter}#1 \relax}
\def\xreverseit#1#2 #3{%
  \ifx\relax#3%
  #2%
  \expandafter\xthree
  \fi
  \xreverseit{#1 #2}#3% 
}
\def\xthree#1#2#3{}

\newcommand\thevariable{The example sentence} % Store the sentence in a variable

\begin{document}

\TheLastWord{The example sentence} 

\TheLastWord{\thevariable}

\end{document}

Of course this will also try expanding the first token when the sentence is given in explicit form.

I removed \protected in front of \def\TheLastWord: this macro is fully expandable, so there's no point in protecting it.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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