我想复制一些内容而不重新定义其标签。例如,
\newbox{\foobox}
\sbox{\foobox}{\vbox{\section{Foo}\label{sec:foo}}
\usebox{\foobox}
\usebox{\foobox}
会发出警告,因为sec:foo
被定义多次。有什么方法可以阻止第二个\usebox
写入辅助文件吗?
答案1
我假设您希望保留第一个,\label
并禁用其他。然后使用以下技巧:
- 该框由两个命令创建
\BeginIgnoreAux{<id>}
,\EndIgnoreAux
位于原始内容之前和之后。这些宏将标记与结果一起写入文件.aux
,标签内容位于两者之间。 - 如果
.aux
文件被读取,则第一次执行标签 stuff 时会照常执行。如果\BeginIgnoreAux{<id>}
使用相同的 多次调用<id>
,则忽略标签 stuff。这可以避免重复的标签。 - LaTeX 读取
.aux
文件两次。例如,在文档末尾.toc
写入文件。因此,宏\AuxResetIgnoreStuff
会清除<id>
s。
\documentclass{article}
\makeatletter
\global\let\AuxResetIgnoreStuff\@empty
\usepackage{auxhook}
\AddLineBeginAux{\string\AuxResetIgnoreStuff}
% Macros inside the `.aux' file
\newcommand*{\AuxBeginIgnore}[1]{%
\@ifundefined{ignore@#1}{%
\global\expandafter\let\csname ignore@#1\endcsname\@empty
\expandafter\g@addto@macro\expandafter\AuxResetIgnoreStuff
\expandafter{%
\expandafter\global\expandafter\let\csname ignore@#1\endcsname\relax
}%
}\AuxSkip
}
\def\AuxSkip#1\AuxEndIgnore{}
\let\AuxEndIgnore\relax
% User commands
\newcommand*{\BeginIgnoreAux}[1]{%
\protected@write\@auxout{}{%
\string\AuxBeginIgnore{#1}%
}%
}
\newcommand*{\EndIgnoreAux}[1]{%
\protected@write\@auxout{}{%
\string\AuxEndIgnore
}%
}
\makeatother
\begin{document}
\tableofcontents
\newbox{\foobox}
\sbox{\foobox}{%
\BeginIgnoreAux{foo}%
\vbox{\section{Foo}\label{sec:foo}}%
\EndIgnoreAux
}
\noindent
\usebox{\foobox}
\usebox{\foobox}
\noindent
Reference to the first label: \ref{sec:foo}.
\end{document}
该.aux
文件包含:
\relax
\AuxResetIgnoreStuff
\AuxBeginIgnore{foo}
\@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}}
\newlabel{sec:foo}{{1}{1}}
\AuxEndIgnore
\AuxBeginIgnore{foo}
\@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}}
\newlabel{sec:foo}{{1}{1}}
\AuxEndIgnore
以及.toc
文件:
\contentsline {section}{\numberline {1}Foo}{1}