I cannot claim to be more than a dabbler with Luatex, nor really a Lua person; I hope those more knowledgeable than I am will forgive my blunders, but I can at least report my experience.
Within Luatex, package.searchers
is replaced, so that when you require
a module from TeX, Luatex uses TeX's searching mecanism not the usual one. That means in practice that when you run Lua from within Luatex, it won't find modules that your normal system Lua finds. (I don't know enough about the architecture, but I assume it's deliberate, because it wants to be able safely to maintain different parallel structures and be sure that LuaTeX will always pick up TeX-appropriate modules, even if other modules are installed elsewhere.)
In practice that means that if you have installed a lua module via luarocks, you will need either to place a copy, or to include a symbolic link, within a directory that kpathsea
will find. Luarocks is a pretty simple-minded thing, as far as I can tell, and simply dumps files in a convenient directory, so you should be able to find them and link to them or copy them. The documentation rather cutely warns "Of course it no big deal to write an alternative loader and use
that in a macro package", though for some of us (like me!) that may be quite a big deal.
I have no experience of how this plays if you are using a lua module which is not pure Lua but is relying on code compiled from C. Luatex itself already links some such libraries (like slnunicode
), but I have no idea how that may affect your use case I'm afraid. I'd hope it would "just work", but ...
When you are building something which you want to test both as a standalone and as something that will be tied to TeX, I found by trial and error:
If you need (as you conceivably may) code that executes only if it is in one environment or another, test for the definition of lua.version
which will be defined if you are running in Luatex. I suppose strictly speaking just a check for lua is enough (and a check for lua.version
isn't safe, because if lua
is undefined it will error).
if lua and lua.version then
-- we're in LuaTeX
else
-- we're not
end
One way of developing in parallel is to use texlua
as your lua interpreter. If you do that, you will get access automatically to the statically linked libraries that are always part of luatex (like LPEG
and slnunicode
, i.e. without needing to require
them). And your script will run more or less "as if" it were running via a call from a TeX document. But there's a catch. Texlua does not automatically "find" the kpathsea
function, so you need to "tell" it what to do:
kpse.set_program_name("kpsewhich") -- or whatever
Now, for instance
local xml = require("luaxml-domobject")
will find the appropriate module in the TeX directory tree, using kpsewhich
: without that magic, you will get the dismal complaints from package.loader
about not finding the module. Or, worse, you will get a module with that name, but not the one you will get when Luatex is "really" in charge.
The code below may be easier to follow than the explanation! If you run it with texlua
you will get one output; if with lua
a slightly different output, but in both cases it works.
local luatexing = lua and lua.version
-- local lpeg shadows global lpeg if luatex is running this
local lpeg = lpeg
if luatexing then
kpse.set_program_name("kpsewhich")
else
-- if luatex is not in charge we need to require the library
lpeg = require("lpeg")
end
-- The output here will differ depending on
-- whether we have luatex (with statically
-- linked unicode library) or not. Of course,
-- we could then `require` something
-- appropriate.
if luatexing then
io.write(unicode.utf8.lower("Ê") .. "\n")
else
io.write(string.lower("Ê") .. "!\n")
end
-- But this will work in either case: with
-- luatex via the statically linked lpeg
-- library. With regular lua via the require
j = lpeg.P("a matcher")
io.write(j:match("a matcher") .. "\n")
What I don't know, because I haven't really explored it, is whether one needs to be careful to remove the kpathsea
setting from a file that is going to be called directly from a TeX document, where it will already be set. But for development purposes this setup, if any is needed at all, enables you to get reasonably close to the way a script is going to be interpreted when it is called from within a TeX run.
mongo.lua
do you have such a file? Is it in luatex's search path?