我想要做的事情如下:
我想引用前面的一段文字。我可以使用\label
和\ref
命令来实现,如下所示:
\label{x} Lorem ipsum dolor sit amet, consectetur adipiscing elit.
See page \ref{x}.
这将在第二行代码中创建类似“参见第 1 页”的内容。
但是,假设上面的第一行代码中的句子跨越了多页。那么我希望读出的内容是“查看第 1-2 页”。现在我可以通过执行以下操作来解决这个问题:
\label{x} Lorem ipsum dolor sit amet, consectetur adipiscing elit. \label{y}
See pages \ref{x}-\ref{y}.
这将在第二行代码中创建类似“查看第 1-2 页”的内容。
但是,这种方式不够灵活。如果句子没有跨越几页,我最终会得到“参见第 1-1 页”这样的结果,这绝对是我不希望看到的。
所以,我想你可以看出我的困境。我有什么办法可以做我想做的事吗?
答案1
这是一个使用 varioref
包,正如 Martin 提到的:
\documentclass{article}
\usepackage{blindtext}
\usepackage{varioref}
\usepackage[english]{babel}
\begin{document}
\label{text1start}\blindtext[5]\label{text1stop}
\label{text2start}\blindtext[2]\label{text2stop}
See \vpagerefrange{text1start}{text1stop} and \vpagerefrange{text2start}{text2stop}
\end{document}
在这种情况下它的输出是:
答案2
标准\label
s 通常仅用于分段命令和标题等,而不用于文本片段。此外,它的实现由 等软件包重新定义,hyperref
因此很难使用它们并确保与现有软件包 100% 兼容。
相反,您可以定义一个自己的标签宏,例如\textlabel
,然后\textref
它接受两个参数并检查两者是否引用同一页面。以下代码执行此操作。一个可能的改进是不对“页面”文本进行硬编码,而是使用可以更改的宏,例如更改为不同的语言。
\documentclass{article}
\usepackage{hyperref}
\usepackage{lipsum}
\makeatletter
\newcommand*{\newtextlabel}[1]{\global\@namedef{textlabel@#1}}
\newcommand*{\textlabel}[1]{%
% Write label which holds current page
\@bsphack
\protected@write\@auxout{}%
{\string\newtextlabel{#1}{\thepage}}%
\@esphack
% Also add a normal label to be able to use `hyperref`s `\pageref` later
\label{#1}%
}
\newcommand*{\textref}[2]{%
\begingroup
% Get saved label values:
\expandafter\let\expandafter\labela\csname textlabel@#1\endcsname
\expandafter\let\expandafter\labelb\csname textlabel@#2\endcsname
\ifx\labela\labelb
page~\pageref{#1}%
\else
pages~\pageref{#1}--\pageref{#2}%
\fi
\endgroup
}
\makeatother
\begin{document}
\section{Test}\label{test}
\textlabel{a}
\lipsum[1]
\textlabel{b}
\lipsum[2]
\textlabel{x}
\lipsum
\textlabel{y}
\lipsum
See \textref{a}{b} and \textref{x}{y}.
\end{document}
编辑:\pageref
在最终输出中添加了使用。该varioref
包可能也很有趣。