0

The general idea is that I can get the relative path of my project root by including the package mymacros.sty in my subprojects. I have the following setup:

  • mymacros.sty
  • myimg
    • figure.tikz

the content of mymacros.sty looks like this:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mymacros}
\RequirePackage{xparse}

\NewExpandableDocumentCommand \projectabspath {}
{%
  \directlua{tex.print(file.pathpart(file.addsuffix(file.collapsepath("\@currname"),'sty')))}%
}

I'm extracting the relative path from the \@currname macro with lua.

When I call the macro in my file figure.tikz

\documentclass{standalone}
\RequirePackage{luatex85}

\usepackage{../mymacros}
\typeout{\projectabspath}

\begin{document}
absolute path: \projectabspath
\end{document}

I get an empty path. What is the problem with my code?

3

To quote David Carlisle:

The argument of \usepackage is a name not a file path. The fact that it sometimes works at all when passed a relative file path is just due to lack of error checking by the system. If the package does declare itself using \ProvidesPackage the use of such paths will generate a warning that the name is incorrect.

Let's ignore that for a second and see why your code does not work:

You get the value of \@currname at the point the macro is expanded, which is in the middle of your document. There is no current package at that point, so \@currname is empty.

To fix this you have to expand \projectabspath while reading the package. You can use \edef to archive this:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mymacros}

\edef \projectabspath
{%
  \directlua{tex.print(file.pathpart(file.collapsepath("\@currname", true)))}%
}

or define the macro directly from Lua:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mymacros}

\directlua{
  token.set_macro('projectabspath', file.pathpart(file.collapsepath(token.scan_string(), true)))
}\@currname

Note that I added , true to collapsepath, otherwise the returned path is not absolute.

In general LuaTeX provides a more reliable way to get the path of the current file that analyzing \@currname: Use status.filename.

    \NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mymacros}

\directlua{
  token.set_macro('projectabspath', file.pathpart(file.collapsepath(status.filename, true)))
}
  • Thanks works perfectly fine! What would be the preferred way to call a package from a top folder? – Reza Aug 13 '18 at 11:48
  • You could add the top folder to \input@path. After that \usepackage{mymacros} would find it. – Marcel Krüger Aug 13 '18 at 11:53
  • Why is it not working when I use lfs.currentdir() instead of \@currname to determine the path of mymacros.sty? – Reza Aug 15 '18 at 7:09
  • @Reza lfs.currentdir() returns the current working directory of the TeX process. TeX never changes the working directory during a run, so lfs.currentdir() always gives the directory TeX was called from. Normally this is the directory of your main document. – Marcel Krüger Aug 15 '18 at 9:10

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.