LaTeX教程(016)-LaTeX文档结构(16)

server/2024/10/19 19:21:43/

LaTeX教程(016)- LaTeX \LaTeX LATEX文档结构(16)

接上一讲

我们前面知道,\vref是对\ref的升级,而varioref包也提供了一个对\pageref升级的命令\vpageref。它和\vref的原理很相似,内置了一些判断。

\vpageref[same-page][other-page]{key}

在不指定选项的前提下,它所输出的内容就是\vref字符串去掉其中的\ref字符串。例如,如果\ref的输出是3.3,而\vref输出(我们假设引用和引用对象在彼此的对面)就是3.3 on the facing page,那么\vpageref的输出就是on the facing page,没有前面\ref生成的索引字符串。其它情形依此类推,分别是on the preceding page,on the following page以及on page x。只有引用和引用对象在同一页的时候和\vref不同,这种情况下,\vpageref会输出on the current page。该情形下的字符串被存储在命令\reftextcurrent中,重定义这个命令可以将"on the current page"改成其他你想要的字符串。

另外,\vpageref生成的字符串中,只有on page x中的x可以被自动转换为超链接。

注意,不管使用\vref还是\vpageref,最好在命令前后分别放置一个空格,否则它们生成的字符串很可能会和前后文本连在一起。当然,如果是在一个段落的开头,那么前面的空格就不需要了。

\vpageref\vref多了一个选项。其中same-page选项和\vrefsame-page选项作用相同,用来代替引用和引用对象在同一页时的输出字符串。而other-page用于其他情况,也就是引用和引用对象不在同一页的情况。这种情况下,other-page中内容会放置在原本的输出内容的前面。如"other-page+on the preceding page"等。我们可以做个测试:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}
\usepackage[colorlinks=true,linkcolor=blue]{hyperref}
\begin{document}\chapter{A chapter}
\vpageref[same][other]{test}\kant[1]\vpageref[same][other]{test}\kant[2]\label{test}\kant[3]\vpageref[same][other]{test}
\chapter{A chapter two}
\vpageref[same][other]{test}
\end{document}

这里不截图了,自行编译一下。因为有交叉引用,记得要编译两遍。

实际上,像"on the preceding page","on the following page"等文本,也有存储它们的命令,它们分别是

\reftextafter
\reftextafter
\reftextfacebefore
\reftextfaceafter

我们将在下文中讲解这些命令。

\vpageref的星号变体\vpageref*和其原型不同的是它不会生成超链接(注意,经笔者本人测试,该机制并不总是有效的)。

\vpagerefrange命令,其形式如下:

\vpagerefrange[same-page]{first}{last}
\vpagerefrange*[same-page]{first}{last}

它和\vpageref很像,不同的地方是它有两个必选参数,而只有一个选项。该命令用两个索引来确定一个范围,它可以生成如"on page 15-18"这样的索引字符串。我们用一个例子演示一下:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}
\usepackage[colorlinks=true,linkcolor=blue]{hyperref}
\begin{document}\chapter{A chapter}
\label{chap:one}\label{chap:oone}
\kant[1]\kant[2]\chapter{A chapter two}\label{chap:two}\label{chap:twoo}\dots some text \dots\vpagerefrange{chap:one}{chap:oone}\vpagerefrange{chap:two}{chap:twoo}\vpagerefrange{chap:one}{chap:two}\vpagerefrange[Customized text]{chap:two}{chap:twoo}\end{document}

编译(只截取部分,记得编译两遍):
在这里插入图片描述

如上面的例子所呈现的那样,如果两标签在同一页上,则只会显示一个页码。更特别地,如果两个标签都在当前页上,并且没有指定same-page选项时,则会显示"on the current page"。这句文本被存储在命令\reftextcurrent中,可以重定义它。而如果指定了该选项,那么此种情况下就会显示我们在选项中自定义的文本(注意,选项只对两个标签都在当前文件时有效)。其它的情况(两个标签在不同页时)则会显示"on pages x-xx"。如果你用了hyperref,那么两个页码都会生成单独的链接,可以跳转至各自的页码。

和前面讲过的命令一样,星号形式的命令可以抑制hyperref包生成链接(注意,该机制也并不总是有效的)。

\vrefrange,它的命令形或如下:

\vrefrange[same-page]{first}{last}

它可以简单地表示成一个由代码:

\ref{first} to \ref{last} \vrefpagerange[same-page]{first}{last}

定义而成的命令。我们在期望表示"chapter 2 to chapter 4 on pages 11-28"这样的索引字符串时,才需要使用它。我们用一个例子演示:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}
\usepackage[colorlinks=true,linkcolor=blue]{hyperref}
\begin{document}
% 回忆一下上一篇,\labelformat是用来定制索引字符串的
\labelformat{chapter}{chapter~#1}\chapter{A chapter}
\label{chap:one}\kant[1]\kant[2]\chapter{A chapter two}\label{chap:two}\dots some text \dots\vrefrange{chap:one}{chap:two}\end{document}

编译:

在这里插入图片描述

定义你自己的索引命令

有时候你可能会想用varioref包的内部特性来定义你自己的索引命令,该包为此提供了三个辅助命令。

\vpagerefcompare{key1}{key2}{true-code}{false-code}

该命令比较key1key2处的页码,并且根据比较结果,决定执行true-code还是false-code。如果两个标签的页码相等,就执行true-code,否则执行false-code

\vpagerefnearby{key}{true-code}{false-code}

该命令会判断标签\labek{key}是不是在附近,通过判断它生成的页索引是文本的(如previous, current, next等)还是一个带有数字页码的字符串。如果是前者,执行true-code,否则(后者)执行false-code

\vrefpagenum{cmd}{key}

该命令允许我们定义自己的小命令,以实现类似于前面两个命令所提供的功能。第二个命令是一个标签,也就是我们用在\label中的东西。第一个参数是任意一个命令(注意必须是自定义的,不能和已有的命令重复),在使用了上述命令之后,cmd就会存储key的页码。我们用一个例子演示一下:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\begin{document}\chapter{A chapter}
\label{chap:one}\vrefpagenum{\mycmd}{chap:one} %使用\mycmd存储chap:one的页码\mycmd\end{document}

编译:
在这里插入图片描述

这些命令几乎不会用到,这里不详细展开。

语言选项

该包支持由babel系统(第13章会讲到)定义的选项,因此,像`\usepackage[ngerman]{varioref},这样正文中的标签就会生成符合德语的索引字符串。如果你的文档是多语言的,那么就要指定所有的语言。如果你所用的语言不在选项中,那么你就需要定制自己的索引字符串,定制的方法我们后面讲。

个性化的定制

为了更进一步的定制,生成的索引字符串都是由宏来定义的,也就是说,它们存储在一些命令中。在默认情况下(没有设置其他语言的情况下),如果标签在索引的前一页,但不在对面,索引就会生成字符串"on the preceding page"。该文本存储在命令\reftextbefore。而如果标签在索引的前一页,并且它们相互在对方的对面一页,即,标签在左手页,索引在右手页,那么索引就会生成字符串"on the facing page"。该文本存储在命令\reftextfacebefore中。

类似的,如果如果标签在索引的后面一页,但不在对面,索引就会生成字符串"on the following page"。这段文本存储在命令\reftextafter中。而如果标签在索引后面一页,并且在对面,那么就会生成"on the facing page"。该文本存储在命令\reftextfaceafter中。

如上一篇所说,\reftextfacebefore\reftextfaceafter只在双页模式的文档类中才会生效。

而标签和索引在同一页时,生成的索引字符串被存储在命令\reftextcurrent中。

这些命令都可以被重定义,用你想用的语言。

我们作个演示:

\documentclass{ctexbook} % 注意我们要使用到中文
% 因此将文档类改为ctexbook,并且记得使用xelatex引擎编译
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}
\usepackage[colorlinks=true,linkcolor=blue]{hyperref}
\begin{document}
\chapter{Chapter one}\renewcommand{\reftextbefore}{在上一页}
\renewcommand{\reftextafter}{在下一页}
\renewcommand{\reftextfacebefore}{在左手页}
\renewcommand{\reftextfaceafter}{在右手页}
\renewcommand{\reftextcurrent}{在当前页}\label{test01}\vpageref{test01}\vpageref{test02}\kant[1]
\label{test02}\vpageref{test01}\vpageref{test03}\kant[2]
\label{test03}\vpageref{test02}\end{document}

使用中文时记得使用xelatex引擎编译,并且编译两遍。这里不截图了,读者自行编译。

当标签和索引相距较远时,索引就会调用\reftextfaraway命令。该命令和前面那些命令不同,它有一个参数。默认情况下,它存储的是"on page x"这样的字符串,我们在重定义它的时候可以使用\pageref来生成页码。例如,我们在前面的例子中加上一行重定义命令:

\renewcommand\reftextfaraway[1]{在第~\pageref{#1}~页}

然后在最后的\vpageref{test02}代码后面加上一行\vpageref{test01},再编译就会生成索引字符串"在第 1 页"。

\reftextpagerange\reftextlabelrange的内部定义都非常简单,它们分别通过两个\pageref\ref来表示从一个标签到另一个标签的范围。

如果前面的例子你都自己编译过,那么你可能会发现这样的现象: 不会连续出现两个相同的文本型索引(像on the current page, on the previous page这种)。我们用一个例子演示一下:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\begin{document}
\chapter{Chapter one}\label{test01}sometext\dots\vpageref{test01}\vpageref{test01}\vpageref{test01}\vpageref{test01}\end{document}

编译:

在这里插入图片描述

哪怕相邻索引对应的是两个不同的标签的key,只要调用了同一个\reftext...命令,就会显示不同的文本,中间隔着一些内容也不影响:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}
\begin{document}\chapter{Chapter one}\label{test01}sometext\dots\vpageref{test01}\kant[1]
\label{test02}\vpageref{test02}\end{document}

内容较多,请读者自行编译。

如果同一个\reftext...命令连续出现多次,则会有两个字符串轮流出现的现象,如前面的例子所示。

但是,如果两个相同的\reftext...命令之间,隔着一个不同的\reftext...命令,就会打破这种限制,也就是说,这两个相同的\reftext...命令生成的文本也可能是相同的。我们演示一下:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}
\begin{document}\chapter{Chapter one}\label{test01}sometext\dots\vpageref{test01}\vpageref{test02}\vpageref{test01}\kant[1]
\label{test02}\vpageref{test01}\vpageref{test02}\end{document}

请读者自行编译。

会出现这种现象的不仅仅是\reftextcurrent,文本型索引的那几个命令都有这样的特性。

这是因为varioref包想要将索引文本插入到日常用语中,而为了避免语言上的重复,给每一个\reftext...命令准备了两个不同的字符串,使它们轮流出现。varioref包通过调用\reftextvario命令实现这一特性。该命令有两个参数,它使得这两个参数中的内容轮流出现。我们用一个例子演示:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}
\begin{document}\chapter{Chapter one}sometext\dots\reftextvario{test01}{test02}\reftextvario{test01}{test02}\reftextvario{test01}{test02}\end{document}

编译:
在这里插入图片描述

而默认情况下,varioref是像如下这种方式定义这些索引命令的:

\newcommand\reftextfaceafter{on the \reftextvario{facing}{next} page}
\newcommand\reftextfacebefore{on the \reftextvario{facing}{preceding} page}
\newcommand\reftextafter {on the \reftextvario{following}{next} page}
\newcommand\reftextbefore{on the \reftextvario{preceding page}{page before}}
\newcommand\reftextcurrent {on \reftextvario{this}{the current} page}
\newcommand\reftextfaraway [1]{on page~\pageref{#1}}
\newcommand\reftextpagerange [2]{on pages~\pageref{#1}--\pageref{#2}}
\newcommand\reftextlabelrange[2]{\ref{#1} to~\ref{#2}}

这些命令你都可以根据自己的需求自定义它们。

有些用户可能不喜欢文本型的索引,那么我们可以将这些\reftext...命令定义为on page~\thevpagerefnum\thevpagerefnum会获取到当前索引的页码。例如:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}
\begin{document}\renewcommand\reftextcurrent {on page~\thevpagerefnum}
\renewcommand\reftextbefore {on page~\thevpagerefnum}\chapter{Chapter one}sometext\dots
\label{test01}\vpageref{test01}\kant[1]\vpageref{test01}\end{document}

自行编译一下,两处索引都会显示为"on page 1"。

如果你想让所有的文本型索引都不显示(被忽略,而不是变成页码),只显示那些页码索引,那么就把\reftext...命令定义成{\unskip}。例如:

\documentclass{book}
\usepackage[a5paper,margin=1.5in]{geometry}
\usepackage[nospace]{varioref}
\usepackage{kantlipsum}\begin{document}\renewcommand\reftextcurrent {\unskip}
\renewcommand\reftextbefore {\unskip}\chapter{Chapter one}sometext\dots
\label{test01}\vpageref{test01}\vpageref{test02}\kant[1]\vpageref{test01}\label{test02}\end{document}

编译完你会发现,只有一个\vpageref{test02}生成的"on the next page",其他的都被忽略了。这是因为\reftextbefore没有被重定义。

注意,这里的{\unskip}是必要的,否则会生成一段空白间距。

有些语言具有完全不同的句子结构,以至于仅调整个别的字词和短语是不够的。为解决这样的问题,varioref包还提供了四个命令,它们分别是\vrefformat\Vrefformat, \vrefrangeformat\fullrefformat。我们很少用到,这里不再详述。感兴趣的读者可以查阅包文档。

一些要小心的问题

考虑这样一种情形,如果文本型索引在换页时从中间断开,会怎么样呢?例如:

table 5 on the current

<换页>

page

这表示"表格5"在哪一页呢?varioref以索引的末尾为参考点,也就是说,这种情形下,"表格5"在"page"那一页,而不在"table 5 on the current"那一页。如果table 5在上面一页,则索引则会这样显示:

table 5 on the following<换页>page

LaTeX \LaTeX LATEX有时候会因为索引的断页产生一些错误,例如,考虑这样一种情形:

table 5 on the following<换页>page"表格5"

此时 LaTeX \LaTeX LATEX发现标签文本是错的,因为"表格5"和page在同一页,系统会将标签文本换成"table 5 on this page"。不幸的是,该文本比"table 5 on the following page"要短,情形就变成了这样:

table 5 on this page<换页>"表格5"

现在标签和索引又不在同一页了,标签文本又是错的了,而前一种却是对的。 LaTeX \LaTeX LATEX会因此进入死循环。无论使用哪种算法,都很难令人满意。出现这样的问题时,需要用户手动调整标签的索引的位置。

在编辑文档时,可以在导言区放置一个\vrefwarning命令,它可以将这类错误转换为警告,而在调用varioref包时,指定draft选项,也有同样的效果。

在导言区放置\vrefshowerrors可以让varioref包在检测到可能的循环时停止,而在调用varioref包时,指定final选项,也有同样的效果。这实际上也是默认设置。

如果你希望在文档的某些地方仅禁用错误,这些命令也可以在文档内部使用。

另外,如果你不想要我们前面演示的那种轮流切换的文本型索引,又不想重定义每个\reftext...命令,那么就可以重定义\reftextvario命令,使得它只显示第一个参数或者第二个参数(两个备用文本中的一个):

\renewcommand\reftextvario[2]{#1}
不指定nospace选项时,该包会有何表现

varioref包设计之初,它有一个特殊的行为: 它的命令会移除前面的空格,并且会增加一个自己的空格。因此,你可以就算不在\vpageref前面放置空格,包也会将索引放置合适的位置。但是这样有一个问题,如果我不想要索引前面的空格呢? 例如,我们想要将索引放在一个括号里(如(\vpageref{xxx})),多一个空格就不合适了。宏包提供了星号形式的命令来取消前面的空格,也就是说,如果我们不想在前面加一个空格,就使用\vpageref*{xxx}

但这种方法和其他包的配合不太好,因此我们总是建议指定nospace选项。如果指定了nospace选项,那么常规的索引命令(\vpageref{xxx})前面都不会自动增加空格,需要的时候,要手动添加(一般情况下都需要)。


http://www.ppmy.cn/server/133133.html

相关文章

电脑桌面自己变成了英文Desktop,怎么改回中文

目录 前言找到Desktop查看位置查找目标修改文件名为桌面重启电脑 或 重启 Windows 资源管理器CtrlShiftEsc 打开任务管理器找到 Windows 资源管理器重启 Windows 资源管理器 查看修改结果 前言 许多人在使用电脑的时候发现&#xff0c;我们经常使用的桌面&#xff0c;不知道因为…

C语言笔记(数据的存储篇)

目录 1.数据类型的详细介绍 2.整型在内存中的存储&#xff1a;原码、反码、补码 3.大小端字节序介绍及判断 4.浮点型的内存中的存储解析 1.数据类型的详细介绍 下述是内置类型&#xff1a; char // 字符数据类型 short // 短整型 int // 整型 long …

spring底层原理

本文参考黑马程序员的spring底层讲解&#xff0c;想要更详细的可以去看视频。 另外文章会每日更新&#xff0c;大概持续1个月&#xff01;&#xff01;&#xff01;每天更新一讲 这部分比较抽象&#xff0c;要经常复习&#xff01;&#xff01;&#xff01; 一、BeanFactory与A…

自然语言处理 (NLP) 的 5 个步骤

自然语言处理 (NLP) 的 5 个步骤 引言 如今&#xff0c;我们的世界在数字化连接方面达到了前所未有的水平。信息、见解和数据不断争夺我们的注意力&#xff0c;我们不可能全部消化。对于你的企业来说&#xff0c;挑战在于了解客户和潜在客户对你的产品和服务的看法&#xff0c;…

LeetCode-四数相加-Java

一、题目 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 示例 1&#xff1a; 输入&#xff1a;nums1…

Vue.js 学习总结(10)—— Vue 前端项目性能优化常用技巧

1. 使用路由懒加载 在 Vue.js 应用中&#xff0c;路由懒加载可以延迟加载路由组件直到它们被需要时才加载&#xff0c;从而减少应用的初始加载时间。示例代码&#xff1a; // router/index.js import { createRouter, createWebHistory } from vue-router;const Home () >…

C++中的vector使用与实现

一、vector的使用 1.1 vector的定义 是一种类模板 template < class T, class Alloc allocator<T> > class vector; 其中的模板参数Alloc是在使用空间配置器&#xff08;内存池&#xff09;&#xff0c;并给了缺省值&#xff0c;暂时不深究 1.2遍历方式 1.…

[旧日谈]关于Qt的刷新事件频率,以及我们在Qt的框架上做实时的绘制操作时我们该关心什么。

[旧日谈]关于Qt的刷新事件频率&#xff0c;以及我们在Qt的框架上做实时的绘制操作时我们该关心什么。 最近在开发的时候&#xff0c;发现一个依赖事件来刷新渲染的控件会导致程序很容易异常和崩溃。 当程序在运行的时候&#xff0c;其实软件本身的负载并不高&#xff0c;所以…