更新:
我决定使用丹尼尔的简单解决方案:
\newcommand\Einstein{Albert Einstein (1879-1955)\xdef\Einstein{Einstein}}
这样,第一次使用时\Einstein
会打印全名和出生日期,以后所有使用时\Einstein
都只打印姓氏。
现在想问一下是否有一种简单的方法来改进该命令,以便在每个新章节中,该命令都会跳回到默认设置,即在该新章节中第一次使用时打印全名和出生日期。
\renewcommand
有什么简单的想法吗?我可以通过调用本章开头的方法来做到这一点,但也许还有更聪明的方法。
几天前,我有了一个想法\newcommand
,在我看来,这个想法很酷。
假设你想写一篇长文。在这篇文章中,你提到了许多历史人物的名字。其中一些人物在文章的不同部分重复出现。
进一步想象一下,您想要提供他们的出生和死亡日期 - 但当然您不想在每次提及他们时都提供这些信息,而只想提供一次,即当您在 (a) 第一次在整个文档中提到该名字时或 (b) 第一次在该part
/ chapter
/中提到该名字时section
(您的文本应该是一本书的长度并且包含几个章节)
例如你想在你的*.tex
文件中写入:
This was one of the most important achievements by \Einstein -- in fact,
what \Einstein achieved is one of the most important achievements in the
science of physics as such.
输出应该是这样的:
这是阿尔伯特·爱因斯坦 (1879-1955) 最重要的成就之一——事实上,爱因斯坦所取得的成就是物理学领域最重要的成就之一。
也许您甚至想在第二次出现时省略爱因斯坦的名字——这就是 [括号] 所示的内容。
那么,有人知道如何设计这样的命令,以便日期在整个文档中第一次出现时只打印一次(即上面提到的 (a) 的情况)吗?也许这个命令甚至可以调整,以便它还提供在每个或或第一次出现时打印出生和死亡日期的选项(即上面提到的part
( chapter
b section
) 的情况)?
答案1
您可以尝试以下操作:
\def\addaction#1#2{%
\ifx#2\undefined\else \expandafter\def\expandafter#2\expandafter{\expandafter#1#2}\fi}
\def\resetEinstein{\def\Einstein{Albert Einstein (1879-1955)\xdef\Einstein{Einstein}}}
\addaction\resetEinstein\chapter % in chapters
\addaction\resetEinstein\section % in sections
\addaction\resetEinstein\part % in parts
\resetEinstein % in document
% testing:
\Einstein\ is ... \Einstein.
\section{Test}
\Einstein\ is ... \Einstein.
答案2
如果你想在你的文档中使用这样的功能,我相信有一个包可以做到这一点(请参阅你问题的评论)。但如果你对如何完成了,下面是一个非常简单的宏,我用它来完成类似的任务:在\label
第一次使用时用 定义一个标签,并在\ref
后续使用时用 调用它。用例是重复编号示例(例如,使用包gb4e
),其中编号在整个文档中增加。编号应在第一次使用时分配,并在以后的引用中重复使用。这是一个简化的实现(我使用了一些更复杂的东西):
% \smartlabelif: If label #1 is undefined, run #2 and define it; else #3
\newcommand\smartlabelif[3]{\@ifundefined{fr@#1}
{#2\label{#1}\global\@namedef{fr@#1}{\@currentlabel}}
{#3}}
% Interface command: Define or reuse label #2 in a \item
% Syntax: \refitem{<label>}
\newcommand\refitem[1]{\smartlabelif{#1}{\item}{\item[\ref{#1}]}
有了这些定义,我可以反复使用
\refitem{labelX} This is my example about X.
第一次使用之后的所有使用都将显示首次使用时分配的号码。
实现很简单:第一次使用标签时<label>
,它会定义一个宏fr@<label>
(其值无关紧要,因为它从未使用过)。我无法只检查 LaTeX 的标签定义,因为它们已从文件中保存和恢复.aux
,因此在重新编译时它们始终被定义。还请注意,我将代码的逻辑与其特定用途分开\item
,以便\smartlabelif
可以将其应用于其他类型的标签。
编辑:如果你希望系统在每一章都重新开始,最简单的方法是使用前缀包含章节号的标签,例如fr@\thechapter@Einstein
。在下一章中,将不再找到标签。或者,如果你担心一本很长的书会积累定义,请定义fr@<label>
为价值当前章节(记住该值当前未使用),并测试是否相等。
您可以轻松调整上述条件以提供扩展的作者信息、短引用与长引用(尽管natbib
已经支持这些)等。