1

Below is a minimal example of some code where the memoir class seems to collide with Lua code, executed within a \directlua command, that writes to an external file.

Can anyone help me figure out the source of the problem? Is it possible to find a solution without abandoning the memoir class, in which, for this project, I am heavily invested?

Observed behavior:

There are two files below, somedocument.tex and someprogram.lua, the second called by the first.

Running lualatex somedocument.tex, as is, throws the following error in luaotfload:

(/usr/local/texlive/2020/texmf-dist/tex/latex/base/ts1cmr.fd)...xmf-dist/tex/lu
atex/luaotfload/fontloader-2020-12-30.lua:19085: attempt to call a nil value (f
ield 'suffix').
<to be read again> 
relax 
l.16 \end{document}
                 
? 
! Font \TU/lmr/m/sl/10=[lmromanslant10-regular]:+tlig; at 10pt not loadable: me
tric data not found or bad.

Note how the error does not appear until \end(document) is processed.

I found that I can make the error disappear, and everything run fine, with EITHER of these two changes (or both):

  • changing from memoir class to article class in the LaTeX preamble
  • commenting out the three file i/o lines in the Lua code so that it doesn't write anything to an external file

So it seems to be the conjunction of the memoir class and the use of Lua file i/o that is messing things up.

I was originally running texlive-2019 installed via the Ubuntu repositories, and installing texlive-2020 instead did not solve the problem.

Some context: This is the first time I have tried using Lua extensions in LaTeX. My LaTeX document contains many commands of the form \mycommand{xxx} where xxx should be both printed in the resulting document, and written to an external file. Previously I did this from LaTeX with \index, but thought using Lua would be an improvement.

Another clue is this issue which feels similar: microtype error with lualatex: "attempt to call field warning a nil value"

% somedocument.tex

\documentclass{memoir}
%\documentclass{article}

\directlua{dofile("someprogram.lua")}  % someprogram.lua contains lua function somecommand
\newcommand{\luacommand}[1]{\directlua{tex.write(somecommand("#1"))}}

\begin{document}

Hello world, this is the LaTeX file. Now we will call some Lua code.

\luacommand{foo}
\luacommand{bar}

\end{document}
-- someprogram.lua
function somecommand(mystring)
    tex.print("Writing " .. mystring .. " to file")
    file = io.open("output-file.txt", "a")
    file:write(mystring .. "\n")
    file:close()
end

1 Answer 1

4

You are declaring file as a global variable. This overwrites the file library which is part of lualibs and used in luaotfload, so every attempt to load a font fails. The observation that it still works with the article class is mostly luck: All fonts used afterr writing to the file have been used before, so they no longer have to be initialized and therefore no attempt is made to access the overwritten library. To fix this just use another name and/or make your variable local:

-- someprogram.lua
function somecommand(mystring)
    tex.print("Writing " .. mystring .. " to file")
    local file = io.open("output-file.txt", "a")
    file:write(mystring .. "\n")
    file:close()
end
1
  • 1
    The preferred approach (at least in ConTeXt) is to define a global table userdata = userdata or {} and stuff all data that has to be available globally in there, in this case userdata.file = ... Jan 6, 2021 at 17:55

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.