2つの値を持つ新しいコマンド。そのうちの1つは最初に言及されただけです。

2つの値を持つ新しいコマンド。そのうちの1つは最初に言及されただけです。

2 つの値を持つ新しいコマンドを定義したいと思います。1 つは著者名、もう 1 つは著者の死亡日です。2 番目の値はコマンドが最初に使用されたときにのみ指定され、その後は著者名のみが指定されます。どうすればよいでしょうか?

答え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}

ここに画像の説明を入力してください

これを 1 回または 2 回以上必要な場合は自動化できます。

\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

MWE:

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

結果:

ここに画像の説明を入力してください

関連情報