
Ich möchte einen neuen Befehl definieren, der zwei Werte hat. Einer ist der Name des Autors und der andere sein Todesdatum. Der zweite Wert wird nur beim ersten Mal erwähnt, später wird nur noch der Name des Autors erwähnt. Wie geht das?
Antwort1
Sie können ein Befehlspaar verwenden, von denen sich einer selbst neu definiert:
\makeatletter
\newcommand*\einstein{Albert Einstein\death@einstein}
\def\death@einstein{ ($\dagger$~1955/04/18)\def\death@einstein{}}
\makeatother
Dann wird bei jeder Verwendung \einstein
der Name Albert Einstein
sofort gefolgt vom Aufruf von gedruckt \death@einstein
. Letzterer wird dann gedruckt ($\dagger$~1955/04/18)
und definiertselbstum beim nächsten Gebrauch nichts zu verursachen.
\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}
Dies kann automatisiert werden, wenn Sie es mehr als ein- oder zweimal benötigen:
\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}
Antwort2
Alternative Version mit einer Booleschen Prüfung:
\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}
Das \xspace
Makro aus dem gleichnamigen Paket fügt nach einem Wort ein Leerzeichen ein, außer wenn darauf Satzzeichen, Fußnotenzeichen usw. folgen. Dies ist nützlich, da das ursprüngliche Leerzeichen durch die Makroverarbeitung entfernt wird, wenn das Makro im Dokument aufgerufen wird.
Ergebnis:
Dies kann für mehrere Autoren verallgemeinert werden, die das xkeyval
Paket verwenden. Damit diese Lösung funktioniert, müssen einige Befehle mit erstellt werden. \csname
Beispielsweise #1
kann ein Boolean für einen im Argument enthaltenen Schlüssel mit erstellt werden \expandafter\newif\csname if#1displayed\endcsname
, und ähnliches gilt für das Lesen der Werte der Schlüssel aus den \KV@
von erstellten Makros \define@key
. Zugegebenermaßen ist dies nicht sehr einfach zu lesen, aber hoffentlich sind die Schritte klar.
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}
Ergebnis: