关注该帖子使用 xr-hyper 包制作多卷书时如何启用智能参考?我尝试使用zref
@Andrew Swann 建议的包来详细说明所需的解决方案。不幸的是,我遇到了另一个问题,似乎是 中的一个错误zref
。所以我决定在这里发布问题描述。我不确定这是否是发布此类问题的合适地方,但 的作者 Heiko Oberdiekzref
没有回复我的电子邮件。
根据@Andrew Swann的建议,我尝试使用 Heiko 的软件包在多卷书的两卷之间提供交叉引用zref
。此外,我引入了一个属性chaptervalue
以提供智能引用,当方程式来自引用它的同一章节时,它会隐藏方程式编号的章节部分。这是 MWE。它包含 3 个文件。
通用代码保存在test-zref-common.tex
:
% Load packages abd declare external docs.
\usepackage[user,xr]{zref}
\ifnum\Volume=1
% comment the line below to avoid errors
\zexternaldocument{test-zref-2}% <============
\makeatletter
\zref@ifpropundefined{volume}{
\zref@newprop{volume}{\Volume}
\zref@newprop{chaptervalue}{\the\value{chapter}}
}{}
\zref@localaddprops{main}{volume,chaptervalue}
\makeatother
\else
\zexternaldocument{test-zref-1}
\makeatletter
\zref@ifpropundefined{volume}{
\zref@newprop{volume}{\Volume}
\zref@newprop{chaptervalue}{\the\value{chapter}}
}{}
\zref@localaddprops{main}{volume,chaptervalue}
\makeatother
\fi
% Reset default equation numbering
\usepackage{amsmath}
\numberwithin{equation}{chapter}
\renewcommand{\theequation}{\arabic{equation}}
% Define \sref and \seqref macros for smart cross-references of equations
\makeatletter
\newcommand\ifcurrentchapter[3]{%
\def\temp@a{\number\value{chapter}}%
\def\temp@b{\zref@extract{#1}{chaptervalue}}%
\if\temp@a\temp@b%
#2%
\else%
#3%
\fi%
}
\newcommand{\sref}[1]{\hbox{\ifcurrentchapter{#1}{}{\zref[chaptervalue]{#1}.}\zref{#1}}}
\newcommand{\seqref}[1]{(\sref{#1})}
\makeatother
% Define a macro to print test text
\newcommand{\testtext}{
Compare \number\value{chapter} with \zref[chaptervalue]{ch:1}. Equal: \ifcurrentchapter{ch:1}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:2}. Equal: \ifcurrentchapter{ch:2}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:17}. Equal: \ifcurrentchapter{ch:17}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:18}. Equal: \ifcurrentchapter{ch:18}{Yes}{No}
}
普通文件由第 1 卷读取(test-zref-1.tex
)
\documentclass[oneside]{book}
\newcommand{\Volume}{1}
\input{test-zref-common}
\begin{document}
\chapter{1 in Volume 1}
\label{ch:1}\zlabel{ch:1}
\testtext
\begin{equation}
eq1
\label{1.1}\zlabel{1.1}
\end{equation}
\begin{equation}
eq2
\label{1.2}\zlabel{1.2}
\end{equation}
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2}.
\seqref{17.1}, \seqref{17.2}; \seqref{18.1}, \seqref{18.2}.
\chapter{2 in Volume 2}
\label{ch:2}\zlabel{ch:2}
\testtext
\begin{equation}
eq3
\label{2.1}\zlabel{2.1}
\end{equation}
\begin{equation}
eq4
\label{2.2}\zlabel{2.2}
\end{equation}
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2}.
\seqref{17.1}, \seqref{17.2}; \seqref{18.1}, \seqref{18.2}.
\end{document}
第 2 卷(test-zref-1.tex
):
%\documentclass{scrbook}
\documentclass[oneside]{book}
\newcommand{\Volume}{2}
\setcounter{chapter}{16}
\input{test-zref-common}
\begin{document}
\chapter{1 in Volume 2}
\label{ch:17}\zlabel{ch:17}
\testtext
\begin{equation}
eq1
\label{17.1}\zlabel{17.1}
\end{equation}
\begin{equation}
eq2
\label{17.2}\zlabel{17.2}
\end{equation}
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2}.
\seqref{17.1}, \seqref{17.2}; \seqref{18.1}, \seqref{18.2}.
\chapter{2 in Volume 2}
\label{ch:18}\zlabel{ch:18}
\testtext
\begin{equation}
eq3
\label{18.1}\zlabel{18.1}
\end{equation}
\begin{equation}
eq4
\label{18.2}\zlabel{18.2}
\end{equation}
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2}.
\seqref{17.1}, \seqref{17.2}; \seqref{18.1}, \seqref{18.2}.
\end{document}
如果我从卷 #2 引用卷 #1,则效果很好(即当行
\zexternaldocument{test-zref-2}
已从 中删除test-zref-common.tex
)。但是,当我尝试引用两个卷(从卷 #2 引用卷 #1 以及从卷 #1 引用卷 #2)时,它会失败。zref
抱怨该chaptervalue
属性已定义。附件演示了此问题。
这是 MWE 中的一个 bugzref
还是一个错误?
答案1
这些错误都存在于您的代码中,都在通用文件中。首先,您应该在指定外部文档之前定义属性。其次,您需要在测试中使用\ifnum
not 。以下是修改后的通用文件:\if
% Load packages abd declare external docs.
\usepackage[user,xr]{zref}
\makeatletter
\zref@newprop{volume}{\Volume}
\zref@newprop{chaptervalue}{\the\value{chapter}}
\zref@localaddprops{main}{volume,chaptervalue}
\makeatother
\ifnum\Volume=1
\zexternaldocument{test-zref-2}% <============
\else
\zexternaldocument{test-zref-1}
\fi
% Reset default equation numbering
\usepackage{amsmath}
\numberwithin{equation}{chapter}
\renewcommand{\theequation}{\arabic{equation}}
% Define \sref and \seqref macros for smart cross-references of equations
\makeatletter
\newcommand\ifcurrentchapter[3]{%
\def\temp@a{\number\value{chapter}}%
\def\temp@b{\zref@extract{#1}{chaptervalue}}%
\if\relax\temp@a\else\if\relax\temp@b\else
\ifnum\temp@a=\temp@b%
#2%
\else%
#3%
\fi%
\fi\fi
}
\newcommand{\sref}[1]{\hbox{\ifcurrentchapter{#1}{}{\zref[chaptervalue]{#1}.}\zref{#1}}}
\newcommand{\seqref}[1]{(\sref{#1})}
\makeatother
% Define a macro to print test text
\newcommand{\testtext}{
Compare \number\value{chapter} with \zref[chaptervalue]{ch:1}. Equal: \ifcurrentchapter{ch:1}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:2}. Equal: \ifcurrentchapter{ch:2}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:17}. Equal: \ifcurrentchapter{ch:17}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:18}. Equal: \ifcurrentchapter{ch:18}{Yes}{No}
}
这将在第二个文档的第 17 章中产生以下页面:
答案2
扩展了 @Andrew Swann 给出的答案,我在公共块中更新了他的代码,以避免在第一次运行 LaTeX 时在源文件上生成错误,因为标签的值尚不清楚。这里的关键点是应该用chaptervalue
默认值定义属性。我认为它等于-1
。然后,\ifcurrentchapter
可以修改宏以检查是否\temp@b
为负数,就像第一次运行时一样。此外,我添加了hyperref
和xr-hyper
包,以便允许在书中的卷之间进行超引用。
以下是最终版本test-zref-common.tex
:
% Load packages and declare external docs.
\usepackage{xr-hyper}% <== load xr-hyper package
\usepackage[unicode,colorlinks]{hyperref}% <== load hyperref package
\usepackage[user,xr]{zref}
\makeatletter
\zref@newprop{volume}{\Volume}
\zref@newprop{chaptervalue}[-1]{\the\value{chapter}}% <= note the default value [-1]
\zref@localaddprops{main}{volume,chaptervalue}
\makeatother
\ifnum\Volume=1
\externaldocument{test-zref-2}% <== declare external doc for xr-hyper
\zexternaldocument{test-zref-2}% <== declare external doc for zref
\else
\externaldocument{test-zref-1}
\zexternaldocument{test-zref-1}
\fi
% Reset default equation numbering
\usepackage{amsmath}
\numberwithin{equation}{chapter}
\renewcommand{\theequation}{\arabic{equation}}
% Define \sref and \seqref macros for smart cross-references of equations
\makeatletter
\newcommand\ifcurrentchapter[3]{%
\def\temp@a{\number\value{chapter}}%
\def\temp@b{\zref@extract{#1}{chaptervalue}}%
\ifnum\temp@a=\temp@b%
#2%
\else%
\ifnum\temp@b<0
#2%
\else
#3%
\fi%
\fi%
}
%\newcommand{\sref}[1]{\hbox{\ifcurrentchapter{#1}{}{\zref[chaptervalue]{#1}.}\zref{#1}}}
% note \hyperref in the definition of \sref
\newcommand{\sref}[1]{\hyperref[#1]{\hbox{\ifcurrentchapter{#1}{}{\zref[chaptervalue]{#1}.}\zref{#1}}}}
\newcommand{\seqref}[1]{(\sref{#1})}
%\newcommand{\seqref}[1]{(\hyperref[#1]{\hbox{\sref{#1}}})}
\makeatother
% Define a macro to print test text
\newcommand{\testtext}{
Chapter \sref{ch:1}, Chapter \sref{ch:2},
Chapter \sref{ch:17}, Chapter \sref{ch:18}.
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:1}. Equal: \ifcurrentchapter{ch:1}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:2}. Equal: \ifcurrentchapter{ch:2}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:17}. Equal: \ifcurrentchapter{ch:17}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chaptervalue]{ch:18}. Equal: \ifcurrentchapter{ch:18}{Yes}{No}
\par
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2}.
\par
\seqref{17.1}, \seqref{17.2}; \seqref{18.1}, \seqref{18.2}.
}
\endinput