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?

1 Answer 1

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)))
}
4
  • Thanks works perfectly fine! What would be the preferred way to call a package from a top folder?
    – Reza
    Aug 13, 2018 at 11:48
  • You could add the top folder to \input@path. After that \usepackage{mymacros} would find it. Aug 13, 2018 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, 2018 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. Aug 15, 2018 at 9:10

You must log in to answer this question.

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