我在一个文档中同时使用了amsmath
和pdfcomment
。这导致由产生的引用(\ref{})
看起来像(zref@1)
而不是像的数字(1)
。如果没有amsmath
或,则pdfcomment
不会出现此问题。
一个最小(不)工作示例:
\documentclass{article}
\usepackage{amsmath}
\usepackage{hyperref}
\usepackage{pdfcomment}
\begin{document}
\begin{equation}
\label{eq:1}
E = m \pdftooltip{c}{speed of light}^2
\end{equation}
See eq. (\ref{eq:1}). % <- this produces (zref@1) instead of (1)
\end{document}
用 编译它pdflatex
。
欢迎任何建议。
答案1
问题其实与 无关pdfcomment
,只不过人们更可能\pdftooltip
在方程式中使用 而不是命令\section
。但如果你愚蠢地尝试:
\begin{equation}
\label{eq:1}
x^2 + y^2 = z^2
\section{Pythagoras}
\end{equation}
然后(假设它确实编译了,但我对此表示怀疑)你会发现完全相同的问题。
这是因为,当amsmath
处理方程环境(包括方程环境equation
本身)时(因为它重新定义了方程环境),它会对方程进行一些复杂的操作,这需要多次处理(我相信这也会导致 beamer 和 tikz 出现问题)。这样做的后果之一是,如果您\label
在方程环境中输入命令,则标签不会立即保存,而是至少处理一次方程,然后标签才会保存到文件.aux
。这大概是为了处理诸如align
整个方程内容的多个部分可以被标记之类的事情(我猜是这样)。
现在,\label
命令通过使用 的值来确定要保存哪些信息\@currentlabel
。这是一项巧妙的工作,它确保了\section{Introduction}\label{sec:intro}
Just Works(TM) 之类的功能。但这确实意味着您需要确保在计数器递增和命令\label
处理之间\@currentlabel
不会重新定义 。
这就是魔法与之相反的地方。如果方程式中有一个命令,它以重新定义amsmath
的方式增加计数器,那么它就是\@currentlabel
那保存的是公式标签而不是公式标签。我举的愚蠢例子\section
就是这样一个命令,但它不太可能出现在公式环境中。另一个是\pdftooltip
,正如我们所见,这更有可能出现。
为了验证我说的是否正确,我们可以模拟以下\section
命令:
\documentclass{article}
\usepackage{amsmath}
\renewcommand{\thesection}{\alph{section}}
\begin{document}
\section{Introduction}
\label{sec:intro}
\begin{equation}
\label{eq:1}
E = m c^2
\refstepcounter{section}
\end{equation}
See eq.\ \ref{eq:1} in Section~\ref{sec:intro}.
\end{document}
得出的结果为:
参见第 a 节中的等式 b。
如果我们注释掉这一\refstepcounter
行,我们会得到:
参见第 a 节中的公式 1。
作为另一个实验,我们可以amsmath
使用以下代码来消除这个问题:
\documentclass{article}
\usepackage{pdfcomment}
\renewcommand{\thesection}{\alph{section}}
\begin{document}
\section{Introduction}
\label{sec:intro}
\pdftooltip{hello}{world}
\label{sec:introb}
Sections~\ref{sec:intro} and~\ref{sec:introb} are the same.
\end{document}
在这种情况下,答案很简单:确保在\label
之前发出\pdftooltip
。但对于这种amsmath
情况,事情并不那么简单,因为一切都是内部的。
查看源代码,pdfcomment
我可以看到\pdftooltip
使用\refstepcounter
哪个是重置的魔法命令\@currentlabel
。我猜它只需要在内部使用它,之后不需要设置\@currentlabel
任何特定内容。所以最好的解决方案是修补,以便它在调用时pdfcomment
保存当前值,然后再次恢复它。\@currentlabel
但是,我不建议您自己修补软件包。因此,您应该联系软件包的维护者并请他这样做。与此同时,有一种方法可以解决这个问题。这只是为了确保在\@currentlabel
等式末尾正确的值有效。所以我们需要调用\refstepcounter
但不实际增加计数器。这是一个执行此操作的简单宏:
\makeatletter
\def\refsetcounter#1{%
\protected@edef\@currentlabel
{\csname p@#1\endcsname\csname the#1\endcsname}%
}
\makeatother
将其称为\refsetcounter{equation}
。它必须放在结尾方程环境(或至少在之后\pdftooltip
)。
现在,如果能自动完成这项工作就好了。这将涉及修补命令amsmath
。通常,我也会对此保持警惕,但我对这个amsmath
软件包比对那个软件包更有把握pdfcomment
,所以我准备试一试!
我的实验表明,实际上只有equation
命令存在此问题。不知何故,诸如align
、gather
和 之类的东西multline
都可以正常工作。所以我们只需要确保我们的新命令在环境\refsetcounter{equation}
结束时运行equation
。以下是代码:
\makeatletter
\def\refsetcounter#1{%
\protected@edef\@currentlabel
{\csname p@#1\endcsname\csname the#1\endcsname}%
}
\let\orig@endequation=\endequation
\def\endequation{%
\refsetcounter{equation}%
\orig@endequation}
\makeatother
有了序言中的这段内容,您的代码将生成:
参见公式(1)。
正如它应该。