我有一个项目结构
.
├── includes
│ ├── apxproof.sty
│ └── somecustommodule.sty
└── tex
└── document.tex
包括一个错误修复版本apxproof.sty
并\input@path
设置document.tex
。\def\input@path{{../includes}}
调用时cd tex; pdflatex document
,虽然somecustommodule.sty
按预期加载\usepackage
,但apxproof
使用了全局安装的 MikTeX 包。
这让我感到疑惑:相对于 ,LaTeX 路径的搜索顺序是怎样的\input@path
,我可以让 LaTeX 优先../includes/
于分发文件,而不依赖于 这样的系统范围设置TEXINPUTS
吗?
我目前的解决方法是使用\usepackage{../includes/apxproof}
,这会引发警告
You have requested package `../includes/apxproof', but the package provides `apxproof'.
可以使用沉默包来过滤掉此类警告,但我宁愿不冒险错过相关警告。
完整模型示例
%% ==== tex/document.tex
\documentclass{article}
\makeatletter
\def\input@path{{../includes/}}
\usepackage{apxproof}
\usepackage{somecustommodule}
\begin{document}
\SomeCustomCommand
\ApxproofCustomCommand
\end{document}
%% ==== includes/apxproof.sty
\newcommand{\ApxproofCustomCommand}{(from apxproof.sty)}
%% ==== includes/somecustommodule.sty
\newcommand{\SomeCustomCommand}{(from somecustommodule.sty)}
答案1
处理\input@path
过程非常简单,它只是将提供的目录添加到文件名前面,但出于“效率”的原因,它总是首先尝试给定的文件名,因此
\input{somecustommodule.sty}
将尝试按顺序
\realinput{somecustommodule.sty}
然后\realinput{../includes/somecustommodule.sty}
kpathsea
在每种情况下都使用完整文件搜索。
假设这里第一个失败了,所以文件被第二个找到,正如你所希望的那样。
但是,由于apxproof.sty
第一个标准包已成功,因此\input@path
不使用。
我个人会使用 TEXINPUTS(尽管我已经实现了\input@path
:-) 它不必是系统范围的设置,如果您愿意,您可以(在大多数命令 shell 中)仅为单个调用设置它,例如在 bash 中您可以这样做
TEXINPUTS=../includes: pdflatex myfile
或者(通常更简单)给固定版本apxproof.sty
一个不同的名称,这样您就不依赖目录路径搜索顺序来区分这两个文件。
答案2
更简单的解决方案:在文件名前面添加./
。
一旦想要切换回系统风格,请删除./
。
工作代码
假设../includes
符合问题。
\documentclass{article}
\makeatletter
\def\input@path{{../includes}}
\makeatother
\usepackage{./apxproof}
\usepackage{./somecustommodule}
\begin{document}
\SomeCustomCommand
\ApxproofCustomCommand
\end{document}
解释
如果搜索的文件路径是绝对或明确相对,即以 '/' 或 './' 或 '../' 开头,TeX 通过 Kpathsea 简单检查该文件是否存在,如果需要并启用,则回退到大小写折叠匹配。
经验法则
所有文档级文件路径应绝对或明确相对原因有二:
- 它加快了文件查找机制
- 它可以防止实际和未来名称冲突
如果您不使用前导.
或/
- 接下来非常常见的文件名不能在子文件夹内使用
\input@path
,\l_file_search_path_seq
和\graphicspath
机制:list.tex
,,,...variations.tex
left.pdf
hand.png
- TeX 发行版的更改可能会暗中破坏你的文件在你背后,更重要的是,它可以破坏你的文件默默!
今天可以安全地使用middle.pdf
,但明年,这个名字就可以被一个包使用,就像left.pdf
和right.pdf
已经一样,默默地优先于你自己包含的文档。
随着 MikTeX 基础 TeX 分发概念的出现,事情变得更加复杂:加载新包可能会破坏现有文档。