36

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

0

4 Answers 4

22

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 file seems to be flushed every line while it is being 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 for 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
        \readline\@inputcheck to \line
        \expandafter\getabspath@extr\line\relax\relax\relax\relax\relax
        \expandafter\getabspath@defs\expandafter{\filename}%
        \loop
            \readline\@inputcheck to \line
            \@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
\catcode`I=12
\catcode`N=12
\catcode`P=12
\catcode`U=12
\catcode`T=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 have now made this functionality part of my currfile package. It is provided as a 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 from \jobname.tex), the absolute path of the given file and the parent working directory of the compiler run.

This new version of currfilej has now been released as v0.6 2011/05/06.

4
  • @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. Commented May 4, 2012 at 17:47
  • Thank you for this very nice package. However, it outputs dots above the line instead of underscores. How could I fix this? Commented Apr 2, 2019 at 23:59
  • @IosifPinelis: ist does not output anything, it provides you with the filename stored as raw characters in a macro. Now LaTeX does handle raw underscores this way due to font encoding reasons. To get correct underscores when typesetting the filename you need to switch the font to texttyper (\texttt) or similar. If the macro would contain font instructions you couldn't use it inside log messages or as part of an \input path. Commented Apr 3, 2019 at 5:02
  • By "This should cover usages of -output-directory as well." do you mean "This solution handles the files in -output-directory correctly"?
    – user202729
    Commented Nov 6, 2021 at 2:07
15

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}

\newcommand\fullpath[1]{\luadirect{getPath(\luastring{#1})}}

\begin{document}

\fullpath{\jobname.tex}

\end{document}

The output when in my Windows machine:

Windows output

And when in my Linux box:

Linux output

Hope it helps. :)

2
12

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.

4
  • 3
    An alternative would be realpath `kpsewhich \jobname.tex` ,but I don't know if both these tools are available under MS Windows. Commented Jan 26, 2012 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
    Commented Jan 26, 2012 at 22:53
  • Isn't find terribly slow if there are a whole drive of folders in the current directory? Besides it won't work if the user include TeX file from somewhere else.
    – user202729
    Commented Nov 5, 2021 at 13:48
  • In windows is dir /s/b \jobname.tex
    – J Leon V.
    Commented Feb 22 at 17:22
1

This is now standard LaTeX functionality: \CurrentFilePath gives the directory that this file lives on (relative or absolute depending on how it was imported).

This is documented here: Internal Package ltfilehook

3
  • This is not what I am experiencing. In a .sty file in my local texmf, \CurrentFilePath and \CurrentFilePathUsed are empty.
    – ysalmon
    Commented Aug 27, 2022 at 22:15
  • Note that "The paths returned in \CurrentFilePath are only user paths, given through \input@path (or expl3’s equivalent \l_file_search_path_seq) or by directly typing in the path in the \input command or equivalent. Files located by kpsewhich get the path added internally by the TeX implementation, so at the macro level it looks as if the file were in the current folder, so the path in \CurrentFilePath is empty in these cases" -- in other words ■ if you do \input{b.tex} then \CurrentFilePath will be empty, if you do \input{/full/path/to/b.tex} then \CurrentFilePath will be
    – user202729
    Commented Nov 25, 2022 at 9:19
  • /full/path/to, and in the main file \CurrentFilePath will be empty. ■ \input{\CurrentFilePath/\CurrentFile} will always work to input the current file, except for the main file where it might not when the main file is not in the current working directory. Refer to tex.stackexchange.com/q/153751/250119 for details.
    – user202729
    Commented Nov 25, 2022 at 9:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .