Ich versuche, von LuaLaTeX aus auf SQLite-Datenbanken zuzugreifen, kann aber ein installiertes lsqlite3
Paket nicht laden. Folgendes habe ich bisher versucht:
- Habe eine brandneue Xubuntu 14.04 Installation durchgeführt
- Installiert ein komplettes TeX Live 2014
- Luarocks installiert (wobei Lua5.1 nebenbei installiert wurde)
Verwendet Luarocks zu installieren
lsqlite3
uwe@luabuntu:/media/uwe$ Luarocks-Liste
Installierte Steine:
lsqlite3 0.9.1-2 (installiert) – /usr/local/lib/luarocks/rocks
Angehängt
package.path
an die folgende TeX-Datei:\documentclass{article} \usepackage{luacode} \begin{document} \begin{luacode*} package.path="/usr/local/lib/luarocks/rocks;/usr/local/lib/luarocks/rocks/lsqlite3; /usr/local/lib/lua/5.1/lsqlite3.so" .. package.path require("lsqlite3") \end{luacode*} Hello Lua! \end{document}
Ich erhalte die folgende Fehlermeldung:
! LuaTeX error [\directlua]:3: module 'lsqlite3' not found: no field package.preload['lsqlite3'] [luatexbase.loader] Search failed [kpse lua searcher] file not found: 'lsqlite3' [kpse C searcher] file not found: 'lsqlite3' [oberdiek.luatex.kpse_module_loader]-eroux Search failed stack traceback: [C]: in function 'require' [\directlua]:3: in main chunk. \luacode@dbg@exec ...code@maybe@printdbg {#1} #1 } l.9 \end{luacode*}
Was muss eingestellt werden, damit LuaLaTeX das lsqlite3
Paket findet?
BEARBEITEN
Ich habe versucht, alles gemäß den folgenden Kommentaren anzupassen:
- Angepasst
/usr/local/texlive/2014/texmf.cnf
- Setzen Sie alles in das Beispiel ein
lsqlite3
Bei folgendem Beispiel erhalte ich immer noch die Fehlermeldung über das fehlende Modul\documentclass{article} \directlua{ require "lualoader" } \usepackage{fontspec} \usepackage[english]{babel} \begin{document} \directlua{package.path='/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/home/uwe/.luarocks/share/lua/5.1/?.lua;/home/uwe/.luarocks/share/lua/5.1/?/init.lua;/usr/share/lua/5.1//?.lua;/usr/share/lua/5.1//?/init.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua' package.cpath='/usr/local/lib/lua/5.1/?.so;/home/uwe/.luarocks/lib/lua/5.1/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/lib/x86_64-linux-gnu/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so' require "lualoader" } \directlua{% local sqlite3 = require("lsqlite3") local db = sqlite3.open_memory() db:exec[[ CREATE TABLE test (id INTEGER PRIMARY KEY, content); INSERT INTO test VALUES (NULL, 'Hello World'); INSERT INTO test VALUES (NULL, 'Hello Lua'); INSERT INTO test VALUES (NULL, 'Hello Sqlite3') ]] for row in db:nrows("SELECT * FROM test") do tex.print(row.id .. " : ".. row.content ) end } \end{document}
Antwort1
Es ist möglich, den Mechanismus zum Laden von Paketen in zu ändern Lua
. Im Fall von wird LuaTeX
die kpse
Bibliothek zum Laden von Modulen verwendet, statt des Standardmechanismus, der package.path
und verwendet package.cpath
. Das Setzen dieser Variablen hat also keine Auswirkungen. Aber nichts hindert uns daran, beide Methoden mit einem Lua
Modul zu verwenden, lualoader.lua
. Speichern Sie den folgenden Codeausschnitt als Datei im Verzeichnis, das Ihr Dokument enthält:
-- lualoader.lua
-- this is copied from luatexbase.loader
local make_loader = function(path, pos, loadfunc)
local default_loader = package.searchers[pos]
local loader = function(name)
local file, _ = package.searchpath(name,path)
if not file then
local msg = "\n\t[lualoader] Search failed"
local ret = default_loader(name)
if type(ret) == "string" then
return msg ..ret
elseif type(ret) == "nil" then
return msg
else
return ret
end
end
local loader,err = loadfunc(file, name)
if not loader then
return "\n\t[lualoader] Loading error:\n\t"..err
end
return loader
end
package.searchers[pos] = loader
end
local binary_loader = function(file, name)
local symbol = name:gsub("%.","_")
return package.loadlib(file, "luaopen_"..symbol)
end
make_loader(package.path,2,loadfile)
make_loader(package.cpath,3, binary_loader)
Wir verwenden die Funktion, make_loader
um eine Suchfunktion package.path
oder eine Funktion package.cpath
an einem bestimmten Index in der package.searchers
Tabelle einzufügen. 2
Für Lua-Dateien, 3
für Binärmodule. Wir müssen auch je nach Typ unterschiedliche Funktionen verwenden, um ein Modul zu laden. Wir verwenden loadfile
für Lua
Dateien eine etwas kompliziertere Funktion für Binärmodule, die verwendet package.loadlib
.
Als Beispiel können wir versuchen, lsqlite3
von folgendem Standort zu laden LuaTeX
:
\documentclass{article}
\directlua{
require "lualoader"
}
\usepackage{fontspec}
\usepackage[english]{babel}
\begin{document}
\directlua{%
local sqlite3 = require("lsqlite3")
local db = sqlite3.open_memory()
db:exec[[
CREATE TABLE test (id INTEGER PRIMARY KEY, content);
INSERT INTO test VALUES (NULL, 'Hello World');
INSERT INTO test VALUES (NULL, 'Hello Lua');
INSERT INTO test VALUES (NULL, 'Hello Sqlite3')
]]
for row in db:nrows("SELECT * FROM test") do
tex.print(row.id .. " : ".. row.content )
end
}
\end{document}
Es ist wichtig, LuaLaTeX mit diesem Flag auszuführen --shell-escape
, da Binärbibliotheken standardmäßig blockiert sind. Mit --shell-escape
können Sie externe Programme ausführen und Binärbibliotheken aufrufen.
Das Beispiel ergibt:
Bearbeiten:
AlsUwedarauf hingewiesen, luarocks
dass die Installation durch einige Linux-Paketmanager möglicherweise nicht richtig funktioniert. Ich habe dies unter Fedora erlebt, also habe ich es luarocks
aus der Quelle installiert. Eine andere Lösung könnte darin bestehen, die durch den Befehl aufgelisteten Verzeichnisse package.path
und festzulegen.package.cpath
luarocks path
Auf meinem eigenen System ergibt dies:
$ luarocks path
export LUA_PATH='/home/michal/.luarocks/share/lua/5.2/?.lua;/home/michal/.luarocks/share/lua/5.2/?/init.lua;/usr/local/share/lua/5.2/?.lua;/usr/local/share/lua/5.2/?/init.lua;/usr/share/lua/5.2/?.lua;/usr/share/lua/5.2/?/init.lua;/usr/lib/lua/5.2/?.lua;/usr/lib/lua/5.2/?/init.lua;./?.lua'
export LUA_CPATH='/home/michal/.luarocks/lib/lua/5.2/?.so;/usr/local/lib/lua/5.2/?.so;/usr/lib/lua/5.2/?.so;/usr/lib/lua/5.2/loadall.so;./?.so'
Eine modifizierte Präambel wäre also:
\directlua{
package.cpath = '/home/michal/.luarocks/lib/lua/5.2/?.so;/usr/local/lib/lua/5.2/?.so;/usr/lib/lua/5.2/?.so;/usr/lib/lua/5.2/loadall.so;./?.so'
package.path = '/home/michal/.luarocks/share/lua/5.2/?.lua;/home/michal/.luarocks/share/lua/5.2/?/init.lua;/usr/local/share/lua/5.2/?.lua;/usr/local/share/lua/5.2/?/init.lua;/usr/share/lua/5.2/?.lua;/usr/share/lua/5.2/?/init.lua;/usr/lib/lua/5.2/?.lua;/usr/lib/lua/5.2/?/init.lua;./?.lua'
require "lualoader"
}
Antwort2
Seit Mai 2017 gibt es auf CTAN ein Paket namensluapaketlader, mit dem Sie das Standardsuchverhalten für Pakete in LuaTeX ändern können.
Sobald Sie geladen haben luapackageloader
, require
wird bei der Ausführung von zuerst der standardmäßige kpse-basierte Sucher ausprobiert. Wenn das Modul nicht gefunden wird, wird auch versucht, das Paket aus Luas package.path
und package.cpath
Werten zu laden.
Anwendungsbeispiel
\documentclass{article}
\usepackage{luacode}
\usepackage{luapackageloader}
\begin{document}
\begin{luacode*}
package.path="/usr/local/lib/luarocks/rocks;/usr/local/lib/luarocks/rocks/lsqlite3;
/usr/local/lib/lua/5.1/lsqlite3.so" .. package.path
require("lsqlite3")
\end{luacode*}
Hello Lua!
\end{document}
Zusätzliche Anmerkung: Sie können eval $(luarocks path)
den Paketpfad in Ihrer Shell mithilfe von Umgebungsvariablen festlegen, die der Lua-Interpreter automatisch erkennt. Auf diese Weise müssen Sie nicht package.path
selbst daran herumfummeln.
Antwort3
Basierend auf Kommentaren zudiese Frage, ich habe die folgende Zeile in /usr/local/texlive/2014/texmf.cnf
:
CLUAINPUTS = .;$SELFAUTOLOC/lib/{$progname,$engine,}/lua//;/usr/lib/{$progname,$engine,}/lua//
Aber mein luarocks list
gibt:
Installed rocks:
lsqlite3
0.9.1-2 (installed) - /usr/lib/luarocks/rocks-5.2
Daher müssen Sie den zweiten Pfad möglicherweise entsprechend Ihrer Installation anpassen.
Antwort4
Zusammenfassung
Suche nach dem Paket
Im normalen Lua wird ein Paket in
package.path
und gesuchtpackage.cpath
.In LuaTeX wird ein Paket standardmäßig mit kpse gesucht.
Es gibt zwei Möglichkeiten, zu ändern, wo LuaTeX nach Paketen sucht
Verhalten von kpse ändern
texmf.cnf
Datei, VariablenLUAINPUTS
usw. ändernCLUAINPUTS
.Lassen Sie Lua von laden
package.(c)path
und ändern Sie dann dieseMit
\usepackage{luapackageloader}
werden Pakete sowohl in kpse als auch in gesuchtpackage.(c)path
.Der Wert
package.(c)path
kann vom Benutzer manuell im Lua-Code selbst festgelegt werden.Es ist besser, Umgebungsvariablen festzulegenz.BLUA_PATH
,LUA_CPATH
.Wenn Sie
eval $(luarocks path)
in Bash ausführen, erben alle von dieser Bash-Shell gestarteten Prozesse die Umgebungsvariablen.
Binärpaket
- Wenn das Paket erfordertBinärdateien,
--shell-escape
muss bestanden werden.
Versionierung
Die Paketversionmuss mit der Lua-Version kompatibel sein. Führen Sie
print(_VERSION)
die Überprüfung in Lua durch.Um für Luarocks eine bestimmte Version anzugeben, geben Sie beispielsweise ein
luarocks --lua-version 5.3 path
: