将自定义 \locallabels 命令与自定义 \eqref 命令结合使用

将自定义 \locallabels 命令与自定义 \eqref 命令结合使用

我正在尝试将 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

相关内容