Full path of current file

This question led to a new package:
currfile-abspath (subpackage to currfile)

How can I display the full path of the tex file that I compile? It is a simple file, no include or input present.

Edit: I use MiKTeX 2.9 on a Windows 7 64-bit.

Less demanding: If not possible, then I will be satisfied with a partial path (at least one or two folders up + the filename).

-
There is no possibility to get the full path with TeX-only methods. You usually only get the main base file name without extension (using \jobname). You will need to call some external tool which is operation system depending from within your LaTeX document. – Martin Scharrer Jan 26 '12 at 22:48
Is it possible to use the log file? I see there the full path of the file (on the 4th line). – digital-Ink Jan 27 '12 at 0:05
Mmm, you could try to read the log file back, but this isn't trivial. Unfortunately this information can't be accessed directly. – Martin Scharrer Jan 27 '12 at 0:09
So, basically, I have to write a macro that checks that the log file exists, and when it does, reads the text file as verbatim and outputs the 4th line. Are there such commands available in TeX? – digital-Ink Jan 27 '12 at 10:31
Yes, \IfFileExists and \readline, but I wouldn't take it for granted that it is always in the fourth line. – Martin Scharrer Jan 27 '12 at 10:54
show 1 more comment

The full path is written into the .fls file generated by the -recorder option with TeXLive (MikTeX should have a similar option, maybe --recorder). This files seems to be flushed every line while written, so that it is possible to read the paths of all files accessed so far in the current compiler run.

I wrote the following code to search for a INPUT <path><jobname>.tex line in the .fls file. It also read the first PWD <parent directory> line which is used if the jobname is local. This was actually the easy part and should cover 99.99% of all cases. I just added the remaining parsing code to allow of situations like pdflatex /direct/path/to/document.tex. This should cover usages of -output-directory as well.

I might add this code in my currfile package.

\documentclass{article}

\makeatletter
\def\thepwd@default{./}
\let\thepwd\thepwd@default
\let\theabspath\@empty
\newcommand\getabspath{%
\begingroup
\edef\filename{\jobname.tex}%
\@onelevel@sanitize\filename%
\let\thepwd\thepwd@default
\let\theabspath\@empty
\IfFileExists{\jobname.fls}{%
\openin\@inputcheck=\jobname.fls\relax
\endlinechar\m@ne
\expandafter\getabspath@extr\line\relax\relax\relax\relax\relax
\expandafter\getabspath@defs\expandafter{\filename}%
\loop
\@onelevel@sanitize\line
\expandafter\getabspath@path\expandafter{\line}%
\ifeof\@inputcheck
\let\iterate\relax
\fi
\ifx\theabspath\@empty
\repeat
\closein\@inputcheck
}{%
\PackageWarning{getabspath}
{The required recorder file (.fls) was not found.\MessageBreak
Please compile with the '-recorder' option.\MessageBreak
Occurred}%
}%
\ifx\theabspath\@empty
\let\theabspath\thepwd
\fi
\edef\@tempa{%
\def\noexpand\thepwd{\thepwd}%
\def\noexpand\theabspath{\theabspath}%
}%
\expandafter
\endgroup
\@tempa
}
\def\getabspath@extr#1#2#3#4#5\relax{%
\edef\@tempa{\detokenize{#1#2#3}}%
\edef\@tempb{\detokenize{PWD}}%
\ifx\@tempa\@tempb
\edef\thepwd{\detokenize{#4#5/}}%
\fi
}

\begingroup
\catcodeI=12
\catcodeN=12
\catcodeP=12
\catcodeU=12
\catcodeT=12
\gdef\getabspath@defs#1{%
\def\getabspath@@path ##1INPUT ##2#1\relax##3\relax##4\@nnil{%
\ifx\@empty##4\@empty\else
\def\theabspath{##2}%
\fi
}%
\def\getabspath@path##1{%
\getabspath@@path##1\relax INPUT \@empty#1\relax{}\relax\@nnil
}%
}
\endgroup
\makeatother

\getabspath
\message{Absolute path: \theabspath^^J}
\message{PWD: \thepwd^^J}
\begin{document}
This file has the absolute path \texttt{\theabspath\jobname.tex}.

PWD: \texttt{\thepwd}
\end{document}


Update 2011/05/05:

I now made this functionality part of my currfile package. It is provided as sub-package currfile-abspath which can also be used on its own. It provides \getmainfile, \getabspath{<file>} and \getpwd which set \themainfile, \theabspath and \thepwd to the main file name (which might be different than \jobname.tex), the absolute path of the given file and the parent working directory of the compiler run.

This new version of currfile is now released as v0.6 2011/05/06.

-
The option in MiKTeX is the same, i.e., -recorder. Running: latex -recorder test_file.tex twice produces the correct result. I also tested it with pdflatex and it works in the same way. Note that I get the .fls after the first run of latex or pdflatex. – digital-Ink May 2 '12 at 20:53
@digital-Ink: I didn't tested it under Windows yet myself. With TeX Live under Linux it works at the first run, but it can be easily be different under Windows (both MikTeX and TeX Live), or be an MikTeX specific thing. I'm planning to add this feature to my currfile package as an option. – Martin Scharrer May 2 '12 at 21:29
@digital-Ink: I just tested it myself under Windows: It works in the first run under TeX Live 2012 but requires two runs with MikTeX, which seems to write the .fls file just after the compilation. – Martin Scharrer May 4 '12 at 17:47

Here's a solution that works on Unix systems and pdflatex -shell-escape:

\makeatletter
\def\fullpath{\begingroup\everyeof{\noexpand}\@sanitize
\edef\x{\@@input|"find pwd -name \jobname.tex" }%
\edef\x{\endgroup\noexpand\zap@space\x\noexpand\@empty}\x}
\makeatother


Then \fullpath will print the full path of the file you're typesetting.

There's really no way to get the full path from inside TeX, so an escape to the operating system is necessary.

-
An alternative would be realpath kpsewhich \jobname.tex ,but I don't know if both these tools are available under MS Windows. – Martin Scharrer Jan 26 '12 at 22:50
There's no realpath on Mac OS X. However the technique should work if one finds the correct magic command to use on Windows. – egreg Jan 26 '12 at 22:53

Martin suggested me to write a LuaTeX version, so here it is. :)

Run with lualatex:

\documentclass{article}

\usepackage{luacode}
\usepackage[T1]{fontenc}

\begin{luacode}
-- we need the LuaFileSystem
-- library
require 'lfs'

-- builds path according to the system
-- path separator, as I used in this answer:
-- http://tex.stackexchange.com/a/48241/3094
function buildPath(...)

-- get the system path separator
local pathseparator = package.config:sub(1,1)

-- get the arguments
local elements = {...}

-- return the elements with the path separator
return table.concat(elements, pathseparator)
end

-- get the current path plus the file name.
function getPath(filename)

-- print the input command. According to the
-- documentation, if -2 is used, then the strings
-- are read as if the result of detokenize: all
-- characters have catcode 12 except space, which
-- has catcode 10.
tex.print(-2, buildPath(lfs.currentdir(), filename))

end
\end{luacode}

\begin{document}

\fullpath{\jobname.tex}

\end{document}


The output when in my Windows machine:

And when in my Linux box:

Hope it helps. :)

-
 Nice! LuaTeX is really flexible. I have to check again if (La)TeX requires / instead of \` also under Windows. – Martin Scharrer♦ Apr 28 '12 at 13:24