我的理解是\@currentlabel
保存一个寄存器值。这也适用于hyperref
使用时。
kpsewhich ltxref.dtx
当我读到处理放置在环境之外的\@currentlabel
情况时(当您将它们附加到标题上时就会发生这种情况),我正在看一看。\label
\section{blah}\label{blah}
它的定义是
\def\@currentlabel{}
在我看来,这实际上是在初始化一个宏。我继续查看文档,source2e
但我仍然不明白\@currentlabel
。
为了获得正确的结果,
\@currentlabel
我们必须为整个显示重新定义它。请注意,我们不能使用,\refstepcounter
因为这会导致\@currentlabel
恢复错误,因此总是将第一个标签写入文件.aux
。
是什么意思整體展示?
如果我创建了自己的分段/标题命令,那么是否需要将其包括在内\refstepcounter{CNT}
以便能够附加到\label{}
它?
是否titlesec
自动添加\refstepcounter{CNT}
新的分段命令?
在章节/标题定义中,有\refstepcounter{CNT}
。这是我发现的唯一联系\@currentlabel
。
该命令增加可引用计数器 CNT
\refstepcounter{CNT}
,设置\@currentlabel == {CNT}{eval(\p@cnt\theCNT)}
。然后该命令\label{FOO}
将以下内容写入文件\@auxout : \newlabel{FOO}{{eval(\@currentlabel)}{eval(\thepage)}}
\def\refstepcounter#1{\stepcounter{#1}%
\protected@edef\@currentlabel
{\csname p@#1\endcsname\csname the#1\endcsname}%
}
结果\subsection{subsec1}\label{subsec1}
等于:\@currentlabel
1.1
\newlabel{subsec1}{{1.1}{1}{subsec1}{subsection.1.1}{}}
例子
\documentclass{article}
\usepackage{hyperref}
\begin{document}
\section{sec1}
\label{sec1}
\subsection{subsec1}
\label{subsec1}
\subsubsection{subsubsec1}
\label{subsubsec1}
\paragraph{par1}
\label{par1}
\section{sec2}
\end{document}
相关.aux
行
\newlabel{sec1}{{1}{1}{}{section.1}{}}
\newlabel{subsec1}{{1.1}{1}{subsec1}{subsection.1.1}{}}
\newlabel{subsubsec1}{{1.1.1}{1}{subsubsec1}{subsubsection.1.1.1}{}}
\newlabel{par1}{{1.1.1.1}{1}{par1}{paragraph.1.1.1.1}{}}
有关的
答案1
宏被初始化为无,但每个\refstepcounter
命令都会重新定义它。如果你有,那么在计数器步进后,\newcounter{foo}
的部分工作就是执行\refstepcounter{foo}
\edef\@currentlabel{\p@foo\thefoo}
的工作\label{baz}
是发出最终写入的命令
\newlabel{baz}{{\@currentlabel}{\thepage}}
但两个宏\@currentlabel
和\thepage
将被展开。前者会立即展开,而后者只在\write
文件命令.aux
实际发生时才展开。
请注意,\refstepcounter
只有 才会发生\edef
而 不会发生\xdef
,因此,如果\refstepcounter
发生在一个组(例如一个环境)内, 的值\@currentlabel
将不会在该组结束后继续存在。
您关于显示的引用指的是需要在 中进行的一些变通方法eqnarray
;这并不重要,因为eqnarray
永远不应该使用。该包在其对齐环境中amsmath
使用了不同的技巧。\label
顺便问一下,是什么\p@foo
?对于标准计数器,它是空的,但可以为特定计数器重新定义,以提供页前缀。对于和来说都是如此enumii
,例如,在 中使用。enumiii
enumiv
enumerate
举个例子。让我们看一下
\subsection{subsec1}\label{subsec1}
该命令\subsection
在处理章节标题之前会执行此操作\refstepcounter{subsection}
。如前所述,这重新定义了\@currentlabel
使用
\edef\@currentlabel{\p@subsection\thesubsection}
由于定义被扩展,\p@subsection
和的当前值\thesubsection
被存储;前者为空,后者在您的代码中扩展为\thesection.\arabic{subsection}
和,最终扩展为1.1
。
后来\label{subsec1}
基本上
\protected@write\@auxout{}{\string\newlabel{subsec1}{{\@currentlabel}{\thepage}}}
这将(大致)转化为
\write\@auxout{\string\newlabel{subsec1}{{1.1}{\thepage}}}
因为 的扩展\thepage
在 期间被中和\protected@write
。该\write
操作记录在主垂直列表中,并将在发货时执行;只有此时\thepage
才会扩展。
是否使用替代方法并不重要
\subsection{subsec1\label{subsec1}}
因为\label
只有在排版标题时才会被处理。宏\label
只是在 a 期间吞噬其参数\protected@write
,因此当参数被移动时不会显示。但这是另一个话题。