1

I have defined a command

\newcommand{\mypath}{/Documents/Myfile/additionalresources/}

that contains the path to some external files that I need in my main file. I need to use the \mypath command to set some dofile in a Lua part of my document, and I've tried with

dofile('\luastringN{\mypath}'..'mydata.lua'),

but it didn't work. Any suggestion? Thanks a lot!

  • 1
    Please could you be more clear for your question? What is your main file? – Sebastiano Oct 13 '18 at 9:47
4

I will assume you use the \luastringN command from the luacode package. What does \luastringN do? According to the luacode documentation

Fortunately, LuaTEX offers a primitive that does exactly what we need: escape characters that need to be escaped in a Lua string. Unfortunately, it has a very long name (especially in the prefixed form available in LATEX): \luatexluaescapestring. Also, you need to think to use quotes in addition to this primitive. So this package provides a shorter version: \luastring that also include the quotes, so a safer version of \foo might be defined as \newcommand*\foo[2]{\luadirect{foo(\luastring{#1}, #2)}} It should be noted that the argument of \luastring is fully expanded before being turned into a Lua string. In case where such an expansion is unwanted, two variants are provided: \luastringN for no expansion, and \luastringO for one-level expansion (of the first token) only.

So \luastringN does not expand its argument and includes the quotes. This means

dofile('\luastringN{\mypath}'..'mydata.lua'),

becomes

dofile('"\\mypath "mydata.lua')

This fails because the file "\mypath "mydata.lua does not exists.

We have to change two things: We have to get rid of the additional quotes and expand \mypath to the actual path stored in \mypath.

Getting rid of the quotes is easy: Never write quotes around \luastringN.

For the expansion you have to decide between full expansion and one-level expansion. Here there should be no difference because \mypath directly expands to the path and the path is not expandable, but I would recommend one-level expansion here: This avoids problems if you ever try to use a path containing active characters. So for one-level expansion, use \luastringO:

\documentclass{article}
\usepackage{luacode}
\newcommand{\mypath}{/Documents/Myfile/additionalresources/}
\begin{document}
\directlua{dofile(\luastringO{\mypath}..'mydata.lua')}
\end{document}

This works but there is another way to get the same result: Instead of using \luastringO to get the value of a macro from lua, just use the Lua function token.get_macro:

\documentclass{article}
\newcommand{\mypath}{/Documents/Myfile/additionalresources/}
\begin{document}
\directlua{dofile(token.get_macro'mypath' .. 'mydata.lua')}
\end{document}

This is more flexible because the macro name can be calculated by a Lua function, it is probably more efficient because the value of the macro is never inserted into the main token stream and you do not need any additional packages.

As more general advice I recommend to (almost) never use \luastring[NO] or \luaescapestring. The token library provides much nicer and safer interfaces for getting values from TeX.

One more detail: Instead of appending the strings with .., it is safer to use file.join: This ensures that there will always be a path separator between the components, even if \mypath does not have a trailing /.

\documentclass{article}
\newcommand{\mypath}{/Documents/Myfile/additionalresources/}
\begin{document}
\directlua{dofile(file.join(token.get_macro'mypath', 'mydata.lua'))}
\end{document}

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.