[latex3-commits] [git/LaTeX3-latex3-latex3] main: Update `\lua_load_module:n` (72a8eac8d)

Max Chernoff 49086429+gucci-on-fleek at github.github.io
Sun May 15 06:10:31 CEST 2022


Repository : https://github.com/latex3/latex3
On branch  : main
Link       : https://github.com/latex3/latex3/commit/72a8eac8d3f5cea7f5562c485a65a43ad7e36bb1

>---------------------------------------------------------------

commit 72a8eac8d3f5cea7f5562c485a65a43ad7e36bb1
Author: Max Chernoff <49086429+gucci-on-fleek at users.noreply.github.com>
Date:   Sat May 14 20:51:53 2022 -0600

    Update `\lua_load_module:n`
    
    We now use a Lua search instead of a TeX search for the module.
    
    See #1091


>---------------------------------------------------------------

72a8eac8d3f5cea7f5562c485a65a43ad7e36bb1
 l3kernel/l3luatex.dtx | 124 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 94 insertions(+), 30 deletions(-)

diff --git a/l3kernel/l3luatex.dtx b/l3kernel/l3luatex.dtx
index 40e0ae009..1d1eb218c 100644
--- a/l3kernel/l3luatex.dtx
+++ b/l3kernel/l3luatex.dtx
@@ -115,7 +115,7 @@
 %   \end{texnote}
 % \end{function}
 %
-% \begin{function}[added = 2022-05-07]{\lua_load_module:n}
+% \begin{function}[added = 2022-05-14]{\lua_load_module:n}
 %   \begin{syntax}
 %     \cs{lua_load_module:n} \Arg{Lua module name}
 %   \end{syntax}
@@ -129,8 +129,7 @@
 %   Instead, it is strongly recommended that they write the majorty of their Lua
 %   code in a separate file, and then load it using \cs{lua_load_module:n}.
 %   \begin{texnote}
-%     This is a wrapper around the Lua call
-%     \texttt{require~\string"\meta{module}\string"}.
+%     This is a wrapper around the Lua call |require '|\meta{module}|'|.
 %   \end{texnote}
 % \end{function}
 %
@@ -188,6 +187,14 @@
 %   found, nothing is returned with \emph{no error raised}.
 % \end{function}
 %
+% \begin{function}[added = 2022-05-14]{ltx.utils.require}
+%   \begin{syntax}
+%     |err_msg = ltx.utils.require(|\meta{module name}|)| \\
+%   \end{syntax}
+%   Loads a Lua module, returining |nil| on success and an error message
+%   on failure.
+% \end{function}
+%
 % \end{documentation}
 %
 % \begin{implementation}
@@ -242,21 +249,18 @@
 % \end{macro}
 %
 % \begin{macro}{\lua_load_module:n}
-%   Wrapper around the Lua call \texttt{require~\string"\meta{module}\string"},
-%   with a friendlier error message when the module cannot be found.
+%   Wrapper around |ltx.utils.require'|\meta{module}|'|.
 %    \begin{macrocode}
+\cs_generate_variant:Nn \bool_if:nF { e }
+\cs_generate_variant:Nn \msg_error:nnnn { nnnV }
 \cs_new_protected:Npn \lua_load_module:n #1
   {
-    \file_if_exist:nTF { #1 .lua }
+    \bool_if:eF { \@@_load_module_p:n { #1 } }
       {
-        \@@_now:n { require "\@@_escape:n { #1 }" }
-      }
-      {
-        \msg_error:nnn
-          { luatex } { module-not-found } { #1 }
+        \msg_error:nnnV
+          { luatex } { module-not-found } { #1 } { \g_@@_err_msg_str }
       }
   }
-
 %    \end{macrocode}
 % \end{macro}
 %
@@ -302,10 +306,11 @@
 \msg_new:nnnn { luatex } { module-not-found }
   { Lua~module~`#1'~not~found. }
   {
-    The~file~`#1.lua'~could~not~be~found~in~the~current~
-    directory~or~in~the~TeX~search~path.~Please~ensure~that~
-    the~file~was~properly~installed~and~that~the~filename~
-    database~is~current.
+    The~file~`#1.lua'~could~not~be~found.~Please~ensure~
+    that~the~file~was~properly~installed~and~that~the~
+    filename~database~is~current. \\ \\
+    The~Lua~loader~provided~this~additional~information: \\
+    #2
   }
 
 \prop_gput:Nnn \g_msg_module_name_prop { luatex } { LaTeX3 }
@@ -350,20 +355,23 @@ local tonumber = tonumber
 %
 %   Local copies of standard functions.
 %    \begin{macrocode}
-local abs        = math.abs
-local byte       = string.byte
-local floor      = math.floor
-local format     = string.format
-local gsub       = string.gsub
-local lfs_attr   = lfs.attributes
-local open       = io.open
-local os_date    = os.date
-local setcatcode = tex.setcatcode
-local sprint     = tex.sprint
-local cprint     = tex.cprint
-local write      = tex.write
-local write_nl   = texio.write_nl
-local utf8_char  = utf8.char
+local abs               = math.abs
+local byte              = string.byte
+local floor             = math.floor
+local format            = string.format
+local gsub              = string.gsub
+local lfs_attr          = lfs.attributes
+local open              = io.open
+local os_date           = os.date
+local setcatcode        = tex.setcatcode
+local sprint            = tex.sprint
+local cprint            = tex.cprint
+local write             = tex.write
+local write_nl          = texio.write_nl
+local utf8_char         = utf8.char
+local package_loaded    = package.loaded
+local package_searchers = package.searchers
+local table_concat      = table.concat
 
 local scan_int     = token.scan_int or token.scan_integer
 local scan_string  = token.scan_string
@@ -371,6 +379,7 @@ local scan_keyword = token.scan_keyword
 local put_next     = token.put_next
 local token_create = token.create
 local token_new    = token.new
+local set_macro    = token.set_macro
 %    \end{macrocode}
 %
 %   Since token.create only returns useful values after the tokens
@@ -607,6 +616,61 @@ end
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{ltx.utils.require}
+%   Loads a Lua module. This function loads the module just like the standard
+%   Lua global function |require|, with two key differences:
+%   \begin{enumerate}
+%     \item This function is guaranteed not to throw an error.
+%     \item This function does \emph{not} return the loaded module; instead, it
+%           returns |nil| on success and an error message on failure.
+%   \end{enumerate}
+%    \begin{macrocode}
+local function require(name)
+  if package_loaded[name] then
+    return
+  end
+
+  local failure_details = {}
+  for _, searcher in ipairs(package_searchers) do
+    local loader, data = searcher(name)
+    if type(loader) == 'function' then
+      package_loaded[name] = loader(name, data) or true
+      return
+    elseif type(loader) == 'string' then
+      failure_details[#failure_details + 1] = loader
+    end
+  end
+
+  return table_concat(failure_details, '\n')
+end
+
+ltx.utils.require = require
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_load_module_p:n}
+%   Check to see if we can load a module using |ltx.utils.require|. If we can
+%   load the module, then we load it immediately. Otherwise, we save the error
+%   message in |\g_@@_err_msg_str|.
+%    \begin{macrocode}
+local char_given   = command_id'char_given'
+local c_true_bool  = token_create(1, char_given)
+local c_false_bool = token_create(0, char_given)
+local c_str_cctab  = token_create('c_str_cctab').mode
+
+luacmd('@@_load_module_p:n', function()
+  local result = require(scan_string())
+  if result == nil then
+    set_macro(c_str_cctab, 'g_@@_err_msg_str', '', 'global')
+    put_next(c_true_bool)
+  else
+    set_macro(c_str_cctab, 'g_@@_err_msg_str', result, 'global')
+    put_next(c_false_bool)
+  end
+end)
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsection{Preserving iniTeX Lua data for runs}
 %
 %    \begin{macrocode}





More information about the latex3-commits mailing list.