交叉引用时忽略某个部分或章节

交叉引用时忽略某个部分或章节

我为我们的微积分系列保留了一套开放的微积分教材,该系列有四门课程(微积分 I-IV)。每门课程都有自己对应的开放教材。有时,后续课程的教材需要参考早期教材中的某个结果。

像往常一样,我使用 xr 包完成此操作,将以前的文本作为外部文档加载,并且一切正常,除了以下问题:

由于该系列先修课程的讲师可能无法讲完他们需要的所有材料,因此我会重复一些章节。例如,《微积分 III》的第一章可能包含《微积分 II》最后一章的几个章节。

当使用 xr 交叉引用早期文本时,这会导致重复部分的多重定义引用激增。

有什么方法可以配置 xr 包以忽略重复部分的引用?

例如:整个项目的目录树顶层有 BookA.tex 和 BookB.tex。还有子目录,例如 /text(包含每个部分的 .tex 文件)、/figures 等。

BookA 有两个部分,包括使用

\input{text/Section1}

\input{text/Section2}

BookB 是 BookA 的延续,但由于使用 BookA 和 BookB 的课程有重叠,因此它还包括第 2 节。因此 BookB 具有

\usepackage{xr}

\externaldocument{BookA}

在序言和文件中,

\input{text/Section2}

\input{text/Section3}

由于 Section2 同时出现在 BookA 和 BookB 中,因此使用 BookA 进行交叉引用会产生多重定义的引用。

我想要一种方法来引用 BookA(因为 Section3 引用了 Section1),但省略 BookB 中也出现的章节。

答案1

您可以使用可选参数\externaldocument,它将在导入的标签前加上字符串作为前缀,以使其唯一。

\externaldocument[booka-]{BookA}

将使所有导入的标签都具有名称booka-<label>。这当然要求您记住引用是在此文件中还是在外部文件中。


下面稍微重新定义了xr和的核心宏xr-hyper,使得标签仅在当前文档中不存在时才创建(如果r@<label>定义,则标签存在)。这要求在读取\externaldocument主文件时调用,幸运的是,它能够正常工作。.aux\AtBeginDocument

将以下文件另存为bookb.tex。该文件用于filecontents创建所有其他.tex文件。警告:filecontents覆盖现有文件而不发出警告,请仅在空的测试目录中运行代码。

编译如下

pdflatex bookb
pdflatex booka
pdflatex booka
pdflatex bookb
\RequirePackage{filecontents}
\begin{filecontents}{section1.tex}
\section{Section 1}\label{sec:1}
\kant[1-4]
\end{filecontents}
\begin{filecontents}{section2.tex}
\section{Section 2}\label{sec:2}
\kant[5-7]
\end{filecontents}
\begin{filecontents}{section3.tex}
\section{Section 3}\label{sec:3}
\kant[8-9]
\end{filecontents}
\begin{filecontents}{booka.tex}
\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{kantlipsum}
\usepackage{hyperref}

\begin{document}
\input{section1}
\input{section2}
\end{document}
\end{filecontents}

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{etoolbox}
\usepackage{kantlipsum}

\usepackage{xr-hyper}
\usepackage{hyperref}

\makeatletter
\@ifpackageloaded{xr}
  {\def\sf@safe@newlabel#1{%
     \ifcsundef{r@#1}
       {\newlabel{#1}}
       {\PackageInfo{xr}{label `#1' already defined, skipping}%
        \@gobble}}
   \long\def\XR@test#1#2#3#4\XR@{%
     \ifx#1\newlabel
       \sf@safe@newlabel{\XR@prefix#2}{#3}%
     \else\ifx#1\@input
        \edef\XR@list{\XR@list#2\relax}%
     \fi\fi
     \ifeof\@inputcheck\expandafter\XR@aux
     \else\expandafter\XR@read\fi}}
  {}%
\@ifpackageloaded{xr-hyper}
  {\long\def\XR@test#1#2#3#4\XR@{%
     \ifx#1\newlabel
       \ifcsundef{r@#2}
         {\expandafter\protected@xdef\csname r@\XR@prefix#2\endcsname
            {\XR@addURL{#3}}}
         {\PackageInfo{xr-hyper}{label `#2' already defined, skipping}}%
     \else\ifx#1\@input
       \edef\XR@list{\XR@list\filename@area#2\relax}%
    \fi\fi
    \ifeof\@inputcheck\expandafter\XR@aux
    \else\expandafter\XR@read\fi}}
  {}
\makeatother

\AtBeginDocument{\externaldocument{booka}}

\begin{document} 
\ref{sec:1} (in old doc) 

\ref{sec:2} (in both docs, but numbering goes out to this one)

\ref{sec:3} (only in this doc)
\input{section2}
\input{section3}
\end{document}

相关内容