我对......感兴趣\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