我正在尝试将 refs 和 labels 的范围限制在 LaTeX 文档的某些部分。参见这个问题。
我有一个自定义\locallabels{}
命令,修改自这里以及自定义\eq{}
命令:
\documentclass{article}
\AtBeginDocument{%
\let\origref\ref \let\origpageref\pageref \let\origlabel\label \let\origeqref\eqref \newcommand\locallabels[1]{%
\renewcommand\label[1]{\origlabel{#1##1}}% ← notice the change here:
\renewcommand\ref[1]{\origref{#1##1}}% ##1#1, not #1##1
\renewcommand\pageref[1]{\origpageref{#1##1}}%
\renewcommand\eqref[1]{\origeqref{#1##1}}%
}}
\usepackage{amsmath}
\newcommand{\eq}[1]{\eqref{eq:#1}}
\begin{document}
\section{Section 1}
\label{sec}
\begin{equation}
\label{eq:1}
\int3x+4\pi\,dx
\end{equation}
\eq{1} should give (1), but it actually gives (2).
\locallabels{:sec2}
\section{Section 2}
\label{sec2}
\begin{equation}
\label{eq:1}
\int6x+3y\,dx
\end{equation}
\eq{1} should give (2), but it gives "(??)".
\end{document}
为什么第二个引用是未解析的引用“(??)” \eq{1}
?为什么第一个引用是“(1)” \eq{1}
?
更新:我发现hyperref
(未包含在上面的 MWE 中)使事情变得复杂。请参阅下面的评论。
另外,我该如何定义一个命令来关闭\locallabels{}
某个引用的效果。例如,这不起作用:
\newcommand{\refnolocallabels}[2]{\locallabels{}\ref{#1}\locallabels{#2}}
谢谢
答案1
这里有两个独立的问题:正如评论中提到的,amsmath
内部使用自己的定义\label
并仅在显示环境内分配其含义。因此,在外部进行更改的技巧\label
不起作用。相反,必须为提供重新定义\label@in@display
(即amsmath
内部)。
第二个问题性质不同:在命令中,\locallabels
有一个 的重新定义\ref
和一个 的重新定义。但最终\eqref
应该只有一个 的内部调用\ref
。对于这两个重新定义,对 的调用被应用了两次,当然这会导致从未定义的标签。\eqref
\ref
\eq{1}
:sec2
总而言之,正确的代码是
\makeatletter
\AtBeginDocument{%
\let\origlabel@in@display\label@in@display
\let\origref\ref \let\origpageref\pageref \let\origlabel\label
% \let\origeqref\eqref
\newcommand\locallabels[1]{%
\renewcommand\label[1]{\origlabel{#1##1}}% ← notice the change here:
\renewcommand\ref[1]{\origref{#1##1}}%
\renewcommand\pageref[1]{\origpageref{#1##1}}%
% \renewcommand\eqref[1]{\origeqref{#1##1}}%
\renewcommand\label@in@display[1]{\origlabel@in@display{#1##1}}%
}}
\makeatother