I would like to define a new command which has two values, one is name of Author and the other is his death date, while the second value is only mentioned the first time the command is used and later only Author name is mentioned. How to do that?
2 Answers
You can use a pair of commands one of which redefines itself:
\makeatletter
\newcommand*\einstein{Albert Einstein\death@einstein}
\def\death@einstein{ ($\dagger$~1955/04/18)\def\death@einstein{}}
\makeatother
Then every time you use \einstein
it will print the name Albert Einstein
immediatly followed by the call of \death@einstein
. The latter will then print ($\dagger$~1955/04/18)
and then define itself to to nothing the next time it is used.
\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}
This can be automated if you need it more than once or twice:
\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}
-
1Thanks a lot, it worked for me just fine. I am beginner at LaTeX, what should I learn to be able to make such soloutions Commented Dec 29, 2019 at 14:56
-
Well, the first step is, do you understand what the code in this answer does?– StanCommented Dec 30, 2019 at 16:20
-
The first method you created a command with the name of the person which consists of the name and another variable called death@person. Then you defined this death@person as it consistes of the symbol dagger and the this variable. The second method you defined a command newperson that defines a new command with the name of the person and his death date What I don't understand in the codes is that how it mention the death date at the first time only. Commented Dec 30, 2019 at 20:03
-
-
I was able to further develop the first solution to only mention the last name of the person upon further using of the command. \makeatletter \newcommand*\einstein{\vorname Einstein \death@einstein} \def\vorname{ Albert \def\vorname{}} \def\death@einstein{(gest. 1955) \def\death@einstein{}} \makeatother \begin{document} \einstein \par \einstein \par \end{document} But I am confused with the second automated solution. I tried defining other csname but it only mentions the first name. What would be the right way to do it. Commented Jan 8, 2020 at 12:22
Alternative version with a boolean check:
\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}
The \xspace
macro from the package with the same name inserts a space after a word except when it is followed by punctuation, footnote marks etc. This is useful because the original space is removed by the macro processing procedure when the macro is called in the document.
Result:
This can be generalized for more than one author using the xkeyval
package. To make this solution work there are some commands that need to be constructed with \csname
, for example a boolean for a key contained in the argument #1
can be constructed using \expandafter\newif\csname if#1displayed\endcsname
, and similar for reading the values of the keys from the \KV@
macros created by \define@key
. Admittedly this is not very easy to read but hopefully the steps are clear.
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}
Result:
\am
also occur in so-called moving arguments? E.g., in the heading of a section, which gets also written to the .toc-file, and which also occurs in the table of contents, and which probably gets repeated in page-headers? What to do in case\am
(as part of a moving argument) is moved to a place prior to that place where you typed=used it the first time?