3

Update:

I decided to use Daniel's simple solution:

\newcommand\Einstein{Albert Einstein (1879-1955)\xdef\Einstein{Einstein}}

With this, the first use of \Einstein prints the full name with birthdates and all following uses of \Einstein print only his surname.

Now wanted to ask if there is a simple way to improve the command so that at every new chapter, the command jumps back to the default of printing the full name with birthdates at first use in that new chapter.

any simple ideas? I could do that, by invoking a \renewcommand at the beginning of the chapter, but, amybe there are smarter ways.


A few days ago I had an idea for a \newcommand which -- in my eyes -- would be kind of cool to have.

Imagine you wanted to write a lengthy text. In this text you mention a bunch of names of historical figures. Some of these figure reoccur at different parts of your text.

Imagine further that you want to provide their dates of birth and death -- but of course you do not want to provide them every time you mention them but only once, i.e., when you mention that name either (a) for the first time in your entire document or (b) for the first time in that part/chapter/section (should your text be book-length and contain several chapters)

For example you want to write in your *.tex-file:

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.

The Output should be like:

This was one of the most important achievements by Albert Einstein (1879-1955) – in fact, what [Albert] Einstein achieved is one of the most important achievements in the science of physics as such.

Maybe you even want to omit Einstein's forename in the second occurrence, too -- this is what the [brackets] illustrate.

So, does anyone have an idea how such a command could be designed so that the date is printed only once at the first occurrence in the entire document (i.e., the case of (a) as mentioned above)? Maybe this command could even be tweak so that it also provides the option to print the dates of birth and death at the first occurrence in every part or chapter or section (i.e., the case of (b) as mentioned above)?

  • 4
    Sounds like the glossaries package (especially acronyms) or similar packages. – Qrrbrbirlbel Nov 20 '13 at 9:14
  • You might want to try nameauth, it offers a lot of options. – DG' Nov 20 '13 at 10:09
  • 2
    \newcommand\Einstein{Albert Einstein (1879-1955)\xdef\Einstein{Einstein}} would be such a macro that redefines itself on the first expansion. Of course a lot of sugar could be added around this mechanism to make it more accessible. – Daniel Nov 20 '13 at 13:20
  • @Daniel : I like that. That would be a simple solution. I guess, however, that there is no way to automatically redefine back to "Albert Einstein (1879-1955)" at the beginning of every part or chapteror section, right? – ClintEastwood Nov 20 '13 at 15:40
  • Sure, there is. However, I am not sure what exactly you are asking here. (1) Are you interested in learning how something like that could be implemented, or (2) is this a specific problem you need a solution for. In the latter case, I would suggest to use some existing package. Use, for example, the acronym package and then do a \preto{\part}{\acresetall} (\preto is from the etoolbox package) to have all acronyms reset at every part. There might be other packages that are even better suited. – Daniel Nov 20 '13 at 16:01
1

You can try this:

\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.
  • do you think it is possible to combine this with \xspace? I know, xspace is not usually recommended, but I am using it and now realized that I cannot simply add \xspace to these definitions (e.g.: ...\xdef\Einstein{Einstein\xspace}). Any workaround? – ClintEastwood Feb 2 '15 at 13:55
  • 1
    @ClintEastwood Try \def\resetEinstein{\def\Einstein{Albert Einstein (1879-1955)\gdef\Einstein{Einstein\xspace}\xspace}}. I don't know, what it is but I mean that you must use \gdef instead \xdef when you are using this. And I hope that the difference between \xdef and \gdef is generally known. – wipet Feb 19 '15 at 5:37
3

If you want to use such a facility in your documents, I'm sure there's a package for that (see the comments to your question). But if you're more curious about how it's done, here's a very simple macro that I use for a similar task: Define a label with \label on first use, and invoke it with \ref on subsequent uses. The use case is for repeating numbered examples (e.g., with the package gb4e), where the numbering increases throughout the document. The number should be assigned on first use, and reused on later references. Here's a simplified implementation (I use something a bit more baroque):

% \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}]}

With these definitions, I can repeatedly use

\refitem{labelX} This is my example about X.

and all uses after the first one will show up with the number assigned on first use.

The implementation is simple: On first use of a label <label>, it defines a macro fr@<label> (whose value does not matter, since it's never used). I can't just check LaTeX's label definitions because they are saved and restored from the .aux file, so on recompilation they are always defined. Note also that I separated the logic of the code from its specific use with \item, so that \smartlabelif can be applied to other kinds of labels.

Edit: If you want the system to start anew at every chapter, the simplest way is to just use labels whose prefix includes the chapter number, e.g., fr@\thechapter@Einstein. In the next chapter, the labels will no longer be found. Or if you're worried about the accumulated definitions in a long book, define fr@<label> to have as value the current chapter (remember that the value is currently unused), and test for equality.

You can easily adapt the above conditional to provide extended author information, short vs. long citations (though natbib already supports those), etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.