Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

share|improve this question
2  
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
1  
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

3 Answers 3

up vote 10 down vote accepted

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.

share|improve this answer
1  
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

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

share|improve this answer
    
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

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.

share|improve this answer
3  
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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