
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}
結果: