issue on lualatex and mongo

I have an issue with lualatex and mongo

% !config
% arara: lualatex :{shell : yes , synctex : yes}
% arara : tikzmake :{ jobs : 1, force : yes}
\documentclass[12pt,a4paper]{book}
\usepackage{Bibles}
\usepackage{lipsum}
%\usepackage[utf8x]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}
\title{bible accessibilité}
\usepackage{ifluatex}
\usepackage{luatexbase}
\usepackage{luacode}
\begin{document}
\maketitle
\begin{luacode*}
dofile("bible.lua")
\end{luacode*}
\end{document}


my lua code:

mongo = require('mongo')
client = mongo.Client('mongodb://127.0.0.1:27017')
ERP = client:getCollection('bible','Etablissement Recevant du Public (ERP)')
vote = client:getCollection('bible','bureau de vote')
enseignement = client:getCollection('bible',"etablissement enseignement")
logement = client:getCollection('bible','logement')
transport = client:getCollection('bible','transport')
voirie = client:getCollection('bible','voirie')
stationnement = client:getCollection('bible','carte de stationnement')
travail = client:getCollection('bible','lieux de travail')
CCIA  = client:getCollection('bible','commission communale et intercommunale accessibilite')
CCDSA = client:getCollection('bible','COMMISSION CONSULTATIVE DEPARTEMENTALE DE SECURITE ET D’ACCESSIBILITE')
formation_acces = client:getCollection('bible','formation accessibilite')
test1 = client:getCollection('bible','test')
function essais()
local q = mongo.BSON{_id=9}
local r = test1:findOne(q):value()
print("nom du domaine",r.domaine)
end


and the issue

 module 'mongo' not found:
stack traceback:
[C]: in function 'require'
./bible.lua:1: in main chunk
[C]: in function 'require'
[\directlua]:1: in main chunk.
\luacode@dbg@exec ...code@maybe@printdbg {#1} #1 }


regard

• it can't find a file mongo.lua do you have such a file? Is it in luatex's search path? – David Carlisle Feb 28 at 16:13
• hello mongo is a lua module which I have on an other directory – Dylan Paddeu Feb 28 at 16:18
• Is the "other directory" a place where lualatex can find it? – Ulrike Fischer Feb 28 at 16:19
• but if it is just somewhere on your machine and not in the luatex input path then of course luatex can not find it. It doesn't search your entire filesystem looking for files. – David Carlisle Feb 28 at 16:19
• I'm using texmaker on macos. Do I need to configure texmaker in other to find lua module – Dylan Paddeu Feb 28 at 16:22

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.