为什么 \label 在 \footnote 之后不起作用?

为什么 \label 在 \footnote 之后不起作用?

在评论中Martin Scharrer 的回答为什么环境的标签必须出现在标题之后?有讨论是否应该放在\label里面或后面\caption。通过阅读评论,我们可以感觉到,在大多数情况下,是否将 放在\label命令参数里面或命令后面并不重要,而将其放在后面可能是更好的选择,因为根据阿克塞尔的名言Leslie Lamport 认为,“标签可以出现在分段或命令的参数中\caption,但不能出现在其他移动参数中”。

也就是说,这句话可能表明,将其放在\label命令后面是一种最佳做法,因为它总是有效,即使在“移动参数”的情况下也是如此。

笔记:我意识到这并非字面上的意思(否则我就不会问这个问题了),但在我看来,根据那句引言,人们可以合理地假设这是如此。)

然而,当\labeling \footnotes 时,只有\ref\label里面\footnote不是之后。为什么会这样呢?

\documentclass{article}

\begin{document}

Text.\footnote{\label{fn:test-1}This is a footnote.}

More text.\footnote{This is another footnote.}\label{fn:test-2}

Let's reference fn.~\ref{fn:test-1}, and let's also reference fn.~\ref{fn:test-2}

\end{document}

在此处输入图片描述

一个既涉及到为什么会这样,又涉及到为什么这样设计的答案,会比一个仅仅涉及到为什么会这样设计的答案更受欢迎。

答案1

让我们看看内核中的一些代码:

% latex.ltx, line 6031:
\long\def\@footnotetext#1{\insert\footins{%
    \reset@font\footnotesize
    \interlinepenalty\interfootnotelinepenalty
    \splittopskip\footnotesep
    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
    \hsize\columnwidth \@parboxrestore
    \protected@edef\@currentlabel{%
       \csname p@footnote\endcsname\@thefnmark
    }%
    \color@begingroup
      \@makefntext{%
        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
    \color@endgroup}}%

当这样做时,LaTeX 会将其与的当前值\label{foo}关联起来;大多数情况下,这是通过foo\@currentlabel\refstepcounter

% latex.ltx, line 3888:
\def\refstepcounter#1{\stepcounter{#1}%
    \protected@edef\@currentlabel
       {\csname p@#1\endcsname\csname the#1\endcsname}%
}

但在脚注的情况下,由于可选参数\footnote并且可以将脚注拆分为\footnotemark和,因此这项工作是手动完成的\footnotetext

现在要注意的\protected@edef\@currentlabel{...}

\insert\footins{

该命令\insert是 TeX 原语;它执行几项操作,其中一项相当于执行

\setbox\footins=\vbox{

{我们已经找到了“犯罪现场”:从上到下的材料都}以组为单位进行评估(扩展和执行),包括的定义\@currentlabel

因此,如果你说

\footnote{Some text}\label{foo}

忘记了引用脚注编号的值,\@currentlabel因为设置该值的组已关闭。唯一的解决方法是执行

\footnote{\label{foo}Some text}

因此当\label的值\@currentlabel正确时就会执行。

答案2

\label命令始终会生成一个标签,该标签将产生包含该标签的最低级别编号环境(或命令)的编号。在您的示例中,这是文档本身,它没有编号---因此\ref发出命令时不会出现任何编号。

命令中的混淆之处\caption在于,那里的标签实际上对应于包含它的 、 等。标题本身tablefigure不是编号,但它们控制包含它们的其他环境是否编号。

如果您创建了三个表格,但只在最后一个表格上添加了标题,则该表格将被标记为“表格 1”,而不是“表格 3”。这应该是这样的。如果不是这样,我会怀疑我是否遗漏了表格 1 和 2,花些时间思考排字员在编辑过程中犯了错误,或者两者兼而有之。

因此,\begin{table}不能依赖它来增加表格编号,因为并非所有表格都已编号。但所有带有标题的表格都已编号,这就是为什么生成适当编号的任务被委托给命令的原因\caption。不过,虽然\caption处理其包含环境的计数器,但它本身实际上并没有编号。这也是必须的,以避免在文档中出现一个图和一个表,标记为“图 1”和“表 2”。


这基本上就是全部的答案,但这里有几个例子可以澄清我的意思。

首先,下面显示了\label{fn:test-2}示例中的命令工作,它只是没有任何东西可显示。看看当某些\section命令意味着有\label东西要编号时会发生什么:

\documentclass{article}

\begin{document}

\section{A section}
\section{Another}
\section{One more}
Text.\footnote{\label{fn:test-1}This is a footnote.}

More text.\footnote{This is another footnote.}\label{fn:test-2}

Let's reference fn.~\ref{fn:test-1}, and let's also reference fn.~\ref{fn:test-2}

\end{document}

问题代码现在在第三部分

请注意,的结果\ref{fn:test-2}现在是 3,即标签命令出现的部分编号。这是因为是\section最后一个在与该部分内的文本相同或更高的分组级别生成数字的命令,并且该\label命令出现在该部分内。


现在考虑与环境示例等同的情况table(请记住,这就是\caption命令实际上生成数字)。它看起来像这样,

\documentclass{article}

\begin{document}

\section{Demo}
\begin{table}
    \begin{tabular}{c}
        cell 1
    \end{tabular}
    \caption{This is the \emph{Table}'s caption}
\end{table}\label{tab:test}

\end{document}

\label命令紧跟在它表面上应该标记的内容之后,就像您编写时一样\footnote{}\label{}。但希望您能很清楚地知道,这不会(也不应该)为它旁边但不属于的表创建标签。

相关内容