diff options
Diffstat (limited to 'luatexbase-loader.dtx')
-rw-r--r-- | luatexbase-loader.dtx | 167 |
1 files changed, 153 insertions, 14 deletions
diff --git a/luatexbase-loader.dtx b/luatexbase-loader.dtx index 695efe6..0a3945f 100644 --- a/luatexbase-loader.dtx +++ b/luatexbase-loader.dtx @@ -67,6 +67,9 @@ See source file '\inFileName' for details. \generate{% \usedir{tex/luatex/luatexbase}% \file{luatexbase.loader.lua}{\from{luatexbase-loader.dtx}{luamodule}}% + \usedir{doc/luatex/luatexbase}% + \file{test-loader.lua}{\from{luatexbase-loader.dtx}{testdummy}}% + \file{test-loader.sub.lua}{\from{luatexbase-loader.dtx}{testdummy}}% } \obeyspaces @@ -122,10 +125,45 @@ See source file '\inFileName' for details. % \maketitle % % \begin{abstract} +% Lua modules are loaded using the |require()| function which, similarly to +% \tex's |\input|, takes care of locating the file and load it, but also makes +% a few supplementary checks, for example to avoid loading the same module +% twice. This package adapts the way the files are searched in order to +% accommodate the TDS as well as usual Lua naming conventions. +% +% For higher-level functions related to Lua modules, see +% \href{file:luatexbase-modutils.pdf}{\pk{luatexbase-modutils}}, which also +% loads the present package. % \end{abstract} % % \section{Documentation} % +% Starting with \luatex 0.45.0, |require()| uses Kpathsea for file searching +% when the library is initialised (which is always the case in \tex mode, +% unless explicitly disabled by the user). However, it does not respect the +% Lua convention that |require("foo.bar")| should look for |foo/bar.lua|. +% \footnote{Support for that has been added in rev 3558 of \luatex, currently +% unreleased but probably part of \luatex 0.54.} This package implements such +% behaviour. +% +% More precisely, it implements a new kpse searcher that looks for file +% |foo/bar| using Kpathsea with the format |lua| (that is, search along +% |LUAINPUTS| and try the following extensions: |.luc|, |.luctex|, |.texluc|, +% |.lua|, |.luatex|, |.texlua|). If this search fails, it falls back to +% |foo.bar|. +% +% Also, older versions of \luatex, such as 0.25.4 (\texlive 2008), don't know +% about the |lua| format for kpse searching. So, an emulator for this function +% is provided. The emulator is not perfect, in particular it may find more +% results than the normal |lua| format search. In order to ensure more +% homogeneous results across versions, this emulator is used as a fall-back +% when the real |lua| format search doesn't find any result. +% +% Finally, a combined version of this new kpse searcher and the original +% function at |package.loaders[2]| (using first the new loader, then the old +% one if the new doesn't return any result) is installed as +% |package.loaders[2]|. +% % \section{Implementation} % % \subsection{\tex package} @@ -190,7 +228,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase-loader}[2010/03/26 v0.1 Lua module loader for LuaTeX (mpg)] +\x{luatexbase-loader}[2010/03/26 v0.1 Lua module loader for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -219,10 +257,23 @@ See source file '\inFileName' for details. % % \subsubsection{Main content} % -% Load the supporting Lua module. +% First load \pk{luatexbase-compat}. +% +% \begin{macrocode} +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname RequirePackage\endcsname\relax + \input luatexbase-compat.sty +\else + \RequirePackage{luatexbase-compat} +\fi +% \end{macrocode} +% +% Load the supporting Lua module. This one doesn't follow the usual naming +% conventions, since it won't be loaded with the usual functions for +% obvious bootstraping reasons. % % \begin{macrocode} -\directlua{% +\luatexbase@directlua{% local file = "luatexbase.loader.lua" local path = assert(kpse.find_file(file, 'tex'), "File '"..file.."' no found") @@ -241,42 +292,130 @@ See source file '\inFileName' for details. % % \begin{macrocode} %<*luamodule> -module('luatextra', package.seeall) +module('luatexbase', package.seeall) +% \end{macrocode} +% +% Emulate (approximatively) kpse's lua format search. +% +% |lua_search_suffixes| is taken verbatim from Kpathsea's source +% (\file{tex-file.c}, constant |LUA_SUFFIXES|),\footnote{Unchanged since +% 2007-07-06, last checked 2010-05-10.} except for the addition of the +% empty string at the beginning (since this is what kpse does: first try +% without adding a suffix). +% +% There is a problem with using the |tex| search format: kpse will try to +% add suffixes from the |TEX_SUFFIXES| constant, which leads to problems +% when a file \meta{name}|.tex| exists. We prevent that by checking the +% extension of the file found. +% +% \begin{macrocode} +local lua_search_suffixes = { + "", ".luc", ".luctex", ".texluc", ".lua", ".luatex", ".texlua", + } +local lua_valid_suffixes = { + luc = true, + lua = true, + luctex = true, + texluc = true, + luatex = true, + texlua = true, +} +local function find_file_lua_emul(name) + for _, suf in ipairs(lua_search_suffixes) do + local name = name..suf + local f = kpse.find_file(name, 'texmfscripts') + or kpse.find_file(name, 'tex') + if suf == "" and f then + local ext = string.match(f,"^.+%.([^/\\]-)$") + if lua_valid_suffixes[suf] then + return f + end + elseif f then + return f + end + end +end +% \end{macrocode} +% +% If lua search format is available, use it with emulation as a fall-back, +% or just use emulation. +% +% \begin{macrocode} +local find_file_lua +if pcall('kpse.find_file', 'dummy', 'lua') then + find_file_lua = function (name) + return kpse.find_file(name, 'lua') or find_file_lua_emul(name) + end +else + find_file_lua = function (name) + return find_file_lua_emul(name) + end +end +% \end{macrocode} +% +% Find the full path corresponding to a module name. +% +% \begin{macrocode} +local function find_module_file(mod) + return find_file_lua(mod:gsub('%.', '/'), 'lua') + or find_file_lua(mod, 'lua') +end % \end{macrocode} % +% Combined searcher, using primarily the new kpse searcher, and the +% original as a fall-back. +% % \begin{macrocode} +local package_loader_two = package.loaders[2] local function load_module(mod) - local file = kpse.find_file(mod, 'lua') + local file = find_module_file(mod) if not file then - return "\n\t[luatextra.loader] Search failed" + local msg = "\n\t[luatexbase.loader] Search failed" + local ret = package_loader_two(mod) + if type(ret) == 'string' then + return msg..ret + elseif type(ret) == 'nil' then + return msg + else + return ret + end end local loader, error = loadfile(file) if not loader then - return "\n\t[luatextra.loader] Loading error:\n\t"..error + return "\n\t[luatexbase.loader] Loading error:\n\t"..error end texio.write_nl("("..file..")") return loader end % \end{macrocode} % +% Finally install this combined loader as loader 2. +% % \begin{macrocode} -table.insert(package.loaders, load_module) +package.loaders[2] = load_module %</luamodule> % \end{macrocode} % % \section{Test files} % -% We just check that the package loads properly, under both LaTeX and Plain -% TeX. Anyway, the test files of other modules using this one already are a -% test\dots +% A dummy lua file for tests. % % \begin{macrocode} -%<testplain>\input luatexbase-loader.sty -%<testlatex>\RequirePackage{luatexbase-loader} -%<*testplain,testlatex> +%<*testdummy> +return true +%</testdummy> % \end{macrocode} % +% Check that the package loads properly, under both LaTeX and Plain TeX, +% and load a dummy module in the current diretory. +% % \begin{macrocode} +%<testplain>\input luatexbase-loader.sty +%<testlatex>\RequirePackage{luatexbase-loader} +%<*testplain,testlatex> +\catcode64 11 +\luatexbase@directlua{require "test-loader"} +\luatexbase@directlua{require "test-loader.sub"} %</testplain,testlatex> %<testplain>\bye %<testlatex>\stop |