
我想定義一個新命令,它有兩個值,一個是作者姓名,另一個是他的死亡日期,而第二個值僅在第一次使用該命令時提及,後來僅提及作者姓名。怎麼做?
答案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}
如果您需要一次或兩次以上,這可以自動化:
\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
微量元素:
\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}
結果: