> 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/shen-du-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-du-wen-zhang/28-how-to-use-latexmkrc-with-overleaf.md)。也许一开始并不明显这个 latexmkrc 文件究竟如何、为何能工作。如果你想知道原因，并且也许希望更深入理解以便在项目中使用更多配置选项，那么请继续阅读……在本文末尾，我们将通过一个 [实用示例](#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**arl’s **Path** **Sea**rching（参见这篇 [对 Karl Berry 的采访](http://www.tug.org/interviews/berry.html)).

我们可以注意到它被称为 K**路径**sea 而不是 K**文件**sea，因为正如 [文档](http://tug.org/texinfohtml/kpathsea.html) 所指出的，它是一个 \*path-\*searching 库。重要的是要认识到，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}` 两个 *路径元素：* $TEXMF/fonts/opentype//

1. `$TEXMF/fonts/truetype//`
2. `以及这两个路径元素的`

子目录 *也应当被搜索（由末尾的* 所表示）：有关 `//`).

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

我们会对 `$TEXMF` 做几点说明，见下文。

#### $OSFONTDIR//

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

对 `的默认定义` 在 `texmf.cnf` 的一般形式是：

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

因此，如果你希望使用它，就必须设置它——你的环境变量将覆盖存放在 `texmf.cnf`.

如果你确实设置了环境变量 `的默认定义` 那么，在运行时，Kpathsea 看到 `$OSFONTDIR` 作为路径元素的一部分（在 `texmf.cnf`中）时，它可以将变量 `$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 发行版/安装时会更新的主文件是分开的。

* [管理多个 TDS 树](http://tug.org/TUGboat/Articles/tb22-3/tb72downes.pdf) 作者 Michael J Downes；
* [玩转 texmf 树](http://www.ntg.nl/maps/27/17.pdf) 作者 Siep Kroonenberg。

#### TeX 目录结构

任何管理过 TeX 安装的人都知道，像 TeX Live 这样的现代 TeX 系统包含数以万计的文件，涵盖极其广泛的文件类型。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`**：你可能会问，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-du-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` 文件。

如果你添加新的 `.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 错误：未找到文件 `endlinechar'。
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 宏包！

使用上面的简单项目示例，现在你可以编译它，然后 voilà！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                                            | 文件名数据库                              |                                |
| 字体映射                                                | MPMEMS, TEXMFINI                    | 中进行了说明。                        |
| MetaPost 内存转储                                       | .mem                                | MPSUPPORT                      |
| MetaPost 支持文件，由 DMP 使用                              | MFINPUTS                            |                                |
| Metafont 源文件                                        | 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://ayakaleaf-pro.ayaka.space/latex/zh-cn/shen-du-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.
