大多数(如果不是全部)编程语言都提供了返回可执行文件完整路径的函数,例如ActiveWorkbook.Path
,Excel/VBA
该功能允许编写不受目录中可执行文件位置影响的代码。我正尝试使用该\file_add_path
函数(l3file
包,我的副本中的第 136 页interface3
),目的类似。虽然\file_if_exist
和\file_add_path
显示对位于本地文件夹中的文件的一些识别,但它们并没有达到我的预期,即\file_if_exist
无法识别位于目录中其他位置的文件,也无法\file_add_path
返回我的“可执行” .tex 文件的完整路径。我做错了什么?
% filename: MWE-23-25Sep2017-addpath.tex
\documentclass{article}
% RN. 25 Sep 2017
%\usepackage{comment}
%\usepackage[check-declarations]{expl3}
\usepackage{xparse}
%-----------------------
\ExplSyntaxOn
% variable declaration:
\tl_new:N \l_rn_path_tl
\NewDocumentCommand\myPathToFile{m}
{
\file_if_exist:nTF {#1}
{
#1:~FILE~EXISTS.\\full~path:~
\file_add_path:nN {#1} \l_rn_path_tl
\tl_use:N \l_rn_path_tl
}
{
#1:~FILE~DOES~NOT~EXIST
}
}
\ExplSyntaxOff
%-----------------------
\begin{document}
1. \myPathToFile{MWE-23-25Sep2017-addPath}
2. \myPathToFile{MWE-23-25Sep2017-addPath.tex}
3. \myPathToFile{XXX-23-25Sep2017-addPath.tex}
\end{document}
答案1
为了回答这个问题,我们首先需要了解 TeX 系统如何查找文件的一些背景知识。
与许多其他编程语言不同,在 TeX 中我们通常不必担心文件的路径。该kpathsea
库被主要的 TeX 发行版(TeX Live、MiKTeX)使用,它允许我们将整个安装视为“平面”:例如,
\usepackage{color}
不是
\usepackage{tex/latex/graphics/color}
或者(在我的系统上)
\usepackage{c:/texlive/2017/texmf-dist/tex/latex/graphics/color}
此概念通过变量传递到“本地”文件中TEXINPUTS
。如果我们有一个“此处”目录
- a.tex
- b.tex
+ ----- subdir
+ - c.tex
+ - d.tex
我们可以成功做到
\input{a}
但不是
\input{c}
因为后者不在这里,所以我们需要
\input{subdir/c}
然而,如果我们
TEXINPUTS=.//;
然后我们设置当前目录的递归搜索,现在
\input{c}
有效。(语法是,//
表示“从这里递归”,而尾随;
表示“紧随标准安装树”。请注意,后者表示标准树中的所有内容都在“这里”。)
这将如何影响\file_add_path:nN
?关键是我们不是创建绝对路径,而是在路径开头添加“片段”:后者在中设置\l_file_search_path_seq
。回到我的“本地”目录示例,假设的标准设置,无需添加即可TEXINPUTS
找到,我们可能会有c.tex
subdir
\seq_push:Nn \l_file_search_path_seq { subdir }
\file_add_path:nN { c.tex } \l__my_tmp_tl
TeX ( expl3
) 现在将首先搜索“此处”,然后搜索“此处 + “subdir/””以查找名为 的文件c.tex
。如果无法在“此处”找到它,但可以使用该前导路径找到它,则将返回
> \l__my_tmp_tl=subdir/c.tex
这正是我们所需要的:一个允许我们使用该文件的路径。
请注意,在 TeX 中我们无法获得目录列表或类似内容,因此无法搜索例如“当前目录的所有子目录”。我们必须知道要查找的位置的名称。kpathsea
当然,库没有这个限制(因此TEXINPUTS
可以使用),Lua 也没有(仅在 LuaTeX 的情况下)。