我试图理解为什么我不能有效地引用我用标签定义的图形或方程式。
例如:
\begin{figure}
\label{fig:area_Treasuries}
\caption{Treasuries as a portion of total financial flows.}
\centering
\includegraphics[width=0.75\textwidth]{graphs/Area_Treasuries.png}
\end{figure}
\paragraph{}
Figure~\ref{fig:area_Treasuries} presents Treasuries (both flowing
into and out of the United States) as a share of total financial
flows. From 1985 to 2010, Treasuries account for, on average, 53.2\%
of total financial flows.
使用上述代码,我收到此警告:
LaTeX 警告:参考第 37 页上的“fig:area_Treasuries”在输入行 477 上未定义。
结果是“图?? 代表国库券...”
为什么会发生这种情况?相关,我不明白为什么我不能引用实际方程式之前(我的意思是在文本中物理上高于实际方程式)的方程式。难道这不是多次编译和交叉引用应该解决的问题吗?
答案1
\label
考虑使用-系统时,需要考虑很多事情\ref
。对于许多人来说,这是自然而然的事情,但一旦你理解了它,它应该可以帮助解决你的大多数问题。
1. 放置\label
是的,这很重要。为什么?嗯,\label
在LaTeX 内核作为
\def\label#1{\@bsphack
\protected@write\@auxout{}%
{\string\newlabel{#1}{{\@currentlabel}{\thepage}}}%
\@esphack}
请注意(尽管发生了其他事情),它还是会向文件中写入.aux
如下内容:
\newlabel{<label>}{{<currentlabel>}{<page>}}
其中<label>
是表单中的供给\label{<label>}
,<currentlabel>
是 的当前值\@currentlabel
- 一个宏,通常在您调用 时更新\refstepcounter{<cntr>}
。因此,如果\@currentlabel
不是根据您所追求的引用而更新的,那么您将获得错误的引用。最值得注意的是,当您放置一个\label
前 \caption
,因为\caption
增加了一些计数器(figure
或table
计数器,说)。是文档中出现引用的页面,并且当时<page>
具有的值——这可以是定义中规定的任何内容,只是为了清楚起见。\thepage
\thepage
底线:由于\label
用途\@currentlabel
,请确保您的放置位置\label
是后对其进行更新。在某些情况下,您可以避免这种情况,因为计数器更新发生在环境的开始处(通常在定理中),或者环境以这样一种方式编写,即通过\label
多次传递捕获并正确分配给计数器,或者只是常规收集过程。
有些人试图\label
通过放置来避免这种放置混乱\label
里面浮点数\caption
(例如)。这完全没问题,因为与打印标题相关的计数器已更新前标题(及所含的\label
)已设置。
相关参考:为什么环境的标签必须出现在标题之后?
2. 我需要编译多少次?
一般来说,\label
-\ref
系统的工作方式分为两个阶段,因此至少需要两次编译(在第一次迭代期间,在后续编译中可能更少)。在第一\label
阶段,标签以以下形式写入.aux
文件(假设您不加载任何交叉引用包,例如hyperref
):
\newlabel{<label>}{{<reference>}{<page>}
这是一个实际的例子和一次编译后的输出:
\documentclass{article}
\begin{document}
\section{A section}\label{sec:section}
See Section~\ref{sec:section}.
\end{document}
具体来说,上述 MWE 产生以下内容.aux
:
\relax
\@writefile{toc}{\contentsline {section}{\numberline {1}A section}{1}}
\newlabel{sec:section}{{1}{1}}
除了可能与 ToC 相关的内容外,还包含相应的\newlabel
。引用本身仍显示为??
,因为在编写该内容时不知道引用是什么。为了更好地理解这一点,您应该知道该.aux
文件实际上是在 之前读取的\begin{document}
。因此,在第一次编译期间,当 TeX 读取 时\ref{<label>}
,该.aux
文件不包含任何引用信息,因此\ref
导致??
输出为 。
现在,在后续编译期间,会.aux
读取\begin{document}
,因此会将引用(和相应的页码)与特定标签关联起来。这样,当\ref{<label>}
遇到 时(在第二阶段),它可以生成正确的引用。
当然,你不需要总是需要两次编译才能获得正确的引用。这是因为特定页面上标签位置的改变不会产生任何不同的输出,因此不需要任何额外的“成对”编译。
3. 那么.aux
文件中发生了什么?
正如已经解释过的,每当你写的时候\label{<label>}
,都会.aux
被写入
\newlabel{<label>}{{<reference>}{<page>}}
在页面 shipout 处。但是,这些信息在\begin{document}
后续编译期间被读取和执行。并且,从技术角度来看(如果你调查\newlabel
和朋友在LaTeX 内核)\label{<label>}
创建一个名为 的宏,\r@<label>
该宏扩展为{<reference>}{<page>}
。并且,根据您使用\ref{<label>}
或\pageref{<label>}
,您将收到<reference>
(技术上,\@firstoftwo
)或<page>
(技术上,\@secondoftwo
)。
4. 页面引用是什么?
当您使用 时\label
,将此信息写入 时.aux
实际上会延迟到页面输出。这样做的原因是系统设置为<label>
使用 来引用<label>
“标题”(通常以数字形式)以及文档中的位置(页面)。由于 TeX 异步收集和优化页面内容,因此已读取的内容可能\label
需要等待后续页面写入。因此,不等到页面输出可能意味着与引用关联的页码不正确。
这通常也是为什么人们会混淆编译两次、三次甚至更多次的原因。这背后的真相是,你必须尽可能多地编译,直到引用稳定下来(即引用更改时页码或标签不会发生变化)。这个神奇的数字通常是两次,但也可能更多。
有关突破极限的示例,请参阅文档需要无数次编译器传递吗?。
\label
5. 影响常规系统\ref
的软件包
有许多软件包会影响工作方式\label
。\ref
最值得注意的是hyperref
,因为它允许与默认界面集成\label
,\ref
但除了默认参考和页码外还添加了一些其他信息。事实上,当hyperref
与上述 MWE 一起使用时
\documentclass{article}
\usepackage{hyperref}% http://ctan.org/pkg/hyperref
\begin{document}
\section{A section}\label{sec:section}
See Section~\ref{sec:section}.
\end{document}
类似.aux
\relax
% ... some hyperref stuff
\@writefile{toc}{\contentsline {section}{\numberline {1}A section}{1}{section.1}}
\newlabel{sec:section}{{1}{1}{A section}{section.1}{}}
请注意,它\newlabel
仍然具有相同的两个参数格式。但是,{..}
与原来的非两个参数相比,第二个参数现在包含 5 个组hyperref
。前两个参数是从原始系统继承而来的,而后三个参数是新的。第三个参数包含与特定引用(在本例中为一个部分,因此为部分标题)相关的标题。第四个参数是用于超链接过程的反向特定引用,而第五个参数始终为空(可能是为了以后扩展包本身,因此只是为了安全保存)。
6. 扩展常规\label
系统\ref
的软件包
这里有一些扩展 LaTeX 交叉引用功能的软件包:
hyperref
它允许您包含参考文献的命名标题(主要是因为包括nameref
)。此外,它还提供了“自动引用”标签的选项 - 使用\autoref
- 插入通常手动添加的前缀(因此变成see \autoref{<label>}
,see Figure~\ref{<label>}
比如说)。
所有常规\label
s 仅存储两个值:当前标签和该标签所在的页码(见\newlabel
上文)。zref
以自然的方式扩展它,以允许存储任意数量的此类特性通过所谓的“属性列表”。此属性列表类似于键值接口,但使用宏,形式为
\z@newlabel{<label>}{\propA{<propA>}\propB{<propB>}...}
注意\z@
-前缀,这明显不同于传统的\newlabel
。事实上,在使用 时你仍然可以使用\label
- ,或者使用-特定的- 。当然,还有更复杂的标签/引用;请参阅\ref
zref
zref
\zlabel
\zref
zref
文档更多细节。
针对你的情况:
你有
\label
前\caption
- 一个非常常见的问题。因此,\@currentlabel
不包含您需要的最新信息,并且会返回不正确的引用。请参阅1就\label
放置而言。作为第一次运行,您需要至少编译两次才能使引用稳定下来。请参阅2就汇编数量而言,
你能在方程式(或任何东西)实际出现在文本中之前引用它。这就是 TeX 的
\label
-\ref
系统的优点;它使用外部文件 (.aux
) 作为编写有关引用的内容以及加载外部文件的位置的中间人。因此,您绝对可以执行以下操作%... ... see equation~\ref{eqn:myeqn} below: \begin{equation} f(x) = ax^2 + bx + c \label{eqn:myeqn} \end{equation} %...
...只要你第一次编译至少两次即可。参见2就汇编数量而言。
答案2
物体的标签必须是后该对象已定义。因此,如果您要标记标题(在您的示例中),则命令\label
必须跟在标题后面或成为标题的一部分。因此,而不是
\label{fig:area_Treasuries}
\caption{Treasuries as a portion of total financial flows.}
你应该使用:
\caption{Treasuries as a portion of total financial flows.}
\label{fig:area_Treasuries}
或者
\caption{Treasuries as a portion of total financial flows.\label{fig:area_Treasuries}}