我需要找到 latex 文件的绝对路径,因为它位于文件系统中。这看似是一项简单的任务,但实际上比我想象的要难。
这是 MWE。我有这棵树
/media/data/latex/path_problem/parent.tex
+
|____/A/B/child.tex
上面的意思是
/media/data/latex/path_problem/parent.tex
/media/data/latex/path_problem/A/B/child.tex
单独编译 child.tex 时,它应该报告与编译 parent.tex 时相同的绝对路径,然后导入 child.tex。原因是,我需要使用子路径的字符串lua
来调用函数child.tex
,并且如果我将其编译为独立文件或与较大的文档组合,则此字符串必须相同,child.tex
否则它将无法工作。
父级subimports
为 child.tex。我正在使用独立包。
我尝试了很多解决方案,但都不起作用,因为当导入时child.tex
,它成为的父级parent.tex
,并且它报告的路径是父级的路径。
解决方案约束
适用于 Windows 和 Linux,但现在让解决方案在 Linux 上运行就足够了,然后我可以将其转换为在 Windows 上运行。
解决方案必须在第一次编译时起作用,即不需要多次编译,因为我使用路径进行使用 lua 的实际处理,如果我需要多次编译文档才能获取名称,它将第一次失败。
我无法修改parent.tex
来修补任何东西。它应该可以自行工作。所有需要的代码更改都应该在 里面child.tex
。
lualatex
由于我正在使用 lua 函数,因此才需要该解决方案。
这是第一次尝试。
child.tex
\documentclass{article}
\IfFileExists{luatex85.sty}{\usepackage{luatex85}}{}
\ifdefined\HCode
\usepackage[utf8]{luainputenc}
\usepackage[T1]{fontenc}
\else
\usepackage{fontspec}
\fi
\usepackage{standalone}
\standalonetrue %in child
\usepackage{import}
\usepackage{shellesc}
\usepackage{filecontents}% http://ctan.org/pkg/filecontents
\usepackage{moreverb}
\begin{document}
\immediate\write18{pwd > temp.dat}
I am the child file, and my path is \verbatiminput{temp.dat}
\end{document}
编译后B>lualatex -shell-escape child.tex
当然会给出正确的结果
现在,当我编译 parent.tex 时:
\documentclass{article}
\IfFileExists{luatex85.sty}{\usepackage{luatex85}}{}
\ifdefined\HCode
\usepackage[utf8]{luainputenc}
\usepackage[T1]{fontenc}
\else
\usepackage{fontspec}
\fi
\usepackage{standalone}
\usepackage{import}
\usepackage{shellesc}
\usepackage{moreverb}
\usepackage{filecontents}% http://ctan.org/pkg/filecontents
\begin{document}
\subimport{A/B/}{child}
\end{document}
编译后,path_problem>lualatex -shell-escape parent.tex
它会按预期提供父路径。我无法修改父路径中的任何内容来更正此问题。
第二次尝试。
改为child.tex
这样(其他都一样)
\begin{document}
\immediate\write18{kpsewhich \jobname.tex > temp1.dat}
I am the child file, and my path is \verbatiminput{temp1.dat}
\end{document}
按照上述方法编译子程序,结果如下
编译父代如上所述,得到
第三次尝试
尝试了currfile-abspath
软件包,但是在 Linux 上由于某种原因它对我来说不起作用:
如何使录音机在 tl-2016 中工作,所需的录音机文件 fls 不存在
但是它在windows上也需要2次编译,这就意味着我无法使用它。
我正在寻找的是类似于 C 宏文件
__FILE__
This macro expands to the name of the current input file,
in the form of a C string constant. This is the path by which the
preprocessor opened the file, not the short name specified
in #include or as the input file name argument.
For example, "/usr/local/include/myheader.h" is a possible
expansion of this macro.
即需要获取 Latex 文件的物理绝对路径字符串,无论它是使用\input
还是将其拉入另一个文件,\include
即\subimport
该字符串在物理上附加到文件本身,而不是文件碰巧所属的最终文档,后者可能位于文件系统的其他地方。TL 2016
解释一下我为什么需要这个
下面是一个小例子,说明为什么我需要这个。假设我code/foo.m
在子文件夹下有一个文件。我需要调用一个 lua 函数以某种方式处理这个文件。所以我需要发送文件的路径。但是当使用父级编译时,我不能直接传递,code/foo.m
因为路径现在已经改变了。所以我现在要做的是
\ifstandalone % Is this the child?
\luadirect{ process("code/foo.m") }
\else %change, since now i must be the parent
\luadirect{ process("parent/child/code/foo.m") }
\fi
如果我能找到孩子的绝对路径,我就可以构建正确的路径,并将上面的内容更改为
\luadirect{ process("/home/me/parent/child/code/foo.m") }
当我单独编译子文档时,或者将子文档作为较大文档的一部分进行编译时,它都会起作用。
答案1
这实际上不是对您问题的回答,而是对您的“澄清您为什么需要它”的评论。在我的一个项目中,我也使用了独立包,并且还必须处理 \input 和 \includegraphics 需要不同路径(如果编译主程序或编译子程序)的问题。
我实施的解决方案是在每个文件夹中添加一个小的配置文件,其中包含一个简单的命令,描述了从该文件夹“到根目录”的路径:
\newcommand\pathprefix{../../}
然后,每个文档从其自己的起始文件夹加载配置文件,因此知道它相对于根文件夹的位置。
然后每个人\input
都可以使用\input{\pathprefix path/from/the/root}
,并且这对于主文档和子文档都适用。
另外:假设根目录中有一些特殊文件,您可以\pathprefix
通过尝试查找此文件自然地找到所需的文件:
\IfFileExists{./specialfile.tex}
{\newcommand\pathprefix{}} %in the root
{\IfFileExists{../specialfile.tex}
{\newcommand\pathprefix{../}} %one folder down
{\IfFileExists{../../specialfile.tex}
....