> For the complete documentation index, see [llms.txt](https://ayakaleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ayakaleaf-pro.ayaka.space/latex/zh-cn/zhi-shi-ku/033-cross-referencing-with-the-xr-package-in-overleaf.md).

# 在 Overleaf 中使用 xr 宏包进行交叉引用

## 概述

该 [`xr` 包](https://ctan.org/pkg/xr?lang=en) 可让你为外部 LaTeX 文档中包含的公式、图、表等创建交叉引用，前提是这些文档是 *独立的。* 一个独立的 LaTeX 文档是指可以编译的文档，因为它包含一个 `\documentclass{...}` 声明以及 `\begin{document}`...`\end{document}` 结构。

### 用法摘要

1. 写入 `\usepackage{xr}` 需要交叉引用外部 LaTeX 文件中内容的 LaTeX 文件导言区。
2. 使用 `xr` 宏包命令 `\externaldocument{filename}` 以指定你想交叉引用其内容的外部文档。

该 `xr` 宏包通过使用包含在……中的交叉引用标签来工作 `.aux` 文件，这些文件是在编译外部 LaTeX 文档时生成的。

### 交叉引用如何工作（简短摘要）

要在 LaTeX 文档中交叉引用一个项目，你需要：

1. 给它一个唯一标识符， `some_string`，使用 `\label` 命令：

```latex
\label{some_string}
```

3. 在你想要引用该元素的位置，你需要写

```latex
\ref{some_string}
```

简而言之，LaTeX 通过将数据写入一个名为……的文件来管理交叉引用 `filename.aux` 其中 `filename` 是主 `.tex` 正在编译的文件名。

要使该过程生效，LaTeX 文档至少需要编译两次：第一次编译 *生成* 引用数据——将其写入 `filename.aux`。在第二次编译时，LaTeX *读取* `filename.aux` 以解析引用，并提供数据来替换……的实例 `\ref{some_string}`.

* 有关交叉引用的更多细节，请参见 Overleaf 文章 [交叉引用章节、公式和浮动体](/latex/zh-cn/wen-dang-jie-gou/03-cross-referencing-sections-equations-and-floats.md).

## 不需要 xr 宏包的项目

诸如书籍或长篇报告之类的大型 LaTeX 项目通常会拆分成一系列较小的 `.tex` 文件，每章一个，并将每章的 `.tex` 文件使用……添加到主 LaTeX 文档中 `\input` 或 `\include`。通常，这些章节并不是独立的：你不能单独编译各个章节，因为它们不包含一个 `\documentclass{...}` 声明或 `\begin{document}...\end{document}` 结构。这些章节用于 *包含* 到一个“容器”文档中，而该文档 *可以* 编译。在这种情况下，对文档元素的交叉引用——在任何单独的章节文件中——可以照常进行：你无需使用 `xr` 宏包。

要查看一个大型项目示例，你可以 [在 Overleaf 中打开此示例。](https://www.overleaf.com/project/new/template/20618?id=70769185\&templateName=Managing+a+large+project+on+Overleaf\&latexEngine=pdflatex\&texImage=texlive-full%3A2020.1\&mainFile=)

## 需要 xr 宏包的项目示例

假设你有一组独立的 LaTeX 文档，例如 N 篇文章的集合： `article1.tex`, `article2.tex` ... `articleN.tex`。这些文章都可以单独编译，并且它们很可能是使用各种文档类、宏包等编写的。

现在想象你想使用 LaTeX 来撰写这些文章的概述或摘要——我们把文件称为 `summary.tex`。我们的摘要需要引用这些各自独立的 N 篇文章中包含的章节、图、表、公式等。该怎么做？

该 `xr` 宏包可以让你做到这一点：它使 `summary.tex` 能够使用任何独立的 `article*.tex` 文件所生成的引用标签。

### 关于 .aux 文件的说明

* 注意，这里我们使用星号（`*`）作为 1 到 N 中任意数字的占位符。

编译任何独立文件 `article1.tex`, `article2.tex` ... `articleN.tex` 会使 LaTeX 生成相应的 `article*.aux` (\*\*`aux`\*\*辅助）文件，其中除其他内容外，还包含生成交叉引用所需的标签数据。

如果这些 `article*.tex` 文件被编辑——例如更改、添加或删除标签（`\label{...}`）——相应的 `article*.tex` 文件必须重新编译，以更新相关的 `article*.aux` 文件。

检测到对……的更改 `article*.tex`，并随后重新编译它们，可以在 Overleaf 中通过使用合适的 `latexmkrc` 文件中。

## 如何在 Overleaf 上使用 xr

我们将使用多文章示例的简化版本；具体来说，我们展示如何通过一个……来自动化编译过程 `latexmkrc` 文件 [由 John Collins 提供给 Overleaf 的](#code-for-latexmkrc) ([维护者 `latexmk`](https://ctan.org/pkg/latexmk?lang=en)).

### 我们示例中使用的文件

我们的示例使用以下文件：

* `**summary.tex**`：这是我们的概述文档。我们需要它来引用包含在 `article1.tex`中的内容，例如图和章节。
  * `summary.tex` 加载 `xr` 宏包，并使用 `\externaldocument{article1}` 以指定来自 `article1.aux` 的引用数据应被使用。
* `**article1.tex**`：一篇单独的独立文章，包含内部交叉引用。编译 `article1.tex` 会生成包含在文件中的交叉引用数据 `article1.aux`.
  * 像 `article1.tex` 这样的外部文件可能由别人编写，供你“按原样”使用，也就是不作修改。
* `**latexmkrc**`：包含用于自动重新编译……的代码（Perl） `article1.tex` 由于对其所做的任何更改——以创建更新的 `article1.aux` 文件中。
  * 我们的 `latexmkrc` 文件是 [由 John Collins 提供给 Overleaf 的](#code-for-latexmkrc) ([维护者 `latexmk`](https://ctan.org/pkg/latexmk?lang=en)).

### 关于 \externaldocument 命令

该 `xr` 宏包提供了`\externaldocument` 命令，其一般形式为

```latex
\externaldocument[prefix]{external_file}
```

* **`前缀` （可选）：** 这个可选参数允许你定义一个前缀，该前缀将添加到从外部文档导入的所有标签前面。如果多个文档使用相同的标签名称，这有助于避免冲突。
* **`external_file` （必需）：** 这个必需参数指定外部 LaTeX 文档的名称（不含 `.tex` 扩展名），你想从中导入引用。该 `xr` 宏包将查找与 `.aux` 对应的文件 `external_file` （例如， `external_file.aux`）以获取标签。

例如，如果我们的主 `.tex` 文件 `summary.tex` 以及外部文件 `article1.tex` 都包含标签 `\label{eq:1}` 那么就会发生标签名称冲突。可以通过写入以下内容来避免这种冲突

```latex
\externaldocument[art1-]{article1}
```

在这种情况下，编译 `article1.tex` 所创建的所有标签都加上前缀 `art1-`。现在你可以访问 `\label{eq:1}`，其中包含于 `article1.tex`，只需写 `\ref{art1-eq:1}` 中 `summary.tex`.

### 项目文件

#### article1.tex

可使用列表下方的链接在 Overleaf 中打开以下代码。

```latex
\documentclass{article}
\title{This is \texttt{article1.tex}}
\begin{document}
\section{Introduction}
\label{introduction}

这是一个独立的 \LaTeX{} 文档，带有
我们想在 \texttt{summary.tex} 中使用的引用。

\subsection{Math references}
\label{mathrefs}
如 \ref{introduction} 节所述，
文档内可以引用不同的元素。
一个文档。

\subsection{Powers series}
\label{powers}

\begin{equation}
\label{eq:1}
\sum_{i=0}^{\infty} a_i x^i
\end{equation}

方程 \ref{eq:1} 是一个典型的幂级数。
\end{document}
```

[打开 `article1.tex` 在 Overleaf 中](https://www.overleaf.com/docs?engine=%5B%5B%3ATemplate%3AEngine%5D%5D}\&snip_name\[]=readme.txt\&snip\[]=A+project+created+from+the+Overleaf+wiki\&snip_name\[]=article1.tex\&main_document=article1.tex\&snip\[]=%5Cdocumentclass%7Barticle%7D%0A%5Ctitle%7BThis+is+%5Ctexttt%7Barticle1.tex%7D%7D%0A%5Cbegin%7Bdocument%7D%0A%5Csection%7BIntroduction%7D%0A%5Clabel%7Bintroduction%7D%0A%0AThis+is+a+standalone+%5CLaTeX%7B%7D+document+with%0Areferences+we+want+to+use+in+%5Ctexttt%7Bsummary.tex%7D.%0A%0A%5Csubsection%7BMath+references%7D%0A%5Clabel%7Bmathrefs%7D%0AAs+mentioned+in+section+%5Cref%7Bintroduction%7D%2C+%0Adifferent+elements+can+be+referenced+within%0Aa+document.%0A%0A%5Csubsection%7BPowers+series%7D%0A%5Clabel%7Bpowers%7D%0A%0A%5Cbegin%7Bequation%7D%0A%5Clabel%7Beq%3A1%7D%0A%5Csum_%7Bi%3D0%7D%5E%7B%5Cinfty%7D+a_i+x%5Ei%0A%5Cend%7Bequation%7D%0A%0AEquation+%5Cref%7Beq%3A1%7D+is+a+typical+power+series.%0A%5Cend%7Bdocument)

编译 `article1.tex` 会产生如下输出：

![在 Overleaf 上编译 article1.tex 文件生成的输出](/files/81252137ff3a28a36f8ce5d1beedd70b80ee633c)

#### summary.tex

这是我们最初的 `summary.tex` 文件 *在……之前* 我们指定要引用哪个外部文档之前。为简单起见， `summary.tex` 不包含任何 `\label` 命令，因为没有内部交叉引用。所有 `\ref` 命令都引用由……生成的标签 `\label` 中包含的命令 `article1.tex`.

```latex
\documentclass{article}
\usepackage{xr}
\title{This is \texttt{summary.tex}}
\begin{document}
在文件 \texttt{article1.tex} 中，导言是第 \ref{introduction} 节。该文件中有两个小节：\ref{mathrefs} 和 \ref{powers}。在 \ref{powers} 小节中，方程 \ref{eq:1} 展示了一个幂级数。
\end{document}
```

[在 *不完整的* `summary.tex` 在 Overleaf 中](https://www.overleaf.com/docs?engine=%5B%5B%3ATemplate%3AEngine%5D%5D}\&snip_name\[]=readme.txt\&snip\[]=A+project+created+from+the+Overleaf+wiki\&snip_name\[]=summary.tex\&main_document=summary.tex\&snip\[]=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bxr%7D%0A%5Ctitle%7BThis+is+%5Ctexttt%7Bsummary.tex%7D%7D%0A%5Cbegin%7Bdocument%7D%0AIn+the+file+%5Ctexttt%7Barticle1.tex%7D%2C+the+introduction+is+section+%5Cref%7Bintroduction%7D.++In+that+file%2C+there+are+two+subsections%3A+%5Cref%7Bmathrefs%7D+and+%5Cref%7Bpowers%7D.+In+subsection+%5Cref%7Bpowers%7D%2C+equation+%5Cref%7Beq%3A1%7D+demonstrates+a+power+series.%0A%5Cend%7Bdocument%7D)

如果我们编译这个版本的 `summary.tex` 它将尝试从……读取引用数据 `summary.aux` 但所需数据包含在外部文件中 `article1.aux` 目前还无法访问。

编译这个不完整的 `summary.tex` 文件会产生如下输出，双问号表示未定义的引用：

![显示缺失引用报告的图像](/files/03883f30721e48066e420b1a92a83eccebf17701)

### 指定外部文档

下一步是指定 `article1` 作为我们想引用其标签的外部文档名称。将以下一行添加到……的导言区 `summary.tex`:

```latex
\externaldocument{article1}
```

这里， `article1` 可以替换为任何你想访问其标签的文件——你可以使用多个 `\externaldocument` 命令来访问额外的外部文件。

### 创建 latexmkrc 文件

下一步是创建一个 `latexmkrc` 文件，如下所示：

* 在项目编辑器窗口中，选择 **新建文件** 图标，位于项目窗口左上角。
* 选择 **新建文件** 在……中 **添加文件** 弹出对话框中，并将文件命名为 `latexmkrc`——注意没有文件扩展名：

![在 Overleaf 中创建 latexmkrc 文件](/files/63b7fb954e5d7a8c007b4acbab907205032061d0)

* 确保 `latexmkrc` 文件已在项目文件区域的顶层（根）创建并保存。也就是说，不要放在文件树中的任何文件夹内。
* 将以下代码复制并粘贴到你的 `latexmkrc` 文件中。

#### latexmkrc 代码

Overleaf 感谢 John Collins， [维护者 `latexmk`](https://ctan.org/pkg/latexmk?lang=en)，他联系我们提供以下 `latexmkrc` 该文件，我们很高兴全文发布——包括极其有帮助的行内注释。

```perl
# This shows how to use the xr package with latexmk.
# John Collins 2023-03-29
#
# The xr package ("a system for eXternal References") is used by a document
# to make references to sections, equations, etc in other external
# documents.
# The definitions in this file enable latexmk to apply latexmk to
# automatically update an external document whenever its .tex file changes,
# so that the references in the main document stay up to date.

# Notes:
#    1. This version is defined to put the files from the compilations of
#       the external documents into a defined subdirectory, to segregate
#       potentially many generated files from the main document
#       directories.
#    2. But for latexmk's custom dependency mechanism to be used, as here,
#       the aux file from compilation of a subdocument must be generated in
#       the same directory as the corresponding source .tex file.  So the
#       .aux file is copied.
#    3. It is assumed that the external documents are to be compiled by
#       pdflatex.  This can be changed, of course, by changing the '-pdf'
#       option given to the invoked latexmk to whatever is needed.
#    4. An ideal implementation would also ensure that recompilation of an
#       external document also happens whenever any of its other source
#       files changes.  But this is not done in the present version, and
#       would probably entail either the use of internal latexmk variables
#       or extra enhancements to latexmk.
#    5. The code uses subroutines copy and fileparse that are loaded by
#       latexmk from the Perl packages File::Copy and File::Basename.
#    6. It also uses some not-yet-documented features of latexmk: an array
#       variable @file_not_found and subroutines popd, pushd, and
#       rdb_add_generated.

#--------------------
# Configurable choices for compilation of external documents

# Subdirectory for output files from compilation of external documents:
$sub_doc_output = 'output-subdoc';

# Options to supply to latexmk for compilation of external documents:
@sub_doc_options = ();

push @sub_doc_options, '-pdf'; # Use pdflatex for compilation of external documents.
# Replace '-pdf' by '-pdfdvi', 'pdfxe', or 'pdflua' if needed.

#--------------------

# Add a pattern for xr's log-file message about missing files to latexmk's
# list.  Latexmk's variable @file_not_found is not yet documented.
# This line isn't necessary for v. 4.80 or later of latexmk.
push @file_not_found, '^No file\\s*(.+)\s*$';

add_cus_dep( 'tex', 'aux', 0, 'makeexternaldocument' );
sub makeexternaldocument {
    if ( $root_filename ne $_[0] )  {
        my ($base_name, $path) = fileparse( $_[0] );
        pushd $path;
        my $return = system "latexmk",
                            @sub_doc_options,
                            "-aux-directory=$sub_doc_output",
                            "-output-directory=$sub_doc_output",
                            $base_name;
        if ( ($sub_doc_output ne '') && ($sub_doc_output ne '.') ) {
               # In this case, .aux file generated by pdflatex isn't in same
               # directory as the .tex file.
               # Therefore:
               # 1. Actual generated aux file must be listed as produced by this
               #    rule, so that latexmk deals with dependencies correctly.
               #    (Problem to overcome: If $sub_dir_output is same as $aux_dir
               #    for the main document, xr may read the .aux file in the
               #    aux_dir rather than the one the cus dep is assumed by latexmk
               #    to produce, which is in the same directory as the .tex source
               #    file for this custom dependency.)
               #    Use not-yet-documented latexmk subroutine rdb_add_generated
               #    to do this:
               # 2. A copy of the .aux file must be in same directory as .tex file
               #    to satisfy latexmk's definition of a custom dependency.
             rdb_add_generated( "$sub_doc_output/$base_name.aux" );
             copy "$sub_doc_output/$base_name.aux", ".";
        }
        popd;
        return $return;
   }
}
```

### 打开一个展示 xr 的 Overleaf 项目

下面提供的链接可在 Overleaf 中打开以下三文件项目。请注意， `latexmkrc` 文件包含 John Collins 提供的代码，但为简洁起见，大部分注释已被删除。

[在 Overleaf 中打开这个三文件示例。](/latex/zh-cn/zhi-shi-ku/033-cross-referencing-with-the-xr-package-in-overleaf.md)

**summary.tex**

这是我们的摘要文件。我们希望在此文件中使用外部文件中创建的交叉引用。这里，我们想使用在……中生成的标签 `article1.tex`.

```latex
\documentclass[12pt]{article}
\usepackage{xr}

\title{Using the xr package on Overleaf}
% put all the external documents here!
\externaldocument{article1}

\begin{document}

在文件 \texttt{article1.tex} 中，导言是第 \ref{introduction} 节。该文件中有两个小节：\ref{mathrefs} 和 \ref{powers}。在 \ref{powers} 小节中，方程 \ref{eq:1} 展示了一个幂级数。

\end{document}
```

**article1.tex**

这个文件是我们的文章之一。注意其中包含各种 `\label` 用于创建标签的命令，多亏了 `xr` 宏包，我们可以在文件中使用这些标签 `summary.tex`.

```latex
\documentclass{article}
\title{This is \texttt{article1.tex}}
\begin{document}
\section{Introduction}
\label{introduction}

这是一个独立的 \LaTeX{} 文档，带有
我们想在 \texttt{summary.tex} 中使用的引用。

\subsection{Math references}
\label{mathrefs}
如 \ref{introduction} 节所述，
文档内可以引用不同的元素。
一个文档。

\subsection{Powers series}
\label{powers}

\begin{equation}
\label{eq:1}
\sum_{i=0}^{\infty} a_i x^i
\end{equation}

方程 \ref{eq:1} 是一个典型的幂级数。
\end{document}
```

**latexmkrc**

这个 `latexmkrc` 文件包含确保外部文件被编译的代码。

```latex
$sub_doc_output = 'output-subdoc';

@sub_doc_options = ();

push @sub_doc_options, '-pdf'; # Use pdflatex for compilation of external documents.
# Replace '-pdf' by '-pdfdvi', 'pdfxe', or 'pdflua' if needed.

push @file_not_found, '^No file\\s*(.+)\s*$';

add_cus_dep( 'tex', 'aux', 0, 'makeexternaldocument' );
sub makeexternaldocument {
    if ( $root_filename ne $_[0] )  {
        my ($base_name, $path) = fileparse( $_[0] );
        pushd $path;
        my $return = system "latexmk",
                            @sub_doc_options,
                            "-aux-directory=$sub_doc_output",
                            "-output-directory=$sub_doc_output",
                            $base_name;
        if ( ($sub_doc_output ne '') && ($sub_doc_output ne '.') ) {

             rdb_add_generated( "$sub_doc_output/$base_name.aux" );
             copy "$sub_doc_output/$base_name.aux", ".";
        }
        popd;
        return $return;
   }
}
```

[在 Overleaf 中打开这个三文件示例。](/latex/zh-cn/zhi-shi-ku/033-cross-referencing-with-the-xr-package-in-overleaf.md)

下图是排版 `summary.tex`的输出的注释版本，显示了交叉引用以及来自外部文件的相应标签 `article1.tex`.

![显示从外部文件导入的引用](/files/28377d8b8484b2c0a2a35ea0cb1ea4a6ae32ec91)

* 有关交叉引用的更多细节，请参见 Overleaf 文章 [交叉引用章节、公式和浮动体](/latex/zh-cn/wen-dang-jie-gou/03-cross-referencing-sections-equations-and-floats.md).

## 关于语法错误的说明

对于你的主项目文件，你可以使用 Overleaf 的 [首个错误即停止编译模式](/latex/zh-cn/zhi-shi-ku/149-using-the-stop-on-first-error-compilation-mode.md) 以确保在检测到第一个错误时立即终止编译。这有助于隔离并识别代码中的错误，而不是让错误连锁传播，因为那会使查找和调试问题困难得多。

该 *external* 文档会通过……自动编译 `latexmkrc` 文件；因此，其中任何 LaTeX 语法错误都不会显示在 Overleaf 界面中——除非你也在 Overleaf 中重新编译它们。那些外部文件中的错误可能会导致交叉引用无法在排版后的 PDF 文件中正确显示，因此我们强烈建议在此类错误一出现时就立即检查并更正。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ayakaleaf-pro.ayaka.space/latex/zh-cn/zhi-shi-ku/033-cross-referencing-with-the-xr-package-in-overleaf.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
