我正在编辑一本书,其中包含大约 25 篇由不同作者用 LaTeX 撰写的论文。由于其中许多论文使用相同的 \label,为了避免冲突,我重新定义了 \label 命令(以及 \ref 和 \pageref 以及 \cite 和 \bibitem),这样如果第三篇论文有 \label{main_theorem},辅助文件实际上会使用标签“iii:main_theorem”,并且 \ref{main_theorem} 实际上指的是同一个标签。我对 \cite 和 \bibitem 做了类似的事情。
%*************** bib/cite hacks
\let\TheReal@citex=\@citex
\let\TheReal@bibitem=\@bibitem
\let\TheReal@lbibitem=\@lbibitem
\gdef\@lbibitem[#1]#2{\TheReal@lbibitem[{#1}]{#2\roman{chapter}}}
\gdef\@bibitem#1{\TheReal@bibitem{#1\roman{chapter}}}
\gdef\@citex[#1]#2{%
\toks@={}\count@=0%
\@for\@citec:=#2\do{%
\advance\count@ 1
\ifnum\count@=1\edef\0{\the\toks@\expandafter\expandafter\noexpand\@citec\roman{chapter}}%
\else\edef\0{\the\toks@,\expandafter\expandafter\noexpand\@citec\roman{chapter}}
\fi%
\toks@=\expandafter{\0}}%
\TheReal@citex[#1]{\the\toks@}%
}
%************** label/ref/pageref hacks %%%%%%%%%%%%% must be before ams pkgs
\let\TheRealLabel=\label
\let\TheRealRef=\ref
\let\TheRealPageref=\pageref
\gdef\label#1{\TheRealLabel{\roman{chapter}:#1}}
\gdef\ref#1{\TheRealRef{\roman{chapter}:#1}}
\gdef\pageref#1{\TheRealPageref{\roman{chapter}:#1}}
这一切都很好,直到我使用 hyperref,它似乎忽略了 \label 的重新定义,无论我在上述代码之前还是之后加载它。
有什么建议吗?如果无论是否加载 hyperref,重新定义都能起作用,那就太好了,所以我不想只从包中抓取 \label 的定义并对其进行调整。
我也愿意尝试其他方法。重新定义 \label 和 \ref 似乎是最直接的解决方案(对我来说)。
请注意,我也希望能够从外部引用内部标签。例如,我可能想在引言(不同的章节)中说“第三篇论文的主要定理是 \ChapRef{iii}{main_theorem}”。
答案1
因为通过\label
/\ref
对hyperref
/nameref
进行了某些重新定义\AtBeginDocument
,所以您还必须在加载包之后使用它:
\usepackage{hyperref}
\usepackage{letltxmacro}
\AtBeginDocument{%
\LetLtxMacro{\TheRealLabel}{\label}%
\LetLtxMacro{\TheRealRef}{\ref}%
\LetLtxMacro{\TheRealPageRef}{\pageref}%
% redefining \label, \ref, \pageref (\renewcommand or \DeclareRobustCommand)
}
更新了 egreg 的评论。\LetLtxMacro
包负责letltxmacro
通过以下方式定义的宏\DeclareRobustCommand
(或作为具有可选参数的宏)定义的宏。