具有两个值的新命令,其中一个仅在第一次提及

具有两个值的新命令,其中一个仅在第一次提及

我想定义一个新命令,它有两个值,一个是作者的名字,另一个是他的死亡日期,而第二个值仅在第一次使用该命令时提及,之后仅提及作者姓名。如何做到这一点?

答案1

您可以使用一对命令,其中一个命令重新定义自身:

\makeatletter
\newcommand*\einstein{Albert Einstein\death@einstein}
\def\death@einstein{ ($\dagger$~1955/04/18)\def\death@einstein{}}
\makeatother

然后每次使用\einstein它时都会立即打印名称,Albert Einstein然后调用\death@einstein。后者将打印($\dagger$~1955/04/18)然后定义本身下次使用时就不会再发生任何变化。

\documentclass{article}

\makeatletter
\newcommand*\einstein{Albert Einstein\death@einstein}
\def\death@einstein{ ($\dagger$~1955/04/18)\def\death@einstein{}}
\makeatother

\begin{document}

\einstein \par
\einstein

\end{document}

在此处输入图片描述

如果你需要多次,可以自动执行此操作:

\documentclass{article}

\makeatletter
\newcommand*\newperson[3]{%
  \def#1{#2\csname death@#2\endcsname}%
  \@namedef{death@#2}{ ($\dagger$~#3)\@namedef{death@#2}{}}%
}
\makeatother

\newperson\einstein{Albert Einstein}{1955/04/18}
\newperson\planck{Max Planck}{1947/10/04}

\begin{document}

\einstein \par
\einstein

\planck \par
\planck

\end{document}

在此处输入图片描述

答案2

带有布尔检查的替代版本:

\documentclass{article}
\usepackage{xspace}
\newif\ifauthordisplayed         % create boolean
\authordisplayedfalse            % set to false
\def\am{%
\ifauthordisplayed%              % if boolean true
Ali Mabrook\xspace%              % print only the name
\else
Ali Mabrook (died 2016)\xspace%  % print name and date
\authordisplayedtrue%            % and set boolean to true
\fi%
}
\begin{document}
\am was an author. His name is \am.
\end{document}

来自同名包的宏\xspace会在单词后插入一个空格,除非该单词后面跟着标点符号、脚注符号等。这很有用,因为当在文档中调用宏时,原始空格会被宏处理过程删除。

结果:

在此处输入图片描述

这可以推广到使用该包的多个作者xkeyval。要使此解决方案发挥作用,需要使用 构建一些命令\csname,例如,#1可以使用 构建包含在参数中的键的布尔值,以及从 创建的宏\expandafter\newif\csname if#1displayed\endcsname中读取键的值的类似命令。诚然,这不是很容易阅读,但希望步骤清晰。\KV@\define@key

梅威瑟:

\documentclass{article}
\usepackage{xkeyval}
\usepackage{xspace}
\makeatletter
\newcommand{\addauthor}[3]{%
% create boolean for the key in argument #1
\expandafter\newif\csname if#1displayed\endcsname
% set boolean to false
\csname #1displayedfalse\endcsname
% define function for this key
\define@key{myauthors}{#1}{%
% if displayed before
\csname if#1displayed\endcsname
% print just the name
#2%
\else%
% print full info and set boolean to true
#2 (died #3)%
\csname #1displayedtrue\endcsname
\fi%
}
}

% call command that is created by define@key
\newcommand{\displayauthor}[1]{%
\csname KV@myauthors@#1\endcsname{}\xspace%
}
\makeatother

\begin{document}
\addauthor{am}{Ali Mabrook}{2016}
\addauthor{js}{John Smith}{2004}

\displayauthor{am} was an author. His name was \displayauthor{am}.

\displayauthor{js} was an author. His name was \displayauthor{js}.

\end{document}

结果:

在此处输入图片描述

相关内容