我为我们的微积分系列保留了一套开放的微积分教材,该系列有四门课程(微积分 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}