有没有办法定义一个命令 \nullifyifmoved{arg},该命令通常会像其参数一样起作用,但如果宏被“移动”,它就会像无操作一样起作用?

有没有办法定义一个命令 \nullifyifmoved{arg},该命令通常会像其参数一样起作用,但如果宏被“移动”,它就会像无操作一样起作用?

我对......感兴趣\nullifyifmoved接受一个参数arg并且像在正常上下文中一样运行的宏arg,只不过它在写入文件时充当无操作. 一些背景知识:

Martin Scharrer 撰文在对另一个问题的评论中

A移动论点是写入辅助文件(例如.aux,但也包括.toc和其他文件)的参数,然后在下次运行时从其他位置读取。诸如分节标题和标签之类的内容都是移动参数。

这是对技术术语“移动参数”的极好解释。回想一下,宏可以“扩展”或“执行”;\protect阻止扩展。我想要一些相反的东西,它不会防止但事实上删除每当将宏写入文件时(即,无论参数在哪里“移动”),该宏的该实例都会完全被删除。

还有另外两个相关(但不完全相同)的问题:

答案1

与其在移动上下文中局部切换的定义,\nullifyifmoved不如给它一个全局定义

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

因此,在\protect执行任何花哨操作的上下文中,命令都会吞噬以下标记,否则它会扩展为无。

例如,使用以下代码

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

章节标题位于Hello¹, goodbye文档正文中,但仅Hello位于目录中。

答案2

LaTeX 中的所有书写操作都使用命令\protected@write;为什么在 \protected@write 中将 \thepage 设置为 \relax?我们可以发现一些关于它的东西,特别是它\thepage在执行原始操作之前设置为放松\write,以避免不合时宜的扩展。此\let操作以组为单位执行。

您的问题的想法是一样的:我们在该组中定义到,\nullifyifmoved以便\@gobble完全忽略它的参数;它的正常定义与相同\@firstofone,它只是返回它的参数。

\protected@write我们不用重新定义,而是可以在\let\nullifyifmoved\@gobble后面添加\let\thepage\relax

\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

相关内容