% \iffalse meta-comment % % Copyright 2009-2013 by Élie Roux % Copyright 2010, 2011 by Manuel Pégourié-Gonnard % % This work is under the CC0 license. % % This work consists of the main source file luatexbase-loader.dtx % and the derived files % luatexbase-loader.sty luatexbase.loader.lua % test-loader-plain.tex test-loader-latex.tex % % Unpacking: % tex luatexbase-loader.dtx % Documentation: % pdflatex luatexbase-loader.dtx % %<*ignore> \begingroup \def\x{LaTeX2e}% \expandafter\endgroup \ifcase 0\ifx\install y1\fi\expandafter \ifx\csname processbatchFile\endcsname\relax\else1\fi \ifx\fmtname\x\else 1\fi\relax \else\csname fi\endcsname % %<*install> \input docstrip.tex \keepsilent \askforoverwritefalse \let\MetaPrefix\relax \preamble See the aforementioned source file(s) for copyright and licensing information. \endpreamble \let\MetaPrefix\DoubleperCent \generate{% \usedir{tex/luatex/luatexbase}% \file{luatexbase-loader.sty}{\from{luatexbase-loader.dtx}{texpackage}}% } \generate{% \usedir{doc/luatex/luatexbase}% \file{test-loader-plain.tex}{\from{luatexbase-loader.dtx}{testplain}}% \file{test-loader-latex.tex}{\from{luatexbase-loader.dtx}{testlatex}}% } \def\MetaPrefix{-- } \def\luapostamble{% \MetaPrefix^^J% \MetaPrefix\space End of File `\outFileName'.% } \def\currentpostamble{\luapostamble}% \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 \Msg{************************************************************************} \Msg{*} \Msg{* To finish the installation you have to move the following} \Msg{* files into a directory searched by TeX:} \Msg{*} \Msg{* luatexbase-loader.sty luatex.loader.lua} \Msg{*} \Msg{* Happy TeXing!} \Msg{*} \Msg{************************************************************************} \endbatchfile % %<*ignore> \fi % %<*driver> \documentclass{ltxdoc} \input{lltxb-dtxstyle} \begin{document} \DocInput{luatexbase-loader.dtx}% \end{document} % % \fi % % \CheckSum{0} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % \pkdate{luatexbase-loader}{v0.6 2013-05-11} % % \maketitle % % \begin{abstract} % Lua modules are loaded using the |require()| function which, similarly to % \tex's |\input|, takes care of locating the file to be loaded. 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, |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 did not respect the % Lua convention that |require("foo.bar")| should look for |foo/bar.lua| until % version 0.60. \luatex 0.74 ships with Lua 5.2 that has a different loading % system. % % The aim of this package is to have a coherent behaviour between versions of % LuaTeX, and to get the loaded file's name printed in the output (\LaTeX % style). The first versions did ensure backward compatibilty to \luatex 0.25 % but as \luatex development is quite fast, this version supports only \luatex % 0.45 and higher. % % More precisely, when asked for |foo.bar| (or |foo.bar.lua|), it first looks % for file |foo/bar| using Kpathsea with the format |lua|, and then for % |foo.bar|, removing the possible extension. % % \section{Implementation} % % \subsection{\tex package} % % \begin{macrocode} %<*texpackage> % \end{macrocode} % % \subsubsection{Preliminaries} % % Catcode defenses and reload protection. % % \begin{macrocode} \begingroup\catcode61\catcode48\catcode32=10\relax% = and space \catcode123 1 % { \catcode125 2 % } \catcode 35 6 % # \toks0\expandafter{\expandafter\endlinechar\the\endlinechar}% \edef\x{\endlinechar13}% \def\y#1 #2 {% \toks0\expandafter{\the\toks0 \catcode#1 \the\catcode#1}% \edef\x{\x \catcode#1 #2}}% \y 13 5 % carriage return \y 61 12 % = \y 32 10 % space \y 123 1 % { \y 125 2 % } \y 35 6 % # \y 64 11 % @ (letter) \y 10 12 % new line ^^J \y 34 12 % " \y 39 12 % ' \y 40 12 % ( \y 41 12 % ) \y 44 12 % , \y 45 12 % - \y 46 12 % . \y 47 12 % / \y 58 12 % : \y 91 12 % [ \y 93 12 % ] \y 94 7 % ^ \y 95 8 % _ \y 96 12 % ` \toks0\expandafter{\the\toks0 \relax\noexpand\endinput}% \edef\y#1{\noexpand\expandafter\endgroup% \noexpand\ifx#1\relax \edef#1{\the\toks0}\x\relax% \noexpand\else \noexpand\expandafter\noexpand\endinput% \noexpand\fi}% \expandafter\y\csname luatexbase@loader@sty@endinput\endcsname% % \end{macrocode} % % Package declaration. % % \begin{macrocode} \begingroup \expandafter\ifx\csname ProvidesPackage\endcsname\relax \def\x#1[#2]{\immediate\write16{Package: #1 #2}} \else \let\x\ProvidesPackage \fi \expandafter\endgroup \x{luatexbase-loader}[2013/05/11 v0.6 Lua module loader for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. % % \begin{macrocode} \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname RequirePackage\endcsname\relax \input ifluatex.sty \else \RequirePackage{ifluatex} \fi \ifluatex\else \begingroup \expandafter\ifx\csname PackageError\endcsname\relax \def\x#1#2#3{\begingroup \newlinechar10 \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else \let\x\PackageError \fi \expandafter\endgroup \x{luatexbase-loader}{LuaTeX is required for this package. Aborting.}{% This package can only be used with the LuaTeX engine^^J% (command `lualatex' or `luatex').^^J% Package loading has been stopped to prevent additional errors.} \expandafter\luatexbase@loader@sty@endinput% \fi % \end{macrocode} % % \subsubsection{Main content} % % 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} \luatexbase@directlua{% local file = "luatexbase.loader.lua" local path = assert(kpse.find_file(file, 'lua'), "File '"..file.."' not found") texio.write_nl("("..path..")") dofile(path)} % \end{macrocode} % % That's all, folks! % % \begin{macrocode} \luatexbase@loader@sty@endinput% % % \end{macrocode} % % \subsection{Lua module} % % \begin{macrocode} %<*luamodule> luatexbase = luatexbase or { } local luatexbase = luatexbase % \end{macrocode} % % Just in case it's called from a \TeX Lua script... % % \begin{macrocode} kpse.set_program_name("luatex") % \end{macrocode} % % In \LaTeX, it's traditional to print the included file paths. We don't want % to do this for scripts using texlua... Currently there is no perfect check % of texlua vs. luatex, so we check for the token table. % % \begin{macrocode} local print_included_path = false if token then print_included_path = true end % \end{macrocode} % % Emulate (approximatively) kpse's lua format search. More precisely, % combine the search path of |texmfscripts| and |tex| in order to % approximate |LUAINPUTS|. But we need to handle suffixes ourselves. % % |lua_suffixes| is taken verbatim from Kpathsea's source % (\file{tex-file.c}, constant |LUA_SUFFIXES|).\footnote{Last checked 2013-04-12.} % % \begin{macrocode} local lua_suffixes = { ".luc", ".luctex", ".texluc", ".lua", ".luatex", ".texlua", } % \end{macrocode} % % Auxiliary function for suffixes: says if |suffix| is a suffix of |name|. % % \begin{macrocode} local function ends_with(suffix, name) return name:sub(-suffix:len()) == suffix end % \end{macrocode} % % Auxiliary function for suffixes: returns the basename of a file if it end % by one of the suffixes. % % \begin{macrocode} local function basename(name) for _, suffix in ipairs(lua_suffixes) do if ends_with(suffix, name) then return name:sub(1, -(suffix:len()+1)) end end return name end % \end{macrocode} % % The main function, emulating the behaviour of |packages.searchers[2]|, % with a small improvement that eliminates the possible extension. % % \begin{macrocode} local function find_module_file(mod) local compat = basename(mod):gsub('%.', '/') return kpse.find_file(compat, 'lua') or kpse.find_file(mod, 'lua') end % \end{macrocode} % % Combined searcher, using primarily the new kpse searcher, and the % original as a fall-back. Starting from \luatex 0.75, Lua 5.2 is used. Among % the changes, |package.loaders| is renamed as |package.searchers|. % % The main improvement is thus the printing of the filename in the output. % % \begin{macrocode} local package_loader_two if not package.searchers then package.searchers = package.loaders end package_loader_two = package.searchers[2] local function load_module(mod) local file = find_module_file(mod) if not file then 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[luatexbase.loader] Loading error:\n\t"..error end if print_included_path then texio.write_nl("("..file..")") end return loader end % \end{macrocode} % % Finally install this combined loader as loader 2. % % \begin{macrocode} package.searchers[2] = load_module % % \end{macrocode} % % \section{Test files} % % A dummy lua file for tests. % % \begin{macrocode} %<*testdummy> return true % % \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} %\input luatexbase-loader.sty %\RequirePackage{luatexbase-loader} %<*testplain,testlatex> \catcode64 11 \luatexbase@directlua{require "test-loader"} \luatexbase@directlua{require "test-loader.sub"} % %\bye %\stop % \end{macrocode} % % \Finale \endinput