在编写多卷书时,我使用了一种智能交叉引用方法,如使用 Zref 包在 2 个卷之间进行智能交叉引用。那里描述的\sref
和\seqref
命令添加到链接中,这些链接由通常的\ref
和\eqref
命令打印,章节号作为前缀“不。“如果目标(例如,一个方程式)位于不同的章节不如果对象位于当前章节,则不打印章节号。
在我添加附录之前,一切都很好。事实是声明将计数器\appendix
重置chapter
为零。因此,chapter
正文第一章和第一个附录中的计数器具有相同的值 1。因此,\seqref
附录 A 中指向第 1 章中方程的命令将打印不带前缀“1”的方程编号。相反,\seqref
第一章中指向附录 A 中方程的命令将打印不带前缀“A”的方程编号。
下面的一个最小工作示例与上面引用的帖子略有不同。主要文本和代码在两个文件中的分离被保留,尽管这对于说明上述问题来说不是必须的。通用代码写在test2-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]{zref}
\makeatletter
\zref@newprop{chaptervalue}[-1]{\the\value{chapter}}% <= note the default value [0]
%%\zref@newprop{chaptervalue}[0]{\thechapter}% <= note the default value [-1]
\zref@localaddprops{main}{chaptervalue}
\makeatother
% 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@a{\thechapter}%
\def\temp@b{\zref@extract{#1}{chaptervalue}}%
\ifnum\temp@a=\temp@b%
%%\if\temp@a\temp@b%
#2%
\else%
\ifnum\temp@b<0
%%\if\temp@b=0
#2%
\else
#3%
\fi%
\fi%
}
\newcommand{\sref}[1]{\hyperref[#1]{\hbox{\ifcurrentchapter{#1}{}{\zref[chaptervalue]{#1}.}\zref{#1}}}}
\newcommand{\seqref}[1]{(\sref{#1})}
\makeatother
% Define a macro to print test text
\newcommand{\testtext}{
Chapter \sref{ch:1}, Chapter \sref{ch:2}, Chapter \sref{ch:1A}.
\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:1A}. Equal: \ifcurrentchapter{ch:1A}{Yes}{No}
\par\noindent
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2}; \seqref{1A.1}, \seqref{1A.2}.
}
\endinput
主文件只是读取代码文件:
\documentclass[oneside]{book}
\input{test2-zref-common}
\begin{document}
\chapter{1 in Volume 1}\label{ch:1}\zlabel{ch:1}
\testtext
\begin{equation}
eq1.1
\label{1.1}\zlabel{1.1}
\end{equation}
\begin{equation}
eq1.2
\label{1.2}\zlabel{1.2}
\end{equation}
\chapter{2 in Volume 2}\label{ch:2}\zlabel{ch:2}
\testtext
\begin{equation}
eq2.1
\label{2.1}\zlabel{2.1}
\end{equation}
\begin{equation}
eq2.2
\label{2.2}\zlabel{2.2}
\end{equation}
\appendix
\chapter{A in Volume 1}\label{ch:1A}\zlabel{ch:1A}
\testtext
\begin{equation}
eq1A.1
\label{1A.1}\zlabel{1A.1}
\end{equation}
\begin{equation}
eq1A.2
\label{1A.2}\zlabel{1A.2}
\end{equation}
\end{document}
我尝试修改代码文件来解决这个问题。首先,我更改了属性的声明chatervalue
,以便将\thechapter
命令的当前值写入文件.aux
,而不是计数器的值chapter
:
%%\zref@newprop{chaptervalue}[-1]{\the\value{chapter}}
\zref@newprop{chaptervalue}[0]{\thechapter}
但是,我无法更改命令,\ifcurrentchapter
以便它正确地将\thechapter
值与chaptervalue
属性进行比较。该命令的以下定义\ifcurrentchapter
总是给出错误值。
\newcommand\ifcurrentchapter[3]{%
%%\def\temp@a{\number\value{chapter}}%
\def\temp@a{\thechapter}%
\def\temp@b{\zref@extract{#1}{chaptervalue}}%
%%\ifnum\temp@a=\temp@b%
\if\temp@a\temp@b%
#2%
\else%
%%\ifnum\temp@b<0
\if\temp@b=0
#2%
\else
#3%
\fi%
\fi%
}
如何修改它的定义以使其按预期工作?
答案1
我只需添加另一个属性,例如一个新的计数器,您就可以将其推进到附录。然后您可以测试它是否相等。替代方案是“绝对章节计数器”,这也可以工作,并使测试更短一些。
\documentclass[oneside]{book}
\usepackage{xr-hyper}% <== load xr-hyper package
\usepackage[unicode,colorlinks]{hyperref}% <== load hyperref package
\usepackage[user,counter]{zref}
\makeatletter
\newcounter{mattercnt}
\zref@newprop{chaptervalue}[-1]{\the\value{chapter}}%
\zref@newprop{mattervalue} [-1]{\the\value{mattercnt}}%
\zref@newprop{chapterprint}{\thechapter}%
\zref@localaddprops{main}{chaptervalue}
\zref@localaddprops{main}{mattervalue}
\zref@localaddprops{main}{chapterprint}
\makeatother
% 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
\ExplSyntaxOn
\newcommand\IfCurrentchapterTF[1]
{
\bool_if:nTF
{
\int_compare_p:nNn { \value{chapter} } = { \zref@extract{#1}{chaptervalue} }
&&
\int_compare_p:nNn { \value{mattercnt} } = { \zref@extract{#1}{mattervalue} }
}
}
\newcommand\IfCounterchapterTF[1]
{
\str_if_eq:eeTF {chapter}{\zref@extractdefault{#1}{counter}{0}}
}
\ExplSyntaxOff
\newcommand{\sref}[1]{%
\hyperref[#1]
{%
\hbox
{%
\IfCounterchapterTF{#1}
{}%print only chapter number
{%
\IfCurrentchapterTF{#1}
{}
{\zref[chapterprint]{#1}.}%
}%
\zref{#1}%
}%
}%
}
\newcommand{\seqref}[1]{(\sref{#1})}
\makeatother
% Define a macro to print test text
\newcommand{\testtext}{
Chapter \sref{ch:1}, Chapter \sref{ch:2}, Chapter \sref{ch:1A}.
\par\noindent
Compare \number\value{chapter} with \zref[chapterprint]{ch:1}. Equal: \IfCurrentchapterTF{ch:1}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chapterprint]{ch:2}. Equal: \IfCurrentchapterTF{ch:2}{Yes}{No}
\par\noindent
Compare \number\value{chapter} with \zref[chapterprint]{ch:1A}. Equal: \IfCurrentchapterTF{ch:1A}{Yes}{No}
\par\noindent
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2}; \seqref{1A.1}, \seqref{1A.2}.
}
\begin{document}
\chapter{1 in Volume 1}\label{ch:1}\zlabel{ch:1}
\testtext
\begin{equation}
eq1.1
\label{1.1}\zlabel{1.1}
\end{equation}
\begin{equation}
eq1.2
\label{1.2}\zlabel{1.2}
\end{equation}
\chapter{2 in Volume 2}\label{ch:2}\zlabel{ch:2}
\testtext
\begin{equation}
eq2.1
\label{2.1}\zlabel{2.1}
\end{equation}
\begin{equation}
eq2.2
\label{2.2}\zlabel{2.2}
\end{equation}
\appendix\stepcounter{mattercnt}
\chapter{A in Volume 1}\label{ch:1A}\zlabel{ch:1A}
\testtext
\begin{equation}
eq1A.1
\label{1A.1}\zlabel{1A.1}
\end{equation}
\begin{equation}
eq1A.2
\label{1A.2}\zlabel{1A.2}
\end{equation}
\end{document}
答案2
看来我自己找到了解决方案。如下:
% Load packages and declare external docs.
\usepackage{xr-hyper}% <== load xr-hyper package
\usepackage[unicode,colorlinks]{hyperref}% <== load hyperref package
\usepackage[user]{zref}
\makeatletter
%%\zref@newprop{chaptervalue}[-1]{\the\value{chapter}}% <= note the default value [0]
\zref@newprop{chaptervalue}[0]{\thechapter}% <= note the default value [-1]
\zref@localaddprops{main}{chaptervalue}
\makeatother
% 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@a{\expandafter\thechapter}%
\def\temp@b{\zref@extract{#1}{chaptervalue}}%
\def\temp@c{0}%
%%\ifnum\temp@a=\temp@b%
%[\temp@a][\temp@b]
\if\temp@a\temp@b%
#2%
\else%
%%\ifnum\temp@b<0
\if\temp@b\temp@c%
#2%
\else
#3%
\fi%
\fi%
}
\newcommand{\sref}[1]{\hyperref[#1]{\hbox{\ifcurrentchapter{#1}{}{\zref[chaptervalue]{#1}.}\zref{#1}}}}
\newcommand{\seqref}[1]{(\sref{#1})}
\makeatother
% Define a macro to print test text
\newcommand{\testtext}{
Chapter \sref{ch:1}, Chapter \sref{ch:2}, Chapter \sref{ch:1A}.
\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:1A}. Equal: \ifcurrentchapter{ch:1A}{Yes}{No}
\par\noindent
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2}; \seqref{1A.1}, \seqref{1A.2}.
}
\endinput
替换的字符串仅跟随注释掉的旧字符串。
更新
Ulrike Fischer 指出,如果章节数大于 9,上述解决方案将失败。她建议使用 LaTeX3 语法添加一两个计数器来实现所需结果。我的以下解决方案避免添加新计数器。它更强大,因为无需增加mattercnt
计数器\appendix
。
test2-zref-1.tex
:
\documentclass[oneside]{book}
\input{test2-zref-common}
\begin{document}
\chapter{1 in Volume 1}\label{ch:1}\zlabel{ch:1}
\testtext
\begin{equation}
eq1.1
\label{1.1}\zlabel{1.1}
\end{equation}
\begin{equation}
eq1.2
\label{1.2}\zlabel{1.2}
\end{equation}
\chapter{2 in Volume 1}\label{ch:2}\zlabel{ch:2}
\testtext
\begin{equation}
eq2.1
\label{2.1}\zlabel{2.1}
\end{equation}
\begin{equation}
eq2.2
\label{2.2}\zlabel{2.2}
\end{equation}
\setcounter{chapter}{15}
\chapter{16 in Volume 1}\label{ch:16}\zlabel{ch:16}
\testtext
\begin{equation}
eq16.1
\label{16.1}\zlabel{16.1}
\end{equation}
\begin{equation}
eq16.2
\label{16.2}\zlabel{16.2}
\end{equation}
\appendix
%\stepcounter{matter}
\chapter{A in Volume 1}\label{ch:1A}\zlabel{ch:1A}
\testtext
\begin{equation}
eq1A.1
\label{1A.1}\zlabel{1A.1}
\end{equation}
\begin{equation}
eq1A.2
\label{1A.2}\zlabel{1A.2}
\end{equation}
\end{document}
代码集中在test2-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]{zref}
%
% Define a macro that prints test text
%
\newcommand{\testtext}{
Chapter \sref{ch:1}, Chapter \sref{ch:2}, Chapter \sref{ch:16}, Chapter \sref{ch:1A}.
\par\noindent
Compare \thechapter\ with \zref[thechapter]{ch:1}. Equal: \IfCurrentchapterTF{ch:1}{Yes}{No}
\par\noindent
Compare \thechapter\ with \zref[thechapter]{ch:2}. Equal: \IfCurrentchapterTF{ch:2}{Yes}{No}
\par\noindent
Compare \thechapter\ with \zref[thechapter]{ch:16}. Equal: \IfCurrentchapterTF{ch:16}{Yes}{No}
\par\noindent
Compare \thechapter\ with \zref[thechapter]{ch:1A}. Equal: \IfCurrentchapterTF{ch:1A}{Yes}{No}
\par\noindent
\seqref{1.1}, \seqref{1.2}; \seqref{2.1}, \seqref{2.2};
\seqref{16.1}, \seqref{16.2}; \seqref{1A.1}, \seqref{1A.2}.
}
% Reset default equation numbering
\usepackage{amsmath}
\numberwithin{equation}{chapter}
\renewcommand{\theequation}{\arabic{equation}}
\newcounter{chaptertotal}
%
% main code
%
\makeatletter
\newcounter{matter}
\zref@newprop{thechapter}[??]{\thechapter}%
\zref@localaddprops{main}{thechapter}
\makeatother
%%
%% Define \sref and \seqref macros for smart cross-references
%%
\makeatletter
\ExplSyntaxOn
\str_new:N \stra
\str_new:N \strb
\newcommand\IfCurrentchapterTF[1]
{
\str_set:Nx \stra { \thechapter }%
\str_set:Nx \strb { \zref@extract{#1}{thechapter} }%
%\stra=\strb \str_if_eq:NNTF \stra \strb {Y}{N}
\str_if_eq:NNTF \stra \strb
}
\ExplSyntaxOff
\newcommand{\sref}[1]{%
\hyperref[#1]
{%
\hbox
{%
\IfCurrentchapterTF{#1}
{}
{\zref[thechapter]{#1}.}%
\zref{#1}%
}%
}%
}
\newcommand{\seqref}[1]{(\sref{#1})}
\makeatother
\endinput