
Me gustaría definir un nuevo comando que tenga dos valores, uno es el nombre del Autor y el otro es su fecha de muerte, mientras que el segundo valor solo se menciona la primera vez que se usa el comando y luego solo se menciona el nombre del Autor. ¿Como hacer eso?
Respuesta1
Puede utilizar un par de comandos, uno de los cuales se redefine a sí mismo:
\makeatletter
\newcommand*\einstein{Albert Einstein\death@einstein}
\def\death@einstein{ ($\dagger$~1955/04/18)\def\death@einstein{}}
\makeatother
Luego, cada vez que lo use, \einstein
imprimirá el nombre Albert Einstein
seguido inmediatamente de la llamada de \death@einstein
. Este último luego imprimirá ($\dagger$~1955/04/18)
y luego definirásí mismoa nada la próxima vez que se use.
\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}
Esto se puede automatizar si lo necesita más de una o dos veces:
\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}
Respuesta2
Versión alternativa con verificación booleana:
\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}
La \xspace
macro del paquete con el mismo nombre inserta un espacio después de una palabra, excepto cuando va seguida de puntuación, notas al pie, etc. Esto es útil porque el procedimiento de procesamiento de macro elimina el espacio original cuando se llama a la macro en el documento.
Resultado:
Esto se puede generalizar para más de un autor utilizando el xkeyval
paquete. Para que esta solución funcione, hay algunos comandos que deben construirse con , por ejemplo , se puede construir \csname
un booleano para una clave contenida en el argumento usando , y similar para leer los valores de las claves de las macros creadas por . Es cierto que esto no es muy fácil de leer, pero es de esperar que los pasos sean claros.#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}
Resultado: