> For the complete documentation index, see [llms.txt](https://overleaf-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://overleaf-pro.ayaka.space/latex/zh-cn/shen-ru-wen-zhang/06-an-introduction-to-kpathsea-and-how-tex-engines-search-for-files.md).

# Kpathsea 简介以及 TeX 引擎如何搜索文件

## 引言

本文介绍 TeX 引擎如何定位排版文档所需文件——无论使用 LaTeX 还是其他宏包。虽然 Overleaf 让用户免去了管理 TeX 安装的种种难题（[TeX Live](https://www.tug.org/texlive/)），但如果你想创建文件夹结构来帮助管理 Overleaf 项目，那么了解 TeX 引擎如何搜索文件的基本原理会很有用/很有兴趣。

为什么会这样呢？如果你把 Overleaf 项目的某些文件存放在文件夹中，那么 LaTeX 可能找不到这些文件，因为默认情况下，TeX 引擎（编译器）可能不会 *知道* 它需要搜索这些文件夹——因此就找不到其中包含的文件。为避免这种情况，你可以创建一个名为 [latexmkrc 文件](https://mg.readthedocs.io/latexmk.html#configuration-files) 并将其添加到项目中，用它来告诉 TeX 引擎你的文件夹存在，并且它应该搜索它们。

如果你想直接看一个展示 latexmkrc 文件的示例，可以阅读这篇帮助文章： [如何在 Overleaf 中使用 latexmkrc：示例与技巧](/latex/zh-cn/shen-ru-wen-zhang/28-how-to-use-latexmkrc-with-overleaf.md)。它的工作原理或原因可能并不一目了然。如果你想知道为什么，并且也许希望更好地理解它，以便在项目中使用更多配置可能性，那么请继续阅读……在本文末尾，我们将演示一个 [实际示例](#kpathsea-and-texinputs-latexmkrc-file-to-the-rescue)——利用我们对 TeX 如何搜索文件的了解——创建一个 latexmkrc 文件来管理包含图形文件的嵌套文件夹。

## TeX 与平台无关性

当 Knuth 创建 TeX 时，平台无关性是指导其设计和实现的核心原则，这一理念也贯穿于 TeX 的内部运作（例如使用整数算术、“自制”的字符串处理、内存管理等）。即便到了今天，现代基于 TeX 的引擎的平台无关性仍然会在公共论坛上引发讨论；例如，请看 tex.stackexchange 上的这场讨论： [XeTeX 和 LuaTeX 是否依赖平台？](https://tex.stackexchange.com/questions/94297/are-xetex-and-luatex-platform-dependent) 其中包含多位知名 TeX 专家的评论和观察。

不过，暂且让我们把更细的细节放在一边，并注意到 TeX 引擎仍然需要具有高度可移植性——能够在多个操作系统上工作并产生“相同”的结果。可移植性的一个关键方面，是以平台无关的方式搜索文件。

## TeX 引擎并不搜索文件……真的吗！？

不，TeX 引擎并不会 *直接* 搜索文件 *自己*。在处理一个 `.tex` 文件时，TeX 引擎可能会识别出需要打开某个特定文件，但它 *会将其委托* 把寻找它的任务交给另一款名为 [*Kpathsea*](https://tug.org/kpathsea/)：一个外部软件库，不属于 *核心* TeX 引擎的源代码。Kpathsea 实际上提供的是一个 API（[应用程序编程接口](https://en.wikipedia.org/wiki/Application_programming_interface)）供 TeX 引擎（以及 BibTeX、MetaPost 和其他应用程序）在需要打开特定文件时调用：Kpathsea 才是实际执行定位该文件工作的部分。

当 Knuth 编写最初的 TeX 引擎——后来所有其他 TeX 引擎最终都由它发展而来——时，查找/打开文件的问题是一个重大挑战，部分原因在于当时技术生态的高度分散。事实上，在 TeX 的源代码中，Knuth 将文件输入/输出称为“可移植性的祸根”（见……的第 12 页，第 25 节 [TeX：程序](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373)).

TeX 社区认识到有必要协调（标准化）TeX 的文件搜索——*以及与 TeX 相关的软件*——并决定为 TeX 提供实现这一点的工具。为了解决一种与平台无关的文件查找方法这一棘手问题，TeX 社区的重要成员 Karl Berry 编写了软件来解决 *路径*搜索问题：他将该解决方案命名为 [**Kpathsea**](http://tug.org/texinfohtml/kpathsea.html)——它源自 **K**Karl 的 **Path** **Sea**rching（参见这篇 [对 Karl Berry 的采访](http://www.tug.org/interviews/berry.html)).

我们可以注意到，它被称为 K**路径**sea，而不是 K**文件**sea，因为正如 [文档](http://tug.org/texinfohtml/kpathsea.html) 所指出的那样，它是一个 \*路径\* 搜索库。需要认识到，Kpathsea 不仅被 TeX 引擎使用；各种与 TeX 相关的程序，包括 BibTeX 和 MetaPost，也使用 Kpathsea 来搜索输入文件。

概括地说，每当 TeX/LaTeX 宏需要打开某个特定文件时，这些宏所由其构成的命令最终会被转换为 TeX 引擎实际执行的底层 TeX 指令（TeX 原语）。如果这些指令包含打开文件的需求，TeX 引擎就会调用 Kpathsea，实际上是在说：“请帮我找到这个文件”；如果 Kpathsea 搜索成功，文件就会被打开。不过，如果 Kpathsea 无法定位该文件，TeX 引擎就会收到通知并停止执行，抛出那个臭名昭著的错误 ``！我找不到文件 `...'`` 事实是 Kpathsea 找不到它。

### 关于 LuaTeX 的说明

严格来说，我们应当先说明一下：LuaTeX 确实提供了一种机制，允许用户通过使用 *回调*。LuaTeX 允许用户使用 Lua 脚本语言编写函数，并将其注册到 LuaTeX 中，这样它就会在 LuaTeX 执行过程中的某些阶段调用该用户定义的函数——因此才有了术语 *回调*。这是一种非常强大的技术，感兴趣的读者可以在……的第 9 节找到更多信息 [LuaTeX 参考手册](http://www.pragma-ade.com/general/manuals/luatex.pdf) （撰写本文时，该链接对应 LuaTeX 1.09）。

### Kpathsea 配置文件：texmf.cnf

每个 TeX 安装都包含一个名为 `texmf.cnf` 的文本文件，它是 Kpathsea 使用的配置文件：其中包含许多“配置变量”，用于定义 Kpathsea 将用来搜索 TeX 引擎（或 BibTeX、MetaPost 等）可能需要的各种文件类型的路径。正如下面将看到的，那些“配置变量”定义的搜索路径是由所谓的 *路径元素*：使用各种结构、变量和参数，把每个路径元素定义为一个“模板”，由 Kpathsea 处理后生成实际的物理目录供搜索。

举个具体例子，这里有一个这样的配置变量，用于定义 OpenType 字体的搜索路径——暂时不必担心这个路径构造的含义：

```
OPENTYPEFONTS = .;$TEXMF/fonts/{opentype,truetype}//;$OSFONTDIR//
```

这里重要的是，该文件 `texmf.cnf` （由 Kpathsea 读取）定义了一个名为 `OPENTYPEFONTS` 它用于定义 Kpathsea 将用来搜索 OpenType 字体的路径。等号右侧看起来并不像你在普通设备上见到的任何路径，因为它是通过各种变量和参数构造出来的，把每个路径定义为一个“模板”或“蓝图”，Kpathsea 会用它来生成真正要搜索的目录。

### Kpathsea 对“路径”的概念

也许最需要掌握的核心概念是 Kpathsea 对“路径”的理解：Kpathsea 用来确定某个特定文件位于何处的基本构造。正如我们在 `OPENTYPEFONTS` 上面的例子中看到的，Kpathsea 对路径的理解与我们在桌面或便携设备上习惯使用的路径很不一样。

引用 Kpathsea 的 [文档](http://tug.org/texinfohtml/kpathsea.html#Searching-overview):

> ……一个 *搜索路径* 是一个由冒号分隔的 *路径元素*，它们是带有一些“额外装饰”的目录名。

——但请注意，分号（`;`） *路径元素*。稍后我们会简要说明这些“额外装饰”的性质。

在我们的 `OPENTYPEFONTS` 示例中，有三个路径元素，每个都用分号（`;`):

![显示 Kpathsea 路径定义中所包含路径元素的图片](/files/cef8b58be4cc163ea68661cb4eda11e17f54660a)

1. `.` （表示当前目录）
2. `$TEXMF/fonts/{opentype,truetype}//`
3. `$OSFONTDIR//`

请注意，双斜杠（`//`）在路径元素中表示搜索子目录（递归地）。

一个典型的 `texmf.cnf` 文件会包含许多“配置变量”，用于定义 Kpathsea 可以搜索的各类文件的搜索路径。

## Kpathsea：非常简要的概述

Kpathsea 是一个复杂的库——包含许多细节和微妙之处——即使只是粗略看一下它的 [文档](http://tug.org/texinfohtml/kpathsea.html) 也会很清楚，我们不可能深入所有细节。不过，我们可以尝试概述它的作用——帮助你建立整体认识，并为进一步阅读提供起点。

### Kpathsea 的核心目的

正如文档所述，Kpathsea 的基本目的是“从用户指定的目录列表中返回一个文件名”，而这些目录（搜索路径）则通过“一些额外装饰”来指定。

### 那些“额外装饰”

上面提到的“一些额外装饰”包括 Kpathsea 用来构建其搜索路径（或“路径模板”）的各种参数和变量，从而可以更通用地定义路径。当 TeX 引擎实际运行（执行）时，Kpathsea 可以使用这些参数/变量的当前值，通过将这些变量替换为其实际（运行时）值来确定真正的路径。你可以很容易识别这些变量（在路径元素中），因为它们都以一个 `$` 符号开头。

因此，我们说 Kpathsea *展开* 一个路径元素，也就是说它会转换这些参数和变量：把一个路径“模板”变成一个或多个实际物理目录的名称，以便在其中查找文件。这提供了很大的灵活性，也意味着 Kpathsea 可能会为单个路径元素构建一个目录列表——例如，如果它被告知要搜索子目录。

### 重访我们的 OpenType 示例

我们将把各条线索汇总起来并探讨 `OPENTYPEFONTS` ，稍微详细一些：

```
OPENTYPEFONTS = .;$TEXMF/fonts/{opentype,truetype}//;$OSFONTDIR//
```

让我们考虑这两个路径元素 `$TEXMF/fonts/{opentype,truetype}//` 和 `$OSFONTDIR//`。在这里，Kpathsea 注意到花括号的使用 `{...}` 并将 `$TEXMF/fonts/{opentype,truetype}` 视为表示 *两个* 路径元素：

1. `$TEXMF/fonts/opentype//`
2. `$TEXMF/fonts/truetype//`

并且 *子目录* 这两个路径元素下的子目录也应该被搜索（由末尾的 `//`).

**注意**：请参阅 Kpathsea 文档中关于 [子目录展开](http://tug.org/texinfohtml/kpathsea.html#Subdirectory-expansion) ，其中有一个重要注意事项，说明各级子目录的搜索顺序（未指定）。

我们将对 `$TEXMF` 见下文。

#### $OSFONTDIR//

`$OSFONTDIR` 是一个变量，其值应定义为一个环境变量，包含字体存放的位置：当然，具体值取决于运行 TeX 所用的操作系统。请注意，这里的末尾 `//` 表示在查找 OpenType 字体时让 Kpathsea 搜索子目录。

的默认定义 `OSFONTDIR` ， `texmf.cnf` 的一般形式是：

```
OSFONTDIR = /please/set/osfontdir/in/the/environment
```

所以如果你想使用它，就一定需要进行设置——你的环境变量将覆盖其中包含的这个“占位符”定义 `texmf.cnf`.

如果你确实设置了环境变量 `OSFONTDIR` 那么在运行时，凡是 Kpathsea 看到 `$OSFONTDIR` 作为路径元素的一部分（在 `texmf.cnf`）时，它就可以将该变量替换为 `$OSFONTDIR` 环境变量中存储的实际值 `OSFONTDIR`。请记住，当在 `texmf.cnf` 路径元素中使用它时，我们要指定变量 `$OSFONTDIR`——并在前面加上 `$`——以告诉 Kpathsea 这是一个其 *值* 需要使用的变量。

#### 关于 $TEXMF 的简要说明

`TEXMF` 是另一个定义在 `texmf.cnf`中的配置变量；例如，在 TeX Live 主发行版中你会看到：

```
TEXMF = {$TEXMFAUXTREES$TEXMFCONFIG,$TEXMFVAR,$TEXMFHOME,!!$TEXMFLOCAL,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFDIST}
```

你不必关心 `TEXMF`——我们不会探究所有细节，只需注意 `$TEXMF` 该变量在路径元素中被使用，因为它定义了一系列顶层文件夹（称为“texmf 树”），可以从这些位置开始搜索文件。

`TEXMF` 如果你想或需要将一个 TeX 安装拆分到多个目录（或目录“树”）中，这个变量就非常有用。例如，拥有一套主要或主控的 TeX/LaTeX 宏包集合（如 TeX Live），以及另一套用于存放本地 LaTeX 宏包的文件和文件夹——或者可能用于存放本地配置文件或标准宏包的自定义版本。这样拆分 TeX 安装，可以更容易管理主要/主控 TeX/LaTeX 宏包集合（发行版）的升级，因为你的本地集合与主文件分离，而主文件会在你升级 TeX Live 发行版/安装时更新。

有关管理更复杂 TeX 安装的更多细节，感兴趣的读者可参考以下两篇论文：

* [Managing Multiple TDS Trees](http://tug.org/TUGboat/Articles/tb22-3/tb72downes.pdf) Michael J Downes 著；
* [Juggling texmf trees](http://www.ntg.nl/maps/27/17.pdf) Siep Kroonenberg 著。

#### TeX 目录结构

任何管理过 TeX 安装的人都知道，现代 TeX 系统，如 TeX Live，包含数以万计的文件，涵盖极其广泛的文件类型。TeX 目录结构（TDS）被设计为组织一个可用 TeX 安装中海量文件集合的最佳实践“蓝图”，并且强烈建议与 Kpathsea 一起使用。

更多信息请参阅 TDS 规范： [TeX 文件的目录结构](https://www.tug.org/tds/tds.pdf).

## Kpathsea 文件类型

使用 Kpathsea 的应用程序套件需要访问广泛的文件类型，因此 Kpathsea 使用“配置变量”来标识它支持的每种文件类型（或文件组）的路径。在线文档中有完整列表（另见我们的 [下方汇总表](#table-listing-kpathsea-config-variables)），这里列出更常见文件类型的“配置变量”：

|                     |                 |
| ------------------- | --------------- |
| **配置变量**            | **文件类型示例**      |
| TEXINPUTS           | TeX 源文件和图形/图片文件 |
| BIBINPUTS，BSTINPUTS | BibTeX 参考文献源文件  |
| TTFONTS             | TrueType 轮廓字体   |
| OPENTYPEFONTS       | OpenType 轮廓字体   |

`TEXINPUTS` 是一个尤其重要的配置变量，因为它指定 TeX 引擎从哪里获取输入源文件。请注意，图像文件也被视为输入文件，并且也可以使用由……定义的路径来搜索。 `TEXINPUTS`.

### Kpathsea 的一些细微之处

如前所述，Kpathsea 有许多细微之处，我们无法在此详尽探讨。不过，这里列出一些读者可能希望进一步了解的特性：

* **文件名数据库：** 为了尽量减少磁盘搜索，Kpathsea 可以利用一个“外部构建的 [名为 ls-R 的文件名数据库文件](http://tug.org/texinfohtml/kpathsea.html#Filename-database) ，它将文件映射到目录”。TeX Live 提供了一个，并提供了在添加新文件时更新它的工具。
* **环境变量**：除了“配置变量”（例如 `OPENTYPEFONTS`）之外，Kpathsea 还巧妙地利用 [环境变量](https://en.wikipedia.org/wiki/Environment_variable)；例如，环境变量的运行时值可用于定义 `texmf.cnf` 文件中的路径元素（可能用来覆盖在 `texmf.cnf`).
* **程序名：** Kpathsea 行为中一个微妙但关键的方面是，它可以利用可执行程序的名称（例如 TeX 引擎）来构造特定于程序的搜索路径。这带来了相当大的灵活性，因为路径搜索可以针对某个特定 TeX 引擎的文件。例如，对于 LuaTeX/LuaLaTeX：

  ```
  TEXINPUTS.lualatex = .;$TEXMF/tex/{lualatex,latex,luatex,generic,}//
  TEXINPUTS.luatex = .;$TEXMF/tex/{luatex,plain,generic,}//
  ```
* **查找 `texmf.cnf`**&#x4F60;可能会问，Kpathsea 如何知道 `texmf.cnf` 存放在哪里？答案是一个名为 `TEXMFCNF`。这需要在运行 TeX 的设备/平台上设置为 `texmf.cnf` 的存放路径。

#### 调试 Kpathsea 问题

Overleaf 用户通常不太需要这些功能，但为了完整性我们还是列出：

* **kpsewhich**：一个独立程序（包含在 TeX Live 中），可用于测试你的设置：确定变量值并查找文件。感兴趣的读者请参阅 [在线文档](http://tug.org/texinfohtml/kpathsea.html#Invoking-kpsewhich) 以获取更多信息。
* **环境变量**：Kpathsea 支持一个名为 [`KPATHSEA_DEBUG`](http://www.tug.org/texinfohtml/kpathsea.html#Debugging) ，用于帮助调试其行为。你可以设置 `KPATHSEA_DEBUG` 为不同的值，取决于你需要多少调试信息。将 `KPATHSEA_DEBUG=-1` 会生成大量的 *大量的* 数据。

## 最后：文件夹、图形文件和 latexmkrc

那么，上述内容与 latexmkrc 有什么关系？如果你阅读这篇文章 [如何在 Overleaf 中使用 latexmkrc：示例与技巧](/latex/zh-cn/shen-ru-wen-zhang/28-how-to-use-latexmkrc-with-overleaf.md) ，你会看到 latexmkrc 示例中的（Perl）代码设置了一个环境变量的值 `TEXINPUTS`:

```
$ENV{'TEXINPUTS'}='./tex//:' . $ENV{'TEXINPUTS'};
```

请注意，这里使用的冒号（:`./tex//**:**`）是 *极其* 很重要。如果你省略那个冒号，那么 TeX/LaTeX 可能无法找到重要的系统文件，比如 LaTeX 宏包！

这个 latexmkrc 文件实际上做的，是添加一个顶层文件夹路径（`./tex` ，如上例所示）到系统定义的 `TEXINPUTS` 环境变量中，以便当 Kpathsea 使用该变量 `$TEXINPUTS` 时，它就会知道文件夹 `/tex//` 应当被搜索以查找输入文件。如果你仔细看，会发现实际使用的路径是 `./tex//:` 该 `//` 这表示让 Kpathsea 递归地搜索 tex 文件夹——也就是说，查看其中包含的任何子文件夹。 `tex` 文件夹。如前所述，我们还添加了重要的冒号字符。

我们也可以对图形文件使用完全相同的技术。

### 关于 BibTeX 的补充说明

如前所述，BibTeX 程序也使用 Kpathsea 来搜索其输入文件；具体来说：

* 该 `BSTINPUTS` 配置变量（搜索路径）用于搜索 `.bst` 文件；
* 和 `BIBINPUTS` 配置变量（搜索路径）将用于搜索 `.bib` .bib 文件。

如果你向你的 `.bst` 或 `.bib` 文件添加到 Overleaf 项目中，你可以使用下面的技巧告诉 BibTeX 在哪里找到这些文件——你需要将 `TEXINPUTS` 与 `BSTINPUTS` 和/或 `BIBINPUTS`.

### TEXINPUTS，以及使用嵌套文件夹存放图形文件

如果你的项目有很多图形文件，创建一组文件夹来存放和管理它们会很方便。例如，下面的截图显示了一个 Overleaf 项目的部分内容，它使用了一个名为 **`graphics`**:

![显示 Overleaf 项目中嵌套文件夹的图片](/files/aa98975bb8d3180bdd915ff10a2ac0e6f9252b60)

其中有许多（嵌套的）子文件夹，包含文档各个部分的图形。

假设我们有上述文件夹结构，并想使用 `graphicx` 宏包（`\usepackage{graphicx}`）并且我们尝试这样做：

```latex
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics{endlinechar}% 最佳实践是不使用文件扩展名
\end{document}
```

这不会奏效，你会得到如下错误：

```
! LaTeX Error: File `endlinechar' not found.
l.4 \includegraphics{endlinechar}
我无法使用以下任何扩展名找到该文件：
.pdf,.PDF,.ai,.AI,.png,.PNG,.jpg,.JPG,.jpeg,.JPEG,.jp2,.JP2,.jpf,.JPF,.bmp,.BMP,
,.ps,.PS,.eps,.EPS,.mps,.MPS,.pz,.eps.Z,.ps.Z,.ps.gz,.eps.gz
```

出现该错误，是因为我们的图形文件存放在 TeX/LaTeX（以及 Kpathsea）不知道的位置，因此无法找到它——该图形文件的路径是：

```
./graphics/Introduction/Chapter1/Section1/Subsection3/endlinechar.png
```

**注意**：普遍接受的最佳实践是 ***避免在文件夹名称中使用空格字符***。虽然文件夹名称中当然可以包含空格，并且使用下面讨论的技术也能处理，但出于在 Overleaf 平台之外的文档可移植性考虑，我们不建议这样做。

正如这篇 [Overleaf 帮助文章](/latex/zh-cn/geng-duo-zhu-ti/27-inserting-images.md) 中所解释的那样，你当然可以使用文件夹来存放图形，但你需要告诉 LaTeX 它们存放在哪里。这里我们来看两种解决方案：

* 使用 \graphicspath 命令；
* 利用我们对 Kpathsea 的了解以及 `TEXINPUTS`.

### 使用 \graphicspath

该 `graphicx` 宏包提供了 `\graphicspath` 命令，你可以用它来声明图形所在的路径；因此我们可以这样做：

```latex
\graphicspath{{./graphics/Introduction/Chapter1/Section1/Subsection3/}}
```

这样 LaTeX 就会找到存储在该路径下的任何图形。

**注意**：如果你 *必须* 的文件夹名称中有空格，那么你需要将路径放在双引号（`"..."`):

```latex
\graphicspath{{"./graphics/Introduction/Chapter 1/Section 1/Subsection 3/"}}
```

**注意**：你可以像这样声明多个路径：

```latex
\graphicspath{{path1}{path2}{path3}...{pathN}}
```

其中 `...` 表示用花括号括起来的附加路径。

**注意**：我们把路径以 `./graphics` 而不是仅用 `/graphics`。点号（.）告诉操作系统该路径相对于当前工作目录。

该 `\graphicspath` 命令效果很好，但如果你有很多文件夹，要逐一添加每个路径就会相当繁琐；此外，通过……定义的路径 `\graphicspath` 如果你重命名文件夹或重新组织它们，这些路径将不再起作用。有没有更简单的方法？有，你可以使用 latexmkrc 文件！

#### \graphicspath 和递归（子目录）

请注意，网上对于某些系统是否支持/启用 `\graphicspath` 在添加 `//` 后是否会递归搜索子目录：例如，请看 tex.stackexchange 上的这些讨论：

* [LaTeX \graphicspath 递归搜索](https://tex.stackexchange.com/questions/25443/latex-graphicspath-recursive-search);
* [用于 MikTeX 的 Graphicspath](https://tex.stackexchange.com/questions/3131/graphicspath-for-miktex).

为了获得最大的兼容性，你应当假设 `\graphicspath` 不支持递归目录搜索。

### Kpathsea 和 TEXINPUTS（latexmkrc 文件来救场）

**注意：** 请注意，下面的技术在 Overleaf 和配置得当的本地 TeX 安装中都能很好地工作； **但** 如果你使用 latexmkrc 文件，你的项目可能会与其他 TeX 安装不兼容，例如出版商和在线期刊投稿系统所使用的安装。第三方 TeX 安装可能支持，也可能不支持或不允许使用 latexmkrc。如果你需要导出 Overleaf 项目以在其他地方使用，或者想投稿给期刊，你应该从路径名中删除空格字符，并为了提高兼容性，添加一个 `\graphicspath` 命令，它会定义所有路径：

```latex
\graphicspath{{path1}{path2}{path3}...{pathN}}
```

其中 `...` 表示用花括号括起来的附加路径。

下面讨论的技术（使用 `TEXINPUTS`）已在 Overleaf 上使用 pdfTeX、XeTeX 和 LuaTeX 引擎成功测试过（即 Overleaf 菜单中的 pdfLaTeX、XeLaTeX 和 LuaLaTeX 编译选项）：

![显示如何在 Overleaf 上选择 LaTeX 编译器的图片](/files/ebe863838c77981f0ad289766b45726c67d6f196)

回到我们的示例，我们想使用这段代码（带有深度嵌套的文件夹），并将借助 latexmkrc 文件来实现：

```latex
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics{endlinechar}% 最佳实践是不使用文件扩展名
\end{document}
```

下面这张截图显示上述代码正常工作：LaTeX 已经找到了我们的图形文件（`endlinechar.png`），尽管它位于一个深度嵌套的文件夹结构中（文件夹名称中没有任何空格）。

![显示一个带有嵌套文件夹的项目在 Overleaf 上编译的图片](/files/23e10215b5da2a542a4f01e01c9612f863a28a27)

那么，我们是怎么做到的？你只需要：

* 创建一个没有扩展名的新文件，并将其命名为 latexmkrc；
* 在该文件中添加下面这一行：

  ```
  $ENV{'TEXINPUTS'}='./graphics//:'.$ENV{'TEXINPUTS'};
  ```

Kpathsea 现在就会知道位于 `**graphics**` 下的文件夹，而且由于 `//` ，它也会查看子文件夹。

再次注意，其中的冒号在 `./graphics//:` 实际上是 *极其* 很重要。如果你省略那个冒号，那么 TeX/LaTeX 可能无法找到重要的系统文件，比如 LaTeX 宏包！

使用上面的简单项目示例，你现在可以编译它，然后哇！LaTeX 找到了你的图形文件——而且你可以重命名或重新组织 /graphics 下的文件夹，这也不会妨碍 LaTeX 找到它们。

## 列出 Kpathsea“配置变量”的表

下表是根据以下内容汇总得出的 [Kpathsea 文档中列出的数据](http://tug.org/texinfohtml/kpathsea.html#Supported-file-formats).

|                                                     |                                   |                                |
| --------------------------------------------------- | --------------------------------- | ------------------------------ |
| **Kpathsea 配置变量**                                   | **文件类型描述**                        | **文件后缀**                       |
| AFMFONTS                                            | Adobe 字体度量信息                      | .afm                           |
| MFBASES, TEXMFINI                                   | Metafont 内存转储                     | .base                          |
| BIBINPUTS, TEXBIB                                   | BibTeX 参考文献源文件                    | .bib                           |
| BLTXMLINPUTS                                        | 供 Biber 使用的 BibLaTeXML 参考文献文件     | .bltxml                        |
| BSTINPUTS                                           | BibTeX 样式                         | .bst                           |
| CLUAINPUTS                                          | Lua 的动态库                          | .dll 和 .so                     |
| CMAPFONTS                                           | 字符映射文件                            | .cmap                          |
| TEXMFCNF                                            | 运行时配置文件                           | .cnf                           |
| CWEBINPUTS                                          | CWEB 输入文件                         | .w, .web, .ch                  |
| TEXCONFIG                                           | Dvips 的“config.\*”文件，例如 config.ps |                                |
| ENCFONTS                                            | 编码向量                              | .enc                           |
| TEXFORMATS, TEXMFINI                                | TeX 内存转储                          | .fmt                           |
| FONTCIDMAPS                                         | CJK 映射                            | .cid                           |
| FONTFEATURES                                        | 主要用于 OpenType 字体特性                | .fea                           |
| FONTS, GFFONTS, GLYPHFONTS, TEXFONTS                | 通用字体位图                            | .gf                            |
| TEXPICTS, TEXINPUTS                                 | 封装式 PostScript 图形                 | .eps, .epsi                    |
| TEXINDEXSTYLE, INDEXSTYLE                           | makeindex 样式文件                    | .ist                           |
| LIGFONTS                                            | 连字定义文件                            | .lig                           |
| TEXMFDBS                                            | 文件名数据库                            |                                |
| TEXFONTMAPS                                         | 字体映射表                             | .map                           |
| MPMEMS, TEXMFINI                                    | MetaPost 内存转储                     | .mem                           |
| MPSUPPORT                                           | 供 DMP 使用的 MetaPost 支持文件           |                                |
| MFINPUTS                                            | Metafont 源文件                      | .mf                            |
| MFPOOL, TEXMFINI                                    | Metafont 程序字符串                    | .pool                          |
| MFTINPUTS                                           | MFT 样式文件                          | .mft                           |
| MISCFONTS                                           | 不属于其他类别的与字体相关的文件                  |                                |
| MLBIBINPUTS, BIBINPUTS, TEXBIB                      | MlBibTeX 参考文献源文件                  | .mlbib, .mlbib                 |
| MLBSTINPUTS, BSTINPUTS                              | MlBibTeX 样式                       | .mlbst, .bst                   |
| MPINPUTS                                            | MetaPost 源文件                      | .mp                            |
| MPPOOL, TEXMFINI                                    | MetaPost 程序字符串                    | .pool                          |
| OCPINPUTS                                           | Omega 编译后的过程文件                    | .ocp                           |
| OFMFONTS, TEXFONTS                                  | Omega 字体度量                        | .ofm, .tfm                     |
| OPENTYPEFONTS                                       | OpenType 字体                       |                                |
| OPLFONTS, TEXFONTS                                  | Omega 属性列表                        | .opl                           |
| OTPINPUTS                                           | Omega 转换过程文件                      | .otp                           |
| OVFFONTS, TEXFONTS                                  | Omega 虚拟字体                        | .ovf                           |
| OVPFONTS, TEXFONTS                                  | Omega 虚拟属性列表                      | .ovp                           |
| PDFTEXCONFIG                                        | PDFTeX 专用配置文件                     |                                |
| PROGRAMFONTS, PKFONTS, TEXPKS, GLYPHFONTS, TEXFONTS | 打包位图字体                            | .pk                            |
| TEXPSHEADERS, PSHEADERS                             | 可下载的 PostScript                   | .pro                           |
| RISINPUTS                                           | RIS 参考文献文件，主要用于 Bibe              | .ris                           |
| SFDFONTS                                            | 子字体定义文件                           | .sfd                           |
| TEXINPUTS                                           | TeX 源文件                           | .tex                           |
| TEXDOCS                                             | TeX 系统的文档文件                       |                                |
| TEXSOURCES                                          | TeX 系统的源文件                        |                                |
| TEXMFSCRIPTS                                        | 在 texmf 树中分发的与体系结构无关的可执行文件        |                                |
| TEXPOOL, TEXMFINI                                   | TeX 程序字符串                         | .pool                          |
| TFMFONTS, TEXFONTS                                  | TeX 字体度量                          | .tfm                           |
| TRFONTS                                             | Troff 字体                          |                                |
| TTFONTS                                             | TrueType 轮廓字体                     | .ttf, ,TTF, .ttc, .TTC, .dfont |
| T1FONTS, T1INPUTS, TEXPSHEADERS, DVIPSHEADERS       | Type 1 PostScript 轮廓字体            | .pfa, .pfb                     |
| T42FONTS                                            | Type 42 PostScript 轮廓字体           |                                |
| VFFONTS, TEXFONTS                                   | 虚拟字体                              | .vf                            |
| WEBINPUTS                                           | WEB 输入文件                          | .web, .ch                      |
| WEB2C                                               | web2c 实现特有的文件                     |                                |


---

# 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://overleaf-pro.ayaka.space/latex/zh-cn/shen-ru-wen-zhang/06-an-introduction-to-kpathsea-and-how-tex-engines-search-for-files.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.
