summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/base/ltluatex.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/base/ltluatex.dtx')
-rw-r--r--Master/texmf-dist/source/latex/base/ltluatex.dtx210
1 files changed, 134 insertions, 76 deletions
diff --git a/Master/texmf-dist/source/latex/base/ltluatex.dtx b/Master/texmf-dist/source/latex/base/ltluatex.dtx
index 62d663c8d3f..49e75c856cc 100644
--- a/Master/texmf-dist/source/latex/base/ltluatex.dtx
+++ b/Master/texmf-dist/source/latex/base/ltluatex.dtx
@@ -24,7 +24,7 @@
\ProvidesFile{ltluatex.dtx}
%</driver>
%<*tex>
-[2015/10/03 v1.0f
+[2015/12/18 v1.0l
%</tex>
%<plain> LuaTeX support for plain TeX (core)
%<*tex>
@@ -119,12 +119,12 @@
% \noindent
% \DescribeMacro{\newluabytecode}
% |\newluabytecode{|\meta{bytecode}|}|\\
-% Allocates a number for lua bytecode register, indexed from~$1$.
+% Allocates a number for Lua bytecode register, indexed from~$1$.
%
% \noindent
% \DescribeMacro{\newluachunkname}
% |newluachunkname{|\meta{chunkname}|}|\\
-% Allocates a number for lua chunk register, indexed from~$1$.
+% Allocates a number for Lua chunk register, indexed from~$1$.
% Also enters the name of the regiser (without backslash) into the
% \verb|lua.name| table to be used in stack traces.
%
@@ -149,7 +149,7 @@
% \section{Plain \TeX\ interface}
%
% The \textsf{ltluatex} interface may be used with plain \TeX\ using
-% |\input{ltluatex}| this inputs |ltluatex.tex| which inputs
+% |\input{ltluatex}|. This inputs |ltluatex.tex| which inputs
% |etex.src| (or |etex.sty| if used with \LaTeX)
% if it is not already input, and then defines some internal commands to
% allow the \textsf{ltluatex} interface to be defined.
@@ -179,7 +179,7 @@
% |\attributedef|.
% The attribute name is recorded in the |attributes| table. A
% metatable is provided so that the table syntax can be used
-% consistently for attributes declared in \TeX\ or lua.
+% consistently for attributes declared in \TeX\ or Lua.
%
% \noindent
% \DescribeMacro{new_whatsit}
@@ -195,7 +195,7 @@
% \noindent
% \DescribeMacro{new_chunkname}
% |luatexbase.new_chunkname(|\meta{chunkname}|)|\\
-% Returns an allocation number for a lua chunk name for use with
+% Returns an allocation number for a Lua chunk name for use with
% |\directlua| and |\latelua|, indexed from~$1$.
% The number is returned and also \meta{name} argument is added to the
% |lua.name| array at that index.
@@ -342,7 +342,7 @@
% \DescribeMacro{create_callback}
% |luatexbase.create_callback(|\meta{name},meta{type},\meta{default}|)|
% Defines a user defined callback. The last argument is a default
-% functtion of |false|.
+% function or |false|.
%
% \noindent
% \DescribeMacro{call_callback}
@@ -351,7 +351,7 @@
%
% \endgroup
%
-% \CheckSum{491}
+% \CheckSum{558}
% \StopEventually{}
%
% \section{Implementation}
@@ -362,6 +362,9 @@
% \end{macrocode}
%
%
+% \changes{v1.0j}{2015/12/02}{Remove nonlocal iteration variables (PHG)}
+% \changes{v1.0j}{2015/12/02}{Assorted typos fixed (PHG)}
+% \changes{v1.0j}{2015/12/02}{Remove unreachable code after calls to error() (PHG)}
% \subsection{Minimum Lua\TeX{} version}
%
% Lua\TeX{} has changed a lot over time. In the kernel support for ancient
@@ -417,8 +420,8 @@
% \subsubsection{Fixes to \texttt{etex.src}/\texttt{etex.sty}}
%
% These could and probably should be made directly in an
-% update to etex.src which already has some luatex-specific
-% code, but does not define the correct range for luatex.
+% update to |etex.src| which already has some Lua\TeX-specific
+% code, but does not define the correct range for Lua\TeX.
%
% \begin{macrocode}
% 2015-07-13 higher range in luatex
@@ -570,6 +573,7 @@
% \end{macrocode}
% \end{macro}
%
+% \changes{v1.0l}{2015/12/18}{Load Unicode data from source}
% \begin{macro}{\catcodetable@initex}
% \changes{v1.0a}{2015/09/24}{Macro added}
% \begin{macro}{\catcodetable@string}
@@ -579,9 +583,8 @@
% \begin{macro}{\catcodetable@atletter}
% \changes{v1.0a}{2015/09/24}{Macro added}
% Save a small set of standard tables. The Unicode data is read
-% here in a group avoiding any global definitions: that needs a bit
-% of effort so that in package/plain mode there is no effect on any
-% settings already in force.
+% here in using a parser simplified from that in |load-unicode-data|:
+% only the nature of letters needs to be detected.
% \begin{macrocode}
\newcatcodetable\catcodetable@initex
\newcatcodetable\catcodetable@string
@@ -613,13 +616,49 @@
\newcatcodetable\catcodetable@latex
\newcatcodetable\catcodetable@atletter
\begingroup
- \let\ENDGROUP\endgroup
- \let\begingroup\relax
- \let\endgroup\relax
- \let\global\relax
- \let\gdef\def
- \input{unicode-letters.def}%
- \let\endgroup\ENDGROUP
+ \def\parseunicodedataI#1;#2;#3;#4\relax{%
+ \parseunicodedataII#1;#3;#2 First>\relax
+ }%
+ \def\parseunicodedataII#1;#2;#3 First>#4\relax{%
+ \ifx\relax#4\relax
+ \expandafter\parseunicodedataIII
+ \else
+ \expandafter\parseunicodedataIV
+ \fi
+ {#1}#2\relax%
+ }%
+ \def\parseunicodedataIII#1#2#3\relax{%
+ \ifnum 0%
+ \if L#21\fi
+ \if M#21\fi
+ >0 %
+ \catcode"#1=11 %
+ \fi
+ }%
+ \def\parseunicodedataIV#1#2#3\relax{%
+ \read\unicoderead to \unicodedataline
+ \if L#2%
+ \count0="#1 %
+ \expandafter\parseunicodedataV\unicodedataline\relax
+ \fi
+ }%
+ \def\parseunicodedataV#1;#2\relax{%
+ \loop
+ \unless\ifnum\count0>"#1 %
+ \catcode\count0=11 %
+ \advance\count0 by 1 %
+ \repeat
+ }%
+ \def\storedpar{\par}%
+ \chardef\unicoderead=\numexpr\count16 + 1\relax
+ \openin\unicoderead=UnicodeData.txt %
+ \loop\unless\ifeof\unicoderead %
+ \read\unicoderead to \unicodedataline
+ \unless\ifx\unicodedataline\storedpar
+ \expandafter\parseunicodedataI\unicodedataline\relax
+ \fi
+ \repeat
+ \closein\unicoderead
\@firstofone{%
\catcode64=12 %
\savecatcodetable\catcodetable@latex
@@ -638,8 +677,8 @@
% \begin{macro}{\newluafunction}
% \changes{v1.0a}{2015/09/24}{Macro added}
% Much the same story for allocating Lua\TeX{} functions except here they are
-% just numbers so are allocated in the same way as boxes. Lua index from~$1$
-% so once again slot~$0$ is skipped.
+% just numbers so they are allocated in the same way as boxes.
+% Lua indexes from~$1$ so once again slot~$0$ is skipped.
% \begin{macrocode}
\ifx\e@alloc@luafunction@count\@undefined
\countdef\e@alloc@luafunction@count=260
@@ -802,6 +841,11 @@ local tex_setattribute = tex.setattribute
local tex_setcount = tex.setcount
local texio_write_nl = texio.write_nl
% \end{macrocode}
+% \changes{v1.0i}{2015/11/29}{Declare this as local before used in the module error definitions (PHG)}
+% \begin{macrocode}
+local luatexbase_warning
+local luatexbase_error
+% \end{macrocode}
%
% \subsection{Lua module utilities}
%
@@ -824,15 +868,14 @@ local modules = modules or { }
local function luatexbase_log(text)
texio_write_nl("log", text)
end
-% \begin{macrocode}
+% \end{macrocode}
%
% Modelled on |\ProvidesPackage|, we store much the same information but
% with a little more structure.
% \begin{macrocode}
local function provides_module(info)
if not (info and info.name) then
- luatexbase_error("Missing module name for provides_modules")
- return
+ luatexbase_error("Missing module name for provides_module")
end
local function spaced(text)
return text and (" " .. text) or ""
@@ -859,13 +902,15 @@ luatexbase.provides_module = provides_module
%
% First an auxiliary for the formatting: this measures up the message
% leader so we always get the correct indent.
+% \changes{v1.0j}{2015/12/02}{Declaration/use of first\_head fixed (PHG)}
% \begin{macrocode}
local function msg_format(mod, msg_type, text)
local leader = ""
local cont
+ local first_head
if mod == "LaTeX" then
cont = string_gsub(leader, ".", " ")
- leader = leader .. "LaTeX: "
+ first_head = leader .. "LaTeX: "
else
first_head = leader .. "Module " .. msg_type
cont = "(" .. mod .. ")"
@@ -915,10 +960,10 @@ luatexbase.module_error = module_error
%
% Dedicated versions for the rest of the code here.
% \begin{macrocode}
-local function luatexbase_warning(text)
+function luatexbase_warning(text)
module_warning("luatexbase", text)
end
-local function luatexbase_error(text)
+function luatexbase_error(text)
module_error("luatexbase", text)
end
% \end{macrocode}
@@ -926,8 +971,11 @@ end
%
% \subsection{Accessing register numbers from Lua}
%
+% \changes{v1.0g}{2015/11/14}{Track Lua\TeX{} changes for
+% \texttt{(new)token.create}}
% Collect up the data from the \TeX{} level into a Lua table: from
% version~0.80, Lua\TeX{} makes that easy.
+% \changes{v1.0j}{2015/12/02}{Adjust hashtokens to store the result of tex.hashtokens()), not the function (PHG)}
% \begin{macrocode}
local luaregisterbasetable = { }
local registermap = {
@@ -940,17 +988,18 @@ local registermap = {
skipzero = "assign_skip" ,
tokszero = "assign_toks" ,
}
-local i, j
local createtoken
-if tex.luatexversion >79 then
- createtoken = newtoken.create
+if tex.luatexversion > 81 then
+ createtoken = token.create
+elseif tex.luatexversion > 79 then
+ createtoken = newtoken.create
end
-local hashtokens = tex.hashtokens
+local hashtokens = tex.hashtokens()
local luatexversion = tex.luatexversion
for i,j in pairs (registermap) do
if luatexversion < 80 then
- luaregisterbasetable[hashtokens()[i][1]] =
- hashtokens()[i][2]
+ luaregisterbasetable[hashtokens[i][1]] =
+ hashtokens[i][2]
else
luaregisterbasetable[j] = createtoken(i).mode
end
@@ -967,7 +1016,7 @@ end
local registernumber
if luatexversion < 80 then
function registernumber(name)
- local nt = hashtokens()[name]
+ local nt = hashtokens[name]
if(nt and luaregisterbasetable[nt[1]]) then
return nt[2] - luaregisterbasetable[nt[1]]
else
@@ -1011,7 +1060,6 @@ local function new_attribute(name)
tex_count["e@alloc@attribute@count"] + 1)
if tex_count["e@alloc@attribute@count"] > 65534 then
luatexbase_error("No room for a new \\attribute")
- return -1
end
attributes[name]= tex_count["e@alloc@attribute@count"]
luatexbase_log("Lua-only attribute " .. name .. " = " ..
@@ -1025,14 +1073,13 @@ luatexbase.new_attribute = new_attribute
% \subsection{Custom whatsit allocation}
%
% \begin{macro}{new_whatsit}
-% Much the same as for attribute allocation in Lua
+% Much the same as for attribute allocation in Lua.
% \begin{macrocode}
local function new_whatsit(name)
tex_setcount("global", "e@alloc@whatsit@count",
tex_count["e@alloc@whatsit@count"] + 1)
if tex_count["e@alloc@whatsit@count"] > 65534 then
luatexbase_error("No room for a new custom whatsit")
- return -1
end
luatexbase_log("Custom whatsit " .. (name or "") .. " = " ..
tex_count["e@alloc@whatsit@count"])
@@ -1053,7 +1100,6 @@ local function new_bytecode(name)
tex_count["e@alloc@bytecode@count"] + 1)
if tex_count["e@alloc@bytecode@count"] > 65534 then
luatexbase_error("No room for a new bytecode register")
- return -1
end
luatexbase_log("Lua bytecode " .. (name or "") .. " = " ..
tex_count["e@alloc@bytecode@count"])
@@ -1076,7 +1122,6 @@ local function new_chunkname(name)
chunkname_count = chunkname_count + 1
if chunkname_count > 65534 then
luatexbase_error("No room for a new chunkname")
- return -1
end
lua.name[chunkname_count]=name
luatexbase_log("Lua chunkname " .. (name or "") .. " = " ..
@@ -1089,7 +1134,7 @@ luatexbase.new_chunkname = new_chunkname
%
% \subsection{Lua callback management}
%
-% The native mechanism for callbacks in Lua allows only one per function.
+% The native mechanism for callbacks in Lua\TeX\ allows only one per function.
% That is extremely restrictive and so a mechanism is needed to add and
% remove callbacks from the appropriate hooks.
%
@@ -1233,7 +1278,7 @@ end
%
% The handler function is registered into the callback when the
% first function is added to this callback's list. Then, when the callback
-% is called, then handler takes care of running all functions in the list.
+% is called, the handler takes care of running all functions in the list.
% When the last function is removed from the callback's list, the handler
% is unregistered.
%
@@ -1244,7 +1289,6 @@ end
% \begin{macrocode}
local function data_handler(name)
return function(data, ...)
- local i
for _,i in ipairs(callbacklist[name]) do
data = i.func(data,...)
end
@@ -1263,18 +1307,18 @@ local function exclusive_handler(name)
end
% \end{macrocode}
% Handler for |list| callbacks.
+% \changes{v1.0k}{2015/12/02}{resolve name and i.description (PHG)}
% \begin{macrocode}
local function list_handler(name)
return function(head, ...)
local ret
local alltrue = true
- local i
for _,i in ipairs(callbacklist[name]) do
ret = i.func(head, ...)
if ret == false then
luatexbase_warning(
- "Function `i.description' returned false\n"
- .. "in callback `name'"
+ "Function `" .. i.description .. "' returned false\n"
+ .. "in callback `" .. name .."'"
)
break
end
@@ -1291,7 +1335,6 @@ end
% \begin{macrocode}
local function simple_handler(name)
return function(...)
- local i
for _,i in ipairs(callbacklist[name]) do
i.func(...)
end
@@ -1313,7 +1356,7 @@ local handlers = {
%
% Defining user callbacks perhaps should be in package code,
% but impacts on |add_to_callback|.
-% If a default function is not required, may may be declared as |false|.
+% If a default function is not required, it may be declared as |false|.
% First we need a list of user callbacks.
% \begin{macrocode}
local user_callbacks_defaults = { }
@@ -1321,16 +1364,25 @@ local user_callbacks_defaults = { }
%
% \begin{macro}{create_callback}
% \changes{v1.0a}{2015/09/24}{Function added}
+% \changes{v1.0i}{2015/11/29}{Check name is not nil in error message (PHG)}
+% \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
% The allocator itself.
% \begin{macrocode}
local function create_callback(name, ctype, default)
- if not name or
- name == "" or
- callbacktypes[name] or
- not(default == false or type(default) == "function")
- then
- luatexbase_error("Unable to create callback " .. name)
+ if not name or name == ""
+ or not ctype or ctype == ""
+ then
+ luatexbase_error("Unable to create callback:\n" ..
+ "valid callback name and type required")
+ end
+ if callbacktypes[name] then
+ luatexbase_error("Unable to create callback `" .. name ..
+ "':\ncallback type disallowed as name")
end
+ if default ~= false and type (default) ~= "function" then
+ luatexbase_error("Unable to create callback `" .. name ..
+ ":\ndefault is not a function")
+ end
user_callbacks_defaults[name] = default
callbacktypes[name] = types[ctype]
end
@@ -1340,15 +1392,19 @@ luatexbase.create_callback = create_callback
%
% \begin{macro}{call_callback}
% \changes{v1.0a}{2015/09/24}{Function added}
+% \changes{v1.0i}{2015/11/29}{Check name is not nil in error message (PHG)}
+% \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
% Call a user defined callback. First check arguments.
% \begin{macrocode}
local function call_callback(name,...)
- if not name or
- name == "" or
- user_callbacks_defaults[name] == nil
- then
- luatexbase_error("Unable to call callback " .. name)
+ if not name or name == "" then
+ luatexbase_error("Unable to create callback:\n" ..
+ "valid callback name required")
end
+ if user_callbacks_defaults[name] == nil then
+ luatexbase_error("Unable to call callback `" .. name
+ .. "':\nunknown or empty")
+ end
local l = callbacklist[name]
local f
if not l then
@@ -1368,12 +1424,14 @@ luatexbase.call_callback=call_callback
% \begin{macro}{add_to_callback}
% \changes{v1.0a}{2015/09/24}{Function added}
% Add a function to a callback. First check arguments.
+% \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
% \begin{macrocode}
local function add_to_callback(name, func, description)
- if
- not name or
- name == "" or
- not callbacktypes[name] or
+ if not name or name == "" then
+ luatexbase_error("Unable to register callback:\n" ..
+ "valid callback name required")
+ end
+ if not callbacktypes[name] or
type(func) ~= "function" or
not description or
description == "" then
@@ -1382,7 +1440,6 @@ local function add_to_callback(name, func, description)
.. "Correct usage:\n"
.. "add_to_callback(<callback>, <function>, <description>)"
)
- return
end
% \end{macrocode}
% Then test if this callback is already in use. If not, initialise its list
@@ -1430,13 +1487,16 @@ luatexbase.add_to_callback = add_to_callback
%
% \begin{macro}{remove_from_callback}
% \changes{v1.0a}{2015/09/24}{Function added}
+% \changes{v1.0k}{2015/12/02}{adjust initialisation of cb local (PHG)}
+% \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
% Remove a function from a callback. First check arguments.
% \begin{macrocode}
local function remove_from_callback(name, description)
- if
- not name or
- name == "" or
- not callbacktypes[name] or
+ if not name or name == "" then
+ luatexbase_error("Unable to remove function from callback:\n" ..
+ "valid callback name required")
+ end
+ if not callbacktypes[name] or
not description or
description == "" then
luatexbase_error(
@@ -1444,7 +1504,6 @@ local function remove_from_callback(name, description)
.. "Correct usage:\n"
.. "remove_from_callback(<callback>, <description>)"
)
- return
end
local l = callbacklist[name]
if not l then
@@ -1457,8 +1516,6 @@ local function remove_from_callback(name, description)
% callback handler.
% \begin{macrocode}
local index = false
- local i,j
- local cb = {}
for i,j in ipairs(l) do
if j.description == description then
index = i
@@ -1469,9 +1526,8 @@ local function remove_from_callback(name, description)
luatexbase_error(
"No callback `" .. description .. "' registered for `" ..
name .. "'\n")
- return
end
- cb = l[index]
+ local cb = l[index]
table.remove(l, index)
luatexbase_log(
"Removing `" .. description .. "' from `" .. name .. "'."
@@ -1488,16 +1544,17 @@ luatexbase.remove_from_callback = remove_from_callback
%
% \begin{macro}{in_callback}
% \changes{v1.0a}{2015/09/24}{Function added}
+% \changes{v1.0h}{2015/11/27}{Guard against undefined list latex/4445}
% Look for a function description in a callback.
% \begin{macrocode}
local function in_callback(name, description)
if not name
or name == ""
+ or not callbacklist[name]
or not callbacktypes[name]
or not description then
return false
end
- local i
for _, i in pairs(callbacklist[name]) do
if i.description == description then
return true
@@ -1527,18 +1584,19 @@ luatexbase.disable_callback = disable_callback
%
% \begin{macro}{callback_descriptions}
% \changes{v1.0a}{2015/09/24}{Function added}
+% \changes{v1.0h}{2015/11/27}{Match test in in-callback latex/4445}
% List the descriptions of functions registered for the given callback.
% \begin{macrocode}
local function callback_descriptions (name)
local d = {}
if not name
or name == ""
+ or not callbacklist[name]
or not callbacktypes[name]
then
return d
else
- local i
- for k, i in pairs(callbacklist[name] or {}) do
+ for k, i in pairs(callbacklist[name]) do
d[k]= i.description
end
end