使用 hyperref 时重新定义 \label 和 \ref

使用 hyperref 时重新定义 \label 和 \ref

我正在编辑一本书,其中包含大约 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/\refhyperref/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(或作为具有可选参数的宏)定义的宏。

相关内容