我怎样才能确定标签是什么(a-la \autoref)?

我怎样才能确定标签是什么(a-la \autoref)?

我想要一个命令,它获取一个标签并返回环境(或最后一个分段命令等),之后我有了\label。我的意思是,像\autoref,但不需要从 TeX 命令/环境名称转换为用于输出的名称(即,如果另一个命令接受并给我,我可以使用\somethingname或自己。)\somethingautorefnamemylabelsomething

笔记:我想要一个不使用提供此功能的软件包的解决方案,例如hyperrefcleveref(尽管如果来自其源代码的一段代码可以解决问题,那么这是一个非常好的解决方案)。

答案1

cleveref解决方案可以接受吗?

编辑:虽然cleveref能够区分标签类型,但它默认使用相同的名称,例如节和子节。使用\crefname\Crefname宏来更改名称定义。还请注意,较低级别的节标题有一个继承机制(例如,子子节将继承对子节所做的任何更改)。有关详细信息,请参阅手册第 7.1.2 节。

\documentclass{article}

\usepackage{cleveref}
\crefname{subsection}{subsection}{subsections}

\begin{document}

\section{foo}\label{foo}

The  label type is \namecref{foo}.

\subsection{bar}\label{bar}

The  label type is \namecref{bar}.

\end{document}

在此处输入图片描述

答案2

重要的是要理解 (La)TeX 本质上是按顺序处理文件的,从头到尾只处理一次。由于对标签的引用可能比标签本身更早出现在文档中,因此很明显,一次运行 LaTeX 是不够的。您至少需要运行两次,并且需要以某种方式将信息从第一次运行传递到第二次运行(以便 LaTeX 可以知道\label它在当前运行中尚未处理的 )。

这就是 .aux 文件的用途。除了在每次运行期间将信息写入此文件之外,LaTeX 还会在开始处理文档之前读取此文件的内容(如果存在)。具体来说,\label命令会导致标签信息以行的形式写入 .aux 文件\newlabel。当在以后的 LaTeX 运行开始时重新读取 .aux 文件时,\newlabel.aux 文件中的命令会导致定义一个\r@<labelname>宏,其中包含上次运行中写入 .aux 文件的数据。

写入 .aux 文件的信息来自哪里\label?创建新标签所需的当前信息始终存储在宏的当前值中\@currentlabel。任何创建新\label上下文的 LaTeX 命令都会更新此信息。其中最重要的是\refstepcounter,它会移动计数器并相应地更新数据\@currentlabel

自动找出标签所指环境的软件包(cleverefhyperref's \autorefvariorefntheorem...)都以大致相同的方式执行此操作。基本思想是重新定义\refstepcounter以将其他数据(例如当前环境名称)存储在 中\@currentlabel,然后通过命令将其存储在 .aux 文件中\label。然后您可以编写从 中检索此数据的宏\r@<labelname>

为了更详细地理解这一点,我建议您看看\refstepcountercleveref 包中是如何重新定义的,以便为下一个存储额外的数据\label。然后看看例如\cref@gettype宏如何从结果宏中检索标签类型信息\r@<labelname>

不用说,要使所有这些适用于每种类型的标签(章节、方程式、定理、脚注……),包括由其他软件包引入的标签,需要付出不小的努力。其中许多都使用了除\refstepcounter将标签信息输入之外的其他机制\@currentlabel,所有这些都需要进行适当的重新定义。

对于简单的应用程序来说,仅复制\refstepcounter\cref@gettypecleveref可能就足够了。但是,如果您复制了足够多的“能解决问题的代码片段”以使其可靠地工作,那么您将复制大约一半的软件包。您最好使用cleveref(或其他软件包之一),因为它们已经为您完成了所有艰苦的工作。

相关内容