交叉引用包:使用哪一个,哪些有冲突?

交叉引用包:使用哪一个,哪些有冲突?

受到我之前问题的启发定理包:使用哪一个,哪些会冲突?,这里还有另一个类似的问题。

有许多不同的软件包可用于进行交叉引用。其中包括hyperrefcleverefvarioreftheoremrefnameref… 这ntheorem包为定理定义了自己的交叉引用命令……

哪些软件包集合提供哪些功能,哪些软件包彼此之间会引起冲突?

答案1

准备工作

在本回答中,我将讨论如何创建对“对象”的交叉引用,例如“定理 2”、“引理 3”、“第 7 页”和“第 4 节”。每个对象都假定与一个\label命令相关联;例如,一些重要的编号定理可能与 相关联\label{thm:important},而一个编号\section指令可能与 相关联\label{sec:results}

交叉引用类别:静态、半动态和全动态

  • 静止的或者硬编码交叉引用。正如名称“静态”所暗示的那样,这些交叉引用是形式为Theorem~2和的硬编码字符串Section~4。其他示例包括in the next paragraphin the final sectionthe preceding lemma

    • 优点:
      1. 实现起来非常简单。
      2. 不需要额外的包(甚至不需要 TeX 命令)。
      3. 甚至不需要使用命令\label。非常灵活。
    • 缺点:
      1. 首次撰写文档时需要非常小心。例如,对尚待提出的方程、定理等的数字的静态引用只能在文档的其余部分完成后才能最终确定。
      2. 如果对象的数字和/或类型稍后更改。例如,如果名为“定理 2”的对象最终变为“引理 3”,则该对象的编号和类型都会发生变化。对于页码的交叉引用,过时风险尤其严重。
      3. 需要在创作过程中愿意进行大量的后续编辑。相关风险是,后续编辑无法捕捉到硬编码交叉引用所需的所有更改。
      4. 没有内置方法可以将这些静态交叉引用转换为超链接目标(如果作者希望这样做的话)。(实际上,一种方法,通过\hyperlinkhypertarget命令超链接包。但是,使用包中的\label各种命令会容易得多。)\refhyperref
  • 半动态交叉引用。这些包括 TeX/LaTeX\ref\pageref命令。我称这种方法为半动态而不是完全动态因为它自动化了编号但对其类型进行硬编码(,,,Theorem... )。pagesection

    • 优点:
      1. 几乎与(完全)静态方法一样简单。
      2. 避免了静态方法的风险(1)和(2),至少对于交叉引用的数字部分而言。
      3. 如果文档中只需要少数交叉引用,这种方法就足够了。
      4. 通过加载该hyperref包,交叉引用的编号也可以变成超链接目标。
    • 缺点:
      1. 如果您一次交叉引用大量对象,比如“公式 (2)、(3)、(5)、(7) 和 (8)”,那么输入所有这些\ref{}命令很快就会变得非常繁琐且容易出错。
      2. 如果你决定改变类型被交叉引用的项目,比如从“定理”到“命题”,准备对交叉引用的硬编码部分进行大量手动编辑。
  • 完全动态交叉引用。对象的类型其编号由 LaTeX 生成。

    • 优点:
      1. 避免上述静态交叉引用方法的所有风险。
      2. 当交叉引用任务很复杂时可以节省大量时间。
    • 缺点:
      1. 需要加载一个或多个额外的 LaTeX 包。
      2. 包中可能尚未定义所有对象类型,需要作者手动添加这些对象类型。
      3. 由于这些软件包执行一些相当复杂的操作,因此存在与其他 LaTeX 软件包发生不必要的交互和不兼容的风险。

哪些软件包提供哪些类型的交叉引用功能?

  • 数学. 提供\eqref交叉引用编号方程的命令。

    键入\eqref{eq:einstein}而不是有两个重要的优点(\ref{eq:einstein})

    1. 你不必记得在交叉引用的公式编号上加上括号,并且
    2. 的输出\eqref(包括括号)始终设置为直立字体形状。此功能非常有用,因为对方程的交叉引用可能出现在某些设置为斜体的文本块中(例如定理陈述的主体中)。按照(近乎通用的?)惯例,方程编号及其括号通常应排版为直立字体形状,而不管周围文本的字体形状如何。不必跟踪对方程的交叉引用是出现在斜体文本块中还是“常规”(即直立字体形状)文本块中,这非常方便。
  • prettyref. 提供命令\prettyref

    这是实现完全动态交叉引用的重要一步。它依靠对象中包含的信息\label来推断对象的类型。但是,这种方法有一些严重的局限性。引用其手册:

    文档中的标签必须采用format:name字符串的形式format来确定 [对象的类型]。除了将格式与名称分开外,请勿:在标签中的任何地方使用该字符。format:name必须是唯一的,因为它是用作标签的。

    简而言之,如果您需要将对象的类型从“定理”更改为“命题”,您还需要更改其标签。这抵消了使用此包的一些优势(在我看来)。如果使用babel选项加载包,则可能会出现第二个问题french,因为这会使:字符“活跃”(在 TeX 特定意义上)。如果您需要同时加载prettyref和,则可以使用以下解决方法babel-french,请参阅查询与 babel-french 一起使用时,prettyref 出现错误尤其是Enrico Gregorio 的回答

  • 瓦里雷夫。提供命令\vrefvpageref。其既定目标是提供“智能页面引用”。从该软件包的用户指南的介绍中可以看出:

    \vref命令引用标签的方式与 相同\ref,但如果引用的内容位于不同的页面上,则结果将根据需要用“在对页上”或“在页面上”等修饰。 该\vpageref命令同样修饰页码;还有用于标签范围的命令\vrefrange和。\vpagerefrange

    如果您需要在每次交叉引用时自动提供页面位置信息,这非常有用。

  • 智能参考。此包部分扩展了 的功能varioref,不仅可以记录 的页面\label,还可以记录任意其他计数器的值(例如当前chapter)。这可以立即用于将“在第 N 章中”添加到交叉引用中,或者通过一些额外的逻辑(例子) 来产生一个varioref“在下一章/上一章”风格的标注。

  • 花哨的。向完全动态交叉引用迈出了又一步。为各种预定义对象类型提供命令\fref(和句子开头的})。它需要使用特定的标签前缀(例如, 、、、等)来告知它对象的类型。如果与一起使用,则可以进行相当多的语言特定改编。与包完全兼容。\Frefchapseceqfigbabelvarioref

    如果你希望将对象类型(例如“Lemma”)添加到已知对象类型列表中fancyref,你可能需要查看Enrico Gregorio 的精彩回答针对这个问题“如何定义一个声明 fancyref 前缀的宏?如何防止它输出文本?”。Enrico 提供了一个名为的宏\mkfancyprefix,它允许用户执行如下指令\mkfancyprefix{lem}{Lemma}。这反过来又允许用户交叉引用引理(或者是引理?!) 并附带\fref{lem:...}说明。

  • 定理参考。顾名思义,此包提供(完全动态的)定理和相关对象(引理、推论等)的交叉引用。需要您使用命令\thlabel而不是\label来工作。功能似乎仅限于类定理对象。

  • 定理. 加载该thref选项后,此软件包提供了一种非常优雅的方法来创建对定理类对象的完全动态交叉引用。即使某些对象共享相同的计数器变量(定理、引理、推论和命题通常如此),它也能正常工作。主要用户命令:\thref.

  • 超链接。除了提供众所周知的将各种交叉引用(包括文档内和文档外的对象)转换为超链接目标的功能外,此软件包还提供了命令\autoref。此命令提供对各种对象的完全动态交叉引用单身的方程式、章节、图形、表格等对象的实例。此命令的一个特殊之处在于,对象的“名称”(例如“方程式”)成为超链接目标的一部分,为鼠标单击并“跳转”到交叉引用的对象提供了一个大的视觉“目标”。

    默认情况下,使用该命令交叉引用的对象的“名称”\autoref为英语。但是,如果软件包babel加载了合适的语言选项,hyperref也会以该语言提供对象的名称。截至 2020 年 2 月中旬,可用的语言选项为(按字母顺序列出)afrikaans、、、(默认;同义词:、、、和) 、(同义词:、、、和)、(同义词:、、catalan和)、、、(同义词:)、(同义词:、、和)、、、和。dutchenglishUKenglishbritishUSenglishamericanfrenchfrenchbfrancaisacadiancanadiengermanngermanaustriannaustriangreekitalianmagyarhungarianportugesportuguesebrazilbrazilanrussianspanishvietnamese

    为了使hyperref包正常工作,通常需要加载它所有其他提供交叉引用功能的软件包。此规则的例外是软件包cleveref-- 见下文。

  • 回忆录文档类:提供命令\tref\fref\pref等,以创建对表格、图形、页面等的动态交叉引用。(请注意,用于创建对章节的交叉引用的memoir命令与包的命令不兼容。)使用这些交叉引用命令对于 LaTeX 代码的可理解性非常有用。明显的代价是交叉引用命令的激增。只需记住非常有限数量的交叉引用命令不是很好吗?!\Crefcleveref

  • 聪明人。目前所有交叉引用软件包的“王者”。主要用户命令:\cref和(以及用于句首的\crefrange大写变体和)。\Cref\Crefrange

    • 除了进行大量花哨的幕后操作来创建完全动态的交叉引用之外,该\cref命令还可以接受一个参数,许多参数。这些参数不需要由作者排序——包会替他/她排序!——它们甚至不需要是同一类型,也就是说,您可以发出命令,包\cref{thm:this,lemma:that,prop:here,cor:there}cleveref自动为您创建一组词汇正确的交叉引用。

    在此处输入图片描述

        \documentclass{article}
        \usepackage{amsthm}
        \usepackage[colorlinks]{hyperref}
        \usepackage[nameinlink]{cleveref}
        %% Define several theorem-like environments:
        \newtheorem{theorem}{Theorem}
        \newtheorem{lemma}[theorem]{Lemma}
        \newtheorem{proposition}[theorem]{Proposition}
        \newtheorem{cor}[theorem]{Corollary}
    
        \begin{document}
        %% Create a few dummy instances of the theorem-like environments:
        \begin{theorem}     \label{thm:this}   \end{theorem}
        \begin{lemma}       \label{lemma:that} \end{lemma}
        \begin{proposition} \label{prop:here}  \end{proposition}
        \begin{cor}         \label{cor:there}  \end{cor}
        \begin{proposition} \label{prop:where} \end{proposition}
        \begin{theorem}     \label{thm:what}   \end{theorem}
    
        \noindent % Now, use a single \cref command to cross-reference them.
        \Cref{thm:this,lemma:that,prop:here,cor:there,prop:where,thm:what}.
        \end{document}
    
    • 如果你有定理、引理、推论、命题和其他环境共享一个计数器变量,cleveref手册建议您在定义这些类似定理的环境之前加载ntheorem或包(当然,在加载之前也是如此)。和包提供了一些非常方便的辅助幕后信息,有助于确定要将哪个名称(定理、引理、推论等)与交叉引用的对象关联,即使环境共享一个公共计数器。amsthmcleverefntheoremamsthmcleveref

    • 广泛的语言适配。如果文档的语言与英语不同,则必须在cleveref加载包时指定为选项。(也cleveref兼容babel。)截至 2016 年底,该包可以将交叉引用对象的名称适配为以下 14 种 [!] 语言:,,,,,(默认),,,,,,,,,,,brazilian和。Toby Cubitt (该包的作者和维护者)积极欢迎提交其他语言的对象名称。catalandanishdutchenglishesperantofrenchgermanitaliannorwegianrussianspanishswedishukrainiancleveref

      关于这些对象名称的呈现,有一条有趣的信息:在英语中,名词没有变格(包括交叉引用中使用的名词),也就是说,无论名词是用于主格、属格、与格、宾格等形式,它们的形式都是相同的。然而,这种简单性并不适用于许多其他语言。:-( 该cleveref包的单数和复数名词形式都是主格形式;如果你将包与英语以外的语言(或者,我想,法语、西班牙语和意大利语)一起使用,你应该使用命令\creflabel而不是\cref,并自己提供名词的适当大小写,如果名词没有以主格形式使用。即使你在使用命令时必须自己提供名词的名称\creflabel,你仍然可以从cleveref包的排序和压缩功能中受益。

    • 事实上,交叉引用的所有方面都可以完全定制。

    • 如果您要创建对类似定理的对象(特别是如果对象共享相同的计数器)的交叉引用,则包的手册cleveref建议ntheorem使用该选项加载包。thref

    • cleveref软件包与其他提供交叉引用命令的软件包完全兼容——包括variorefntheoremhyperref——只要cleveref最后加载

    • 使用该cleveref包时的一些注意事项:

      1. 包与包showonlyrefs的选项严重不兼容mathtools。所谓“严重不兼容”,是指如果cleveref与一起加载\usepackage[showonlyrefs]{mathtools},不仅\cref包含方程对象标签的命令会混乱,而且许多其他交叉引用包也会遇到严重问题。幸运的是,这个问题似乎是cleverefmathtools包之间唯一的不兼容性。
      2. 如果同时加载了footmischyperref软件包,则存在一些未解决的不兼容性问题,会影响对脚注的交叉引用。此问题还会影响提供交叉引用功能的各种其他软件包,包括cleveref
      3. 如果您的文档babel使用选项加载包french,请确保不要在任何和-family 指令:的参数中使用(“冒号”)字符。这是因为 (a) 该组合使角色“活跃”并且 (b)需要对其参数执行各种操作;如果角色处于活动状态,这些操作将崩溃。\label\crefbabel-french:\cref:

附录:进一步交叉引用的可能性

LaTeX 内核当前提供的交叉引用机制的一个主要限制是该\label命令仅写入两件物品.aux文件:的值柜台最后增加了\refstepcounter或类似的指令增加的,以及记录该\label指令的文档。例如,由于这一限制,我们无法轻易地写出类似“如第 yy 节中定理 ~xx 所示”的内容,因为 LaTeX 没有提供将定理编号信息与该定理所在章节编号关联起来的方法hyperrefcleveref包对 LaTeX 内核应用了一些巧妙的技巧,至少部分克服了这一限制。然而,这些技巧并不是那么强大;这种缺乏鲁棒性在一定程度上解释了为什么这两个包通常应该加载最后的

参考值Heiko Oberdiek 创建的软件包包旨在克服这一限制,它既为宏程序员提供了一个接口,又提供了几个使用该接口的软件包。该软件包不会修改基本的\label\ref\pageref命令。相反,它提供了命令\zlabel\zref,其中\zlabel可以编程为生成要写入文件的几条信息(而不仅仅是两条) .aux,并且可以将选项传递给其中\zref以指定应交叉引用哪条信息。

据我所知,到目前为止,主要的交叉引用包(包括hyperref)都没有利用该zref包提供的功能。但是,有几个较小的包或“模块”(也是由 Heiko Oberdiek 编写的)展示了该zref方法的一些潜在用途。例如,该模块abspage可以引用绝对文档的页码。这对于具有罗马格式和阿拉伯格式页码的文档(包括许多书籍!)非常有用:宏\zref[abspage]{LastPage}引用全部的文档的页数,与使用的编号样式无关。

答案2

超链接兼容性

hyperref包重新定义了许多 LaTeX 宏和 LaTeX 包,用于在文档中生成超链接,用于多种引用,例如引文、脚注、标题、目录条目和书签。这就是为什么它通常应该在其他包之后加载,但也有一些例外,例如以下一些包也提供交叉引用功能。请参阅:哪些包应该在 hyperref 之后加载而不是之前加载?

  • nameref:兼容,它是hyperrefbundle 的一部分。可以在hyperref它之前或之后加载。

  • prettyref:适用于hyperref,先加载hyperref

      \usepackage{prettyref}
      \usepackage{hyperref}
    
  • titleref:有效,usetoc不推荐选项

      \usepackage{nameref}
      \usepackage{titleref}% without usetoc
      \usepackage{hyperref}
    
  • varioref:部分支持,请先加载hyperref

      \usepackage{nameref}
      \usepackage{varioref}
      \usepackage{hyperref}
    
  • cite:从 5.0 版开始,兼容hyperrefbackref。早期版本不兼容,hyperrefREADME 文件中提供了一种解决方法。

  • cleveref:兼容,之后加载hyperref

      \usepackage{hyperref}
      \usepackage{cleveref}
    
  • amsrefs:兼容,之后加载hyperref

      \usepackage{hyperref}
      \usepackage{amsrefs}
    
  • ntheoremhyperref通过hyperref选项提供一定的兼容性,并且必须在之前加载hyperref

      \usepackage[hyperref]{ntheorem}
      \usepackage{hyperref}
    
  • memoir: 兼容的

cleveref 兼容性

来自手册:

cleveref软件包增强了 LaTeX 的交叉引用功能,允许根据交叉引用的“类型”(方程式、章节等)和使用交叉引用的上下文自动确定交叉引用的格式。

cleveref应在所有其他包之后加载,以避免出现问题。

  • hyperref:兼容,它也支持backref选项

  • nameref:兼容

  • titleref:兼容

  • varioref: 支持,cleveref重新定义一些宏

  • fancyref:不支持,cleveref提供增强功能

  • ntheorem:不受支持,但cleveref重新定义ntheorem\thref

  • memoir: 兼容的

答案3

包功能

各个包提供的交叉引用功能可以划分如下:

  • 根据引用的标签类型格式化参考文献(例如,排版“第 3 节”而不是仅“3”)。类似以下软件包fancyrefprettyref或者refstyle提供半自动解决方案,因为您必须遵守标签的某些名称前缀或使用特定于类型的引用宏。全自动解决方案由cleverefhyperref

  • 对引用标签序列进行排序和压缩。这似乎仅适用于cleveref

  • 引用标签的名称而不是其编号(例如,章节标题或浮动标题)。例如,这是通过以下方式实现的:namereftitleref

  • 排版“智能”页面引用(即,对于第 3 页的引用,排版为“上一页”,而不是“第 2 页”)。这是varioref

  • 添加交叉引用的超链接。这是(令人惊讶的)无可争议的领域hyperref

上面列出的所有软件包都是“通用的”(即,适用于任何类型的标签)。其他软件包如theoremref或者ntheorem提供上述一些功能,但仅适用于定理。

相关内容