
Gostaria de definir um novo comando que possua dois valores, um é o nome do Autor e o outro é a data de seu falecimento, enquanto o segundo valor só é mencionado na primeira vez que o comando é utilizado e posteriormente apenas o nome do Autor é mencionado. Como fazer isso?
Responder1
Você pode usar um par de comandos, um dos quais se redefine:
\makeatletter
\newcommand*\einstein{Albert Einstein\death@einstein}
\def\death@einstein{ ($\dagger$~1955/04/18)\def\death@einstein{}}
\makeatother
Então, toda vez que você usá \einstein
-lo, o nome será impresso Albert Einstein
imediatamente seguido pela chamada de \death@einstein
. Este último irá imprimir ($\dagger$~1955/04/18)
e definirem sipara nada na próxima vez que for usado.
\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}
Isso pode ser automatizado se você precisar mais de uma ou duas vezes:
\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}
Responder2
Versão alternativa com verificação 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}
A \xspace
macro do pacote com o mesmo nome insere um espaço após uma palavra, exceto quando ela é seguida por pontuação, notas de rodapé, etc. Isso é útil porque o espaço original é removido pelo procedimento de processamento da macro quando a macro é chamada no documento.
Resultado:
Isso pode ser generalizado para mais de um autor usando o xkeyval
pacote. Para fazer esta solução funcionar existem alguns comandos que precisam ser construídos com \csname
, por exemplo, um booleano para uma chave contida no argumento #1
pode ser construído usando \expandafter\newif\csname if#1displayed\endcsname
, e semelhante para ler os valores das chaves das \KV@
macros criadas por \define@key
. É certo que isso não é muito fácil de ler, mas espero que as etapas sejam claras.
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: