如何使序列中的最后一个单词成为第一个单词?

如何使序列中的最后一个单词成为第一个单词?

我正在寻找一个宏,它可以接受一个字符串(最好说是单词序列),并在保留部分序列之前先输出最后一个单词。我想将此宏放入用于为某人排版个人信息的环境的定义中:

\newenvironment{person}[2]%
{% begin definition
    \section*{#2}\label{#1}
    \addcontentsline{toc}{section}{#2}
}{% end definition
\clearpage
}

因此

\addcontentsline{toc}{section}{#2}

应该有

\addcontentsline{toc}{section}{\reverseit{#2}}

\reverseit应该产生阿尔文·汉内斯汉内斯·阿尔文艾伦·詹姆斯·范詹姆斯·范艾伦。它还应该处理当其参数由单个单词组成时的特殊情况(例如,亚里士多德)。

是否可以在 TeX 框架内或者使用 Lua 或 LaTeX3 编写这样的宏?

提出的收据是为了回答我怎样才能颠倒字母/标记的顺序?仅当序列由两个单词组成时才解决我的问题。

答案1

在此处输入图片描述

\documentclass{article}

\protected\def\reverseit#1{\xreverseit{}#1 \relax}
\def\xreverseit#1#2 #3{%
\ifx\relax#3%
#2#1%
\expandafter\xthree
\fi
\xreverseit{#1 #2}#3}
\def\xthree#1#2#3{}
\begin{document}

\reverseit{Hannes Alfv\'{e}n}

\reverseit{}

\reverseit{one}

\reverseit{one two}

\reverseit{one two three}


\end{document}

答案2

LaTeX3 提供了有用的工具,希望它们比 David 的代码(示例毫不掩饰地取自他的解决方案)更容易理解。

\documentclass{article}
\usepackage{expl3, xparse}
\ExplSyntaxOn
\seq_new:N \l_input_seq % declare a list (seq) variable
\tl_new:N \l_last_word_tl % declare a "token list" variable
\NewDocumentCommand{\reverseit}{m}
  {
    \tl_if_blank:nF {#1} % If the input contains no words, do nothing.
      {
        % Split the argument into words (~ stands for a space here).
        \seq_set_split:Nnn \l_input_seq { ~ } {#1}
        % Remove the last word from the seq.
        \seq_pop_right:NN \l_input_seq \l_last_word_tl
        % Put the last word on the left of the sequence.
        \seq_put_left:NV \l_input_seq \l_last_word_tl
        % Use the contents of the sequence, separating words by a space (~).
        \seq_use:Nnnn \l_input_seq { ~ } { ~ } { ~ }
      }
  }
\ExplSyntaxOff
\begin{document}

\reverseit{Hannes Alfv\'{e}n}

\reverseit{}

\reverseit{one}

\reverseit{one two}

\reverseit{one two three}

\end{document}

相关内容