0

I need to find the absolute path of a latex file, as it sits on file system. Seems like a simple task, but it turns out to be harder than I thought.

Here is a MWE. I have this tree

/media/data/latex/path_problem/parent.tex
                        +
                        |____/A/B/child.tex

What the above mean is this

/media/data/latex/path_problem/parent.tex
/media/data/latex/path_problem/A/B/child.tex

When compiling child.tex on its own, it should report the same absolute path as when compiling parent.tex and it then imports child.tex. The reason is, I need to call lua function from child.tex with a string of the path of the child, and this string have to be the same, if I compile child.tex as standalone or as combined with larger document, else it will not work.

The parent subimports the child.tex. I am using standalone package.

I have tried many solutions, and none of them work, since when importing the child.tex, it becomes parent of the parent.tex, and the path it reports is that of the parent.

Solution constraint

Works on windows and Linux, but it is enough for now to have the solution work on Linux, and then I can convert it work on windows.

The solution has to work on first compilation, i.e. does not require multiple compilation, since I use the path for actual processing using lua, and it will fail first time if I need to compile the document multiple times to get the name.

I can't modify the parent.tex to patch anything. It should work on its own. All code changes needed should be inside child.tex.

The solution is only needed for lualatex since I am using lua functions.

Here is first attempt.

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}

Compiled with B>lualatex -shell-escape child.tex and it gives correct result ofcourse

Mathematica graphics

Now when I compile the 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}

compiled with path_problem>lualatex -shell-escape parent.tex It gives the parent path as expected. I can't modify anything in the parent to correct this.

Mathematica graphics

second attempt.

Changed child.tex to this (everything else the same)

\begin{document}
\immediate\write18{kpsewhich \jobname.tex > temp1.dat}
I am the child file, and my path is \verbatiminput{temp1.dat}
\end{document}

Compiled the child as above, and it gives

Mathematica graphics

Compiled parent as above, and it gives

Mathematica graphics

Third attempt

Tried currfile-abspath package, but it did not work for me for some reason on linux:

how-to-make-recorder-work-in-tl-2016-the-required-recorder-file-fls-was-not

But it also requires 2 compilations on windows, which means I can't use it.

What I am looking for, is similar to the C macro FILE

__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. 

i.e. need to obtain a string of the physical absolute path of a Latex file, regardless if it was pulled into another file using \input or \include or \subimport i.e. this string is attached physically to the file itself, not to the final document the file happened to be part of which can be somewhere else in the file system. TL 2016

Clarify why I need this

Here is a small example why I need this. Lets say I have file code/foo.m under the child folder. I need to call a lua function to process this file in some way. So I need to send the path of the file. But when compiled with the parent, I can't just pass code/foo.m since the path has changed now. So what I do now is this

\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 

If I can find the absolute path of the child, I can build the correct path and change the above to be

   \luadirect{ process("/home/me/parent/child/code/foo.m") }    

and it will work when I compile the child standalone, or when I compile the child as part of larger document.

1

Not really an answer to your question but a comment to your "clarify why you need it". In one of my projects I used the standalone package too and also had to handle the problem that \input and \includegraphics needed different pathes if the master was compiled or if a child was compiled.

The solution I implemented was to add in every folder a small config-file with a simple command in it which described the path from this folder "to the root":

\newcommand\pathprefix{../../} 

Every document then loaded the config-file from its own start folder and so knew where is it relativ to the root folder.

Every \input could then use \input{\pathprefix path/from/the/root} and this worked fine for master and for child documents.

Addition: assuming that there is in the root some special file you can naturally find out the needed \pathprefix by trying to find this file:

\IfFileExists{./specialfile.tex}
  {\newcommand\pathprefix{}} %in the root
  {\IfFileExists{../specialfile.tex}
   {\newcommand\pathprefix{../}} %one folder down
   {\IfFileExists{../../specialfile.tex}
    ....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.