8

I'm interested in a macro \nullifyifmoved that takes one argument arg and acts like arg in normal contexts, except it acts like a no-op wherever it is written to a file. Some background:

Martin Scharrer writes in some comment to another question:

A moving argument is an argument which is written into an auxiliary file (like .aux, but also .toc and others) which is then read on some other position at the next run. Things like sectioning titles and labels are moving arguments.

This is an excellent explanation of the technical term "moving argument". Recall that macros can be "expanded" or "executed"; \protect prevents expansion. I want something converse, that doesn't prevent expansion but in fact deletes that instance of the macro entirely whenever it is being written to a file (i.e. wherever the argument is "moved").

There are two other questions that are related (but not identical):

1

2 Answers 2

8

rather than locally switch the definition of \nullifyifmoved in moving contexts you can probably give it a global definition of

\def\nullifyifmoved{%
   \ifx\protect\@typeset@protect\else\expandafter\@gobble\fi}

so that in a context where \protect is doing anything fancy the command gobbles the following token, otherwise it expands to nothing.

For example, with the following code

\documentclass{memoir}

\makeatletter
\def\nullifyifmoved{\ifx\protect\@typeset@protect\else\expandafter\@gobble\fi}
\makeatother

\begin{document}

\tableofcontents

\section{Hello\nullifyifmoved{\footnote{This is a footnote}}\nullifyifmoved{, goodbye}}

Text.

\end{document}

the section heading is Hello¹, goodbye in the document body but only Hello in the table of contents.

3
  • (David Carlisle and egreg:) Are your answers substantially equivalent? (From your respective solution writeups: Are "a place 'where \protect is doing anything fancy'", "a moving context", and "a context where \protected@write is used" equivalent?) Commented Mar 3, 2013 at 2:44
  • No protected@write is one class of moving argument but there are others, protected@edef for example or \PackageInfo tabular preamble constructs such as @{...} etc. Commented Mar 3, 2013 at 10:07
  • To others: Please see also user egreg's excellent answer. Commented Mar 4, 2013 at 0:42
13

All writing operations in LaTeX use the command \protected@write; in Why is \thepage set to \relax in a \protected@write? one can find something about it, in particular the fact that it sets \thepage to relax before doing the primitive operation \write, in order to avoid untimely expansion. This \let operation is performed in a group.

The idea for your problem is just the same: we define \nullifyifmoved to \@gobble in that group so that its argument is completely ignored; its normal definition will be the same of \@firstofone, which simply returns its argument.

Instead of redefining \protected@write we can append \let\nullifyifmoved\@gobble after \let\thepage\relax with

\usepackage{etoolbox}
\makeatletter
\patchcmd{\protected@write}
  {\relax}
  {\relax\let\nullifyifmoved\@gobble}
  {}{\@latex@error{Could not patch \string\protected@write}}
\@ifdefinable{\nullifyifmoved}{\let\nullifyifmoved\@firstofone}
\makeatother
6
  • --verbose please. Commented Feb 24, 2013 at 20:32
  • 1
    @MartinSchröder Before downvoting, you should wait for the requested improvements; or you could provide a better answer. It can happen that no time is available for expanding an answer.
    – egreg
    Commented Feb 24, 2013 at 22:29
  • 1
    As it was, the question deserved a downvote; as it is, it deserves an upvote. :-) Commented Feb 25, 2013 at 7:25
  • @LoverofStructure I never use the "fail" part in that way. Maybe I should; but it's thought for other purposes.
    – egreg
    Commented Mar 1, 2013 at 12:16
  • @egreg Once I know (La)TeX better, I'll understand these things :-) The edit, together with these comments, will serve as a good record / documentation. Commented Mar 1, 2013 at 12:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .