From ad537519dede600d6d0a0542d07c64fbc1e82de3 Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Tue, 30 Apr 2013 12:54:32 +0200
Subject: [doc] fix typos in attr.dtx

---
 luatexbase-attr.dtx | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index ded08b3..1a0df61 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -116,7 +116,7 @@ See the aforementioned source file(s) for copyright and licensing information.
 % \begin{abstract}
 % In addition to the registers existing in \tex and \etex, \luatex introduces
 % a new concept: attributes. This package takes care of attribute allocation
-% just like Plain TeX and LaTeX do for other registers, and also provides a
+% just like Plain \tex and \latex do for other registers, and also provides a
 % Lua interface.
 % \end{abstract}
 %
@@ -283,7 +283,7 @@ See the aforementioned source file(s) for copyright and licensing information.
 %    \subsubsection{Load supporting Lua module}
 %
 %    First load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}), then
-%    the supporting Lua module. We make sure luatex.sty is loaded.
+%    the supporting Lua module. We make sure \verb|luatex.sty| is loaded.
 %
 %    \begin{macrocode}
 \begingroup\expandafter\expandafter\expandafter\endgroup
@@ -299,7 +299,7 @@ See the aforementioned source file(s) for copyright and licensing information.
 %
 %    \subsection{User macros}
 %
-%    The allocaton macro is merely a wrapper around the Lua function, but
+%    The allocation macro is merely a wrapper around the Lua function, but
 %    handles error and logging in \tex, for consistency with other allocation
 %    macros.
 %
@@ -353,13 +353,14 @@ module('luatexbase', package.seeall)
 attributes = {}
 %    \end{macrocode}
 %
-%    There are currently two functions that create a new attribute.One is in
-%    |oberdiek| bundle, the other is this one. We will hack a little in order
-%    to make them compatible. The other function uses |LuT@AllocAttribute| as
-%    attribute counter, we will keep it in sync with ours. A possible problem
-%    might also appear: the other function starts attribute allocation at 0,
-%    which might break luaotfload. We output an error if a new attribute has
-%    already been allocated with number 0.
+%    In the \luatex ecosystem there are currently two functions that create a
+%    new attribute.
+%    One is in |oberdiek| bundle, the other is this one. We will hack a little
+%    in order to make them compatible. The other function uses
+%    |LuT@AllocAttribute| as attribute counter, we will keep it in sync with
+%    ours. A possible problem might also appear: the other function starts
+%    attribute allocation at 0, which will break luaotfload. We output an
+%    error if a new attribute has already been allocated with number 0.
 %
 %    \begin{macrocode}
 local luatex_sty_counter = 'LuT@AllocAttribute'
@@ -374,10 +375,10 @@ if tex.count[luatex_sty_counter] then
 end
 %    \end{macrocode}
 %
-%    The allocaton function. Unlike other registers, allocate starting from 1.
-%    Some code (eg, font handling coming from Con\tex{}t) behaves strangely
-%    with \verb+\attribute0+ and since there is plenty of room here, it
-%    doesn't seem bad to ``loose'' one item in order to avoid this problem.
+%    The allocation function. Unlike other registers, allocate starting from 1.
+%    Some code (e.~g., font handling coming from Con\tex{}t) behaves strangely
+%    with \verb+\attribute0+ set, and since there is plenty of room here, it
+%    doesn't seem bad to ``lose'' one item in order to avoid this problem.
 %
 %    \begin{macrocode}
 local last_alloc = 0
-- 
cgit v1.2.3


From 3f94f09e4111c64e6a4e3495db8ce3ebd195a1c4 Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Tue, 30 Apr 2013 16:50:58 +0200
Subject: draft user whatsit allocator

---
 luatexbase-attr.dtx | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 150 insertions(+), 2 deletions(-)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 1a0df61..977ea12 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -344,7 +344,21 @@ See the aforementioned source file(s) for copyright and licensing information.
 %
 %    \begin{macrocode}
 %<*luamodule>
+--- locals
+local nodenew           = node.new
+local nodesubtype       = node.subtype
+local nodetype          = node.id
+local stringfind        = string.find
+local stringformat      = string.format
+local texiowrite_nl     = texio.write_nl
+local texiowrite        = texio.write
+--- luatex internal types
+local whatsit_t         = nodetype"whatsit"
+local user_defined_t    = nodesubtype"user_defined"
+--- module declaration (deprecated in 5.2)
 module('luatexbase', package.seeall)
+luatexbase       = luatexbase or { }
+local luatexbase = luatexbase
 %    \end{macrocode}
 %
 %    This table holds the values of the allocated attributes, indexed by name.
@@ -368,7 +382,7 @@ if tex.count[luatex_sty_counter] then
   if tex.count[luatex_sty_counter] > -1 then
     error("luatexbase error: attribute 0 has already been set by \newattribute"
         .."macro from luatex.sty, not belonging to this package, this makes"
-        .."luaotfload unuseable. Please report to the maintainer of luatex.sty")
+        .."luaotfload unusable. Please report to the maintainer of luatex.sty")
   else
     tex.count[luatex_sty_counter] = 0
   end
@@ -401,7 +415,7 @@ function new_attribute(name, silent)
     attributes[name] = last_alloc
     unset_attribute(name)
     if not silent then
-        texio.write_nl('log', string.format(
+        texiowrite_nl('log', string.format(
             'luatexbase.attributes[%q] = %d', name, last_alloc))
     end
     return last_alloc
@@ -417,6 +431,140 @@ function unset_attribute(name)
 end
 %    \end{macrocode}
 %
+%    User whatsit allocation (experimental).
+%
+%    \begin{macrocode}
+--- cf. luatexref-t.pdf, sect. 8.1.4.25
+local prefixsep           = "-"  --- make this @ for latex junkies?
+local user_whatsits       = { }  --- name -> id
+local whatsit_ids         = { }  --- id   -> name
+local current_whatsit     = 0
+local anonymous_whatsits  = 0
+local anonymous_prefix    = "anon"
+%    \end{macrocode}
+%
+%    The whatsit allocation is split into two functions:
+%    \verb|new_user_whatsit_id| registers a new id (an integer)
+%    and returns it. It is up to the user what he actually does
+%    with the return value.
+%
+%    Registering whatsits without a name, though supported, is
+%    not exactly good style. In these cases we generate a name
+%    from a counter.
+%
+%    In addition to the whatsit name, it is possible and even
+%    encouraged to specify the name of the package that will be
+%    using the whatsit as the second argument.
+%
+%    \begin{macrocode}
+--- string -> string -> int
+new_user_whatsit_id = function (name, package)
+    if name then
+        if package then name = package .. prefixsep .. name end
+    else -- anonymous
+        anonymous_whatsits = anonymous_whatsits + 1
+        name = anonymous_prefix
+            .. prefixsep
+            .. tostring(anonymous_whatsits)
+    end
+    local id = user_whatsits[name]
+    if id then --- what to do now?
+      texiowrite_nl(stringformat(
+        "replacing whatsit %s (%d)", name, id))
+    else --- new id
+      current_whatsit     = current_whatsit + 1
+      id                  = current_whatsit
+    end
+    user_whatsits[name] = id
+    whatsit_ids[id]     = name
+    texiowrite_nl(stringformat(
+        "new user-defined whatsit %d (%s)", id, name))
+    return id
+end
+luatexbase.new_user_whatsit_id = new_user_whatsit_id
+%    \end{macrocode}
+%
+%    \verb|new_user_whatsit| first registers a new id and
+%    then also creates the corresponding whatsit of subtype “user defined”.
+%    Return values are said node and its id.
+%
+%    \begin{macrocode}
+--- string -> string -> (node_t -> int)
+new_user_whatsit = function (name, package)
+    local id    = new_user_whatsit_id(name, package)
+    local wi    = nodenew(whatsit_t, user_defined_t)
+    wi.user_id = id
+    return wi, id
+end
+luatexbase.new_user_whatsit = new_user_whatsit
+%    \end{macrocode}
+%
+%    If one knows the name of a whatsit, its corresponding id
+%    can be retrieved by means of \verb|get_user_whatsit_id|.
+%
+%    \begin{macrocode}
+--- string -> string -> int
+get_user_whatsit_id = function (name, package)
+    if package then name = package .. prefixsep .. name end
+    return user_whatsits[name]
+end
+luatexbase.get_user_whatsit_id = get_user_whatsit_id
+%    \end{macrocode}
+%
+%    The inverse lookup is also possible via \verb|get_user_whatsit_name|.
+%    Here it finally becomes obvious why it is beneficial to supply a package
+%    name -- it adds information about who created and might be relying on the
+%    whatsit in question.
+%
+%    \begin{macrocode}
+--- string -> string -> int
+get_user_whatsit_name = function (id)
+    return whatsit_ids[id]
+end
+luatexbase.get_user_whatsit_name = get_user_whatsit_name
+%    \end{macrocode}
+%
+%    For the curious as well as the cautious who are interesting in
+%    what they are dealing with, we add a function that outputs the
+%    current allocation status to the terminal.
+%
+%    \begin{macrocode}
+--- string -> unit
+dump_registered_whatsits = function (package)
+    if package then
+        texiowrite_nl("(user whatsit allocation stats for " .. package)
+    else
+        texiowrite_nl("(user whatsit allocation stats")
+    end
+    texiowrite_nl(stringformat(
+        " ((total %d)\n  (anonymous %d))",
+        current_whatsit, anonymous_whatsits))
+    texio.write_nl" ("
+    local whatsit_list = { }
+    for name, val in next, user_whatsits do
+        if package then --- restrict to matching prefix
+            if stringfind(name, "^"..package.."%"..prefixsep) then
+              whatsit_list[#whatsit_list+1] = stringformat("(%s %d)", name, val)
+            end
+        else
+            whatsit_list[#whatsit_list+1] = stringformat("(%s %d)", name, val)
+        end
+    end
+    texiowrite(table.concat(whatsit_list, "\n  "))
+    texiowrite"))"
+end
+luatexbase.dump_registered_whatsits = dump_registered_whatsits
+%    \end{macrocode}
+%    Lastly, we define a couple synonyms for convenience.
+%    \begin{macrocode}
+luatexbase.newattribute            = new_attribute
+luatexbase.newuserwhatsit          = new_user_whatsit
+luatexbase.newuserwhatsitid        = new_user_whatsit_id
+luatexbase.getuserwhatsitid        = get_user_whatsit_id
+luatexbase.getuserwhatsitname      = get_user_whatsit_name
+luatexbase.dumpregisteredwhatsits  = dump_registered_whatsits
+%    \end{macrocode}
+%
 %    \begin{macrocode}
 %</luamodule>
 %    \end{macrocode}
-- 
cgit v1.2.3


From ec9d2665e95c90f27f2529072a0616f7156ea13f Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Thu, 2 May 2013 14:46:54 +0200
Subject: drop calls to deprecated `module()`

---
 TODO                    |  1 -
 luatexbase-attr.dtx     | 20 +++++++++++---------
 luatexbase-cctb.dtx     |  9 ++++++---
 luatexbase-loader.dtx   |  3 ++-
 luatexbase-mcb.dtx      | 21 ++++++++++++++-------
 luatexbase-modutils.dtx | 47 ++++++++++++++++++++++++++++-------------------
 6 files changed, 61 insertions(+), 40 deletions(-)

diff --git a/TODO b/TODO
index 6205464..65e80cc 100644
--- a/TODO
+++ b/TODO
@@ -13,7 +13,6 @@ all
     or generalise use of qstest
 - add debug messages to be used in the test suite?
 - mark all occurences of version-dependent stuff in the code
-- quit using module() in favor of locals
 - support the syntax foo = require"foo" in modutils? How?
 
 compat
diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 977ea12..859803e 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -355,10 +355,10 @@ local texiowrite        = texio.write
 --- luatex internal types
 local whatsit_t         = nodetype"whatsit"
 local user_defined_t    = nodesubtype"user_defined"
---- module declaration (deprecated in 5.2)
-module('luatexbase', package.seeall)
+
 luatexbase       = luatexbase or { }
 local luatexbase = luatexbase
+
 %    \end{macrocode}
 %
 %    This table holds the values of the allocated attributes, indexed by name.
@@ -396,7 +396,7 @@ end
 %
 %    \begin{macrocode}
 local last_alloc = 0
-function new_attribute(name, silent)
+local function new_attribute(name, silent)
     if last_alloc >= 65535 then
         if silent then
             return -1
@@ -420,15 +420,17 @@ function new_attribute(name, silent)
     end
     return last_alloc
 end
+luatexbase.new_attribute = new_attribute
 %    \end{macrocode}
 %
 %    Unset an attribute the correct way depending on \luatex's version.
 %
 %    \begin{macrocode}
 local unset_value = (luatexbase.luatexversion < 37) and -1 or -2147483647
-function unset_attribute(name)
+local function unset_attribute(name)
     tex.setattribute(attributes[name], unset_value)
 end
+luatexbase.unset_attribute = unset_attribute
 %    \end{macrocode}
 %
 %    User whatsit allocation (experimental).
@@ -458,7 +460,7 @@ local anonymous_prefix    = "anon"
 %
 %    \begin{macrocode}
 --- string -> string -> int
-new_user_whatsit_id = function (name, package)
+local new_user_whatsit_id = function (name, package)
     if name then
         if package then name = package .. prefixsep .. name end
     else -- anonymous
@@ -490,7 +492,7 @@ luatexbase.new_user_whatsit_id = new_user_whatsit_id
 %
 %    \begin{macrocode}
 --- string -> string -> (node_t -> int)
-new_user_whatsit = function (name, package)
+local new_user_whatsit = function (name, package)
     local id    = new_user_whatsit_id(name, package)
     local wi    = nodenew(whatsit_t, user_defined_t)
     wi.user_id = id
@@ -504,7 +506,7 @@ luatexbase.new_user_whatsit = new_user_whatsit
 %
 %    \begin{macrocode}
 --- string -> string -> int
-get_user_whatsit_id = function (name, package)
+local get_user_whatsit_id = function (name, package)
     if package then name = package .. prefixsep .. name end
     return user_whatsits[name]
 end
@@ -518,7 +520,7 @@ luatexbase.get_user_whatsit_id = get_user_whatsit_id
 %
 %    \begin{macrocode}
 --- string -> string -> int
-get_user_whatsit_name = function (id)
+local get_user_whatsit_name = function (id)
     return whatsit_ids[id]
 end
 luatexbase.get_user_whatsit_name = get_user_whatsit_name
@@ -530,7 +532,7 @@ luatexbase.get_user_whatsit_name = get_user_whatsit_name
 %
 %    \begin{macrocode}
 --- string -> unit
-dump_registered_whatsits = function (package)
+local dump_registered_whatsits = function (package)
     if package then
         texiowrite_nl("(user whatsit allocation stats for " .. package)
     else
diff --git a/luatexbase-cctb.dtx b/luatexbase-cctb.dtx
index f869c5b..8958f20 100644
--- a/luatexbase-cctb.dtx
+++ b/luatexbase-cctb.dtx
@@ -649,7 +649,8 @@ See the aforementioned source file(s) for copyright and licensing information.
 %
 %    \begin{macrocode}
 %<*luamodule>
-module('luatexbase', package.seeall)
+luatexbase          = luatexbase or { }
+local luatexbase    = { }
 %    \end{macrocode}
 %
 %    The number associated to a CS name is remembered in the |catcodetables|
@@ -657,9 +658,10 @@ module('luatexbase', package.seeall)
 %
 %    \begin{macrocode}
 catcodetables = {}
-function catcodetabledef_from_tex(name, number)
+local function catcodetabledef_from_tex(name, number)
     catcodetables[name] = tonumber(number)
 end
+luatexbase.catcodetabledef_from_tex = catcodetabledef_from_tex
 %    \end{macrocode}
 %
 %    The next function creates some shortcuts for better readability in lua
@@ -667,7 +669,7 @@ end
 %    |luatexbase.catcodetables.CatcodeTableLaTeX|.
 %
 %    \begin{macrocode}
-function catcodetable_do_shortcuts()
+local function catcodetable_do_shortcuts()
     local cat = catcodetables
     cat['latex']                = cat.CatcodeTableLaTeX
     cat['latex-package']        = cat.CatcodeTableLaTeXAtLetter
@@ -678,6 +680,7 @@ function catcodetable_do_shortcuts()
     cat['string']               = cat.CatcodeTableString
     cat['other']                = cat.CatcodeTableOther
 end
+luatexbase.catcodetable_do_shortcuts = catcodetable_do_shortcuts
 %    \end{macrocode}
 %
 %    \begin{macrocode}
diff --git a/luatexbase-loader.dtx b/luatexbase-loader.dtx
index b8e5098..11918a3 100644
--- a/luatexbase-loader.dtx
+++ b/luatexbase-loader.dtx
@@ -274,7 +274,8 @@ See the aforementioned source file(s) for copyright and licensing information.
 %
 %    \begin{macrocode}
 %<*luamodule>
-module('luatexbase', package.seeall)
+luatexbase          = luatexbase or { }
+local luatexbase    = luatexbase
 %    \end{macrocode}
 %
 %    Just in case it's called from a \TeX Lua script...
diff --git a/luatexbase-mcb.dtx b/luatexbase-mcb.dtx
index f4d6448..9070c8f 100644
--- a/luatexbase-mcb.dtx
+++ b/luatexbase-mcb.dtx
@@ -392,7 +392,8 @@ See the aforementioned source file(s) for copyright and licensing information.
 %    \subsubsection{Module identification}
 %
 %    \begin{macrocode}
-module('luatexbase', package.seeall)
+luatexbase          = luatexbase or { }
+local luatexbase    = luatexbase
 local err, warning, info, log = luatexbase.provides_module({
     name          = "luatexbase-mcb",
     version       = 0.5,
@@ -627,7 +628,7 @@ local handlers = {
 %    Add a function to a callback. First check arguments.
 %
 %    \begin{macrocode}
-function add_to_callback (name,func,description,priority)
+local function add_to_callback (name,func,description,priority)
     if type(func) ~= "function" then
         return err("unable to add function:\nno proper function passed")
     end
@@ -690,12 +691,13 @@ function add_to_callback (name,func,description,priority)
     log("inserting '%s'\nat position %s in '%s'",
       description, priority, name)
 end
+luatexbase.add_to_callback = add_to_callback
 %    \end{macrocode}
 %
 %    Remove a function from a callback. First check arguments.
 %
 %    \begin{macrocode}
-function remove_from_callback (name, description)
+local function remove_from_callback (name, description)
     if not name or name == "" then
         err("unable to remove function:\nno proper callback name passed")
         return
@@ -742,13 +744,14 @@ function remove_from_callback (name, description)
     end
     return
 end
+luatexbase.remove_from_callback = remove_from_callback
 %    \end{macrocode}
 %
 %    Remove all the functions registered in a callback. Unregisters the
 %    callback handler unless the callback is user-defined.
 %
 %    \begin{macrocode}
-function reset_callback (name, make_false)
+local function reset_callback (name, make_false)
     if not name or name == "" then
         err("unable to reset:\nno proper callback name passed")
         return
@@ -767,13 +770,14 @@ function reset_callback (name, make_false)
         end
     end
 end
+luatexbase.reset_callback = reset_callback
 %    \end{macrocode}
 %
 %    Get a function's priority in a callback list, or false if the function is
 %    not in the list.
 %
 %    \begin{macrocode}
-function priority_in_callback (name, description)
+local function priority_in_callback (name, description)
     if not name or name == ""
             or not callbacktypes[name]
             or not description then
@@ -788,6 +792,7 @@ function priority_in_callback (name, description)
     end
     return false
 end
+luatexbase.priority_in_callback = priority_in_callback
 %    \end{macrocode}
 %
 %    \subsubsection{Public functions for user-defined callbacks}
@@ -804,7 +809,7 @@ end
 %    callback must also call it, see next function.
 %
 %    \begin{macrocode}
-function create_callback(name, ctype, default)
+local function create_callback(name, ctype, default)
     if not name then
         err("unable to call callback:\nno proper name passed", name)
         return nil
@@ -827,13 +832,14 @@ function create_callback(name, ctype, default)
     lua_callbacks_defaults[name] = default
     callbacktypes[name] = ctype
 end
+luatexbase.create_callback = create_callback
 %    \end{macrocode}
 %
 %    This function calls a callback. It can only call a callback created by
 %    the \texttt{create} function.
 %
 %    \begin{macrocode}
-function call_callback(name, ...)
+local function call_callback(name, ...)
     if not name then
         err("unable to call callback:\nno proper name passed", name)
         return nil
@@ -855,6 +861,7 @@ function call_callback(name, ...)
     end
     return f(...)
 end
+luatexbase.call_callback = call_callback
 %    \end{macrocode}
 %
 %    That's all folks!
diff --git a/luatexbase-modutils.dtx b/luatexbase-modutils.dtx
index 6f500da..0645e1b 100644
--- a/luatexbase-modutils.dtx
+++ b/luatexbase-modutils.dtx
@@ -237,22 +237,23 @@ See the aforementioned source file(s) for copyright and licensing information.
 % they just don't do the same thing (declaring information vs changing the
 % current name space).
 %
-% Now, here is how you module may begin:
+% Now, here is a module header template showing all the recommended elements:
 % \begin{verbatim}
 % local err, warn, info, log = luatexbase.provides_module({
 %     -- required
-%     name        = 'mymodule',
+%     name          = 'mymodule',
 %     -- recommended
-%     date        = '1970/01/01',
-%     version     = 0.0,            -- or version = '0.0a',
-%     description = 'a Lua module template',
+%     date          = '1970/01/01',
+%     version       = 0.0,            -- or version = '0.0a',
+%     description   = 'a Lua module template',
 %     -- optional and ignored
-%     author      = 'A. U. Thor',
-%     licence     = 'LPPL v1.3+',
+%     author        = 'A. U. Thor',
+%     licence       = 'LPPL v1.3+',
 % })
 %
-% module('mynamespace', package.seeall)
-% -- or any other method (see chapter 15 of PIL for examples)
+% mynamespace           = mynamespace or { }
+% local mynamespace     = mynamespace
+%
 % \end{verbatim}
 %
 % Alternatively, if you don't want to assume \pk{luatexbase-modutils} is
@@ -276,8 +277,8 @@ See the aforementioned source file(s) for copyright and licensing information.
 %     })
 % end
 %
-% module('mynamespace', package.seeall)
-% -- or any other method (see chapter 15 of PIL for examples)
+% mynamespace           = mynamespace or { }
+% local mynamespace     = mynamespace
 %
 % local function err(msg)
 %    -- etc.
@@ -457,7 +458,8 @@ See the aforementioned source file(s) for copyright and licensing information.
 %
 %    \begin{macrocode}
 %<*luamodule>
-module("luatexbase", package.seeall)
+luatexbase          = luatexbase or { }
+local luatexbase    = luatexbase
 %    \end{macrocode}
 %
 %    \subsection{Internal functions and data}
@@ -495,44 +497,49 @@ end
 local function module_error_int(mod, ...)
   error(msg_format('error', mod, ...), 3)
 end
-function module_error(mod, ...)
+local function module_error(mod, ...)
   module_error_int(mod, ...)
 end
+luatexbase.module_error = module_error
 %    \end{macrocode}
 %
 %    Split the lines explicitly in order not to depend on the value of
 %    |\newlinechar|.
 %
 %    \begin{macrocode}
-function module_warning(mod, ...)
+local function module_warning(mod, ...)
   for _, line in ipairs(msg_format('warning', mod, ...):explode('\n')) do
     texio.write_nl(line)
   end
 end
-function module_info(mod, ...)
+luatexbase.module_warning = module_warning
+local function module_info(mod, ...)
   for _, line in ipairs(msg_format('info', mod, ...):explode('\n')) do
     texio.write_nl(line)
   end
 end
+luatexbase.module_info = module_info
 %    \end{macrocode}
 %
 %    No line splitting or advanced formating here.
 %
 %    \begin{macrocode}
-function module_log(mod, msg, ...)
+local function module_log(mod, msg, ...)
   texio.write_nl('log', mod..': '..msg:format(...))
 end
+luatexbase.module_log = module_log
 %    \end{macrocode}
 %
 %    Produce custom versions of the reporting functions.
 %
 %    \begin{macrocode}
-function errwarinf(name)
+local function errwarinf(name)
   return function(...) module_error_int(name, ...) end,
     function(...) module_warning(name, ...) end,
     function(...) module_info(name, ...) end,
     function(...) module_log(name, ...) end
 end
+luatexbase.errwarinf = errwarinf
 %    \end{macrocode}
 %
 %    For our own convenience, local functions for warning and errors in the
@@ -547,7 +554,7 @@ local err, warn = errwarinf('luatexbase.modutils')
 %    Load a module with mandatory name checking and optional version checking.
 %
 %    \begin{macrocode}
-function require_module(name, req_date)
+local function require_module(name, req_date)
     require(name)
     local info = modules[name]
     if not info then
@@ -560,6 +567,7 @@ function require_module(name, req_date)
         end
     end
 end
+luatexbase.require_module = require_module
 %    \end{macrocode}
 %
 %    Provide identification information for a module. As a bonus, custom
@@ -567,7 +575,7 @@ end
 %    everything done in |require_module()|.
 %
 %    \begin{macrocode}
-function provides_module(info)
+local function provides_module(info)
     if not (info and info.name) then
         err('provides_module: missing information')
     end
@@ -576,6 +584,7 @@ function provides_module(info)
     modules[info.name] = info
     return errwarinf(info.name)
 end
+luatexbase.provides_module = provides_module
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-- 
cgit v1.2.3


From d17162ae3da3b7bbf5272322061d9c824eccf782 Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Thu, 2 May 2013 16:39:24 +0200
Subject: avoid shadowing locals

---
 luatexbase-attr.dtx | 18 +++++++++++++-----
 luatexbase-cctb.dtx |  7 ++++---
 luatexbase-mcb.dtx  | 23 +++++++++++++++++------
 3 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 859803e..209ffd6 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -356,15 +356,23 @@ local texiowrite        = texio.write
 local whatsit_t         = nodetype"whatsit"
 local user_defined_t    = nodesubtype"user_defined"
 
-luatexbase       = luatexbase or { }
-local luatexbase = luatexbase
+luatexbase              = luatexbase or { }
+local luatexbase        = luatexbase
 
 %    \end{macrocode}
 %
 %    This table holds the values of the allocated attributes, indexed by name.
 %
 %    \begin{macrocode}
-attributes = {}
+luatexbase.attributes   = luatexbase.attributes or { }
+local attributes        = luatexbase.attributes
+%    \end{macrocode}
+%
+%    Scoping: we use locals for the attribute functions.
+%
+%    \begin{macrocode}
+local new_attribute
+local unset_attribute
 %    \end{macrocode}
 %
 %    In the \luatex ecosystem there are currently two functions that create a
@@ -396,7 +404,7 @@ end
 %
 %    \begin{macrocode}
 local last_alloc = 0
-local function new_attribute(name, silent)
+function new_attribute(name, silent)
     if last_alloc >= 65535 then
         if silent then
             return -1
@@ -427,7 +435,7 @@ luatexbase.new_attribute = new_attribute
 %
 %    \begin{macrocode}
 local unset_value = (luatexbase.luatexversion < 37) and -1 or -2147483647
-local function unset_attribute(name)
+function unset_attribute(name)
     tex.setattribute(attributes[name], unset_value)
 end
 luatexbase.unset_attribute = unset_attribute
diff --git a/luatexbase-cctb.dtx b/luatexbase-cctb.dtx
index 8958f20..1e95379 100644
--- a/luatexbase-cctb.dtx
+++ b/luatexbase-cctb.dtx
@@ -649,15 +649,16 @@ See the aforementioned source file(s) for copyright and licensing information.
 %
 %    \begin{macrocode}
 %<*luamodule>
-luatexbase          = luatexbase or { }
-local luatexbase    = { }
+luatexbase                  = luatexbase or { }
+local luatexbase            = luatexbase
 %    \end{macrocode}
 %
 %    The number associated to a CS name is remembered in the |catcodetables|
 %    table.
 %
 %    \begin{macrocode}
-catcodetables = {}
+luatexbase.catcodetables    = luatexbase.catcodetables or { }
+local catcodetables         = luatexbase.catcodetables
 local function catcodetabledef_from_tex(name, number)
     catcodetables[name] = tonumber(number)
 end
diff --git a/luatexbase-mcb.dtx b/luatexbase-mcb.dtx
index 9070c8f..0c04d4d 100644
--- a/luatexbase-mcb.dtx
+++ b/luatexbase-mcb.dtx
@@ -405,6 +405,17 @@ local err, warning, info, log = luatexbase.provides_module({
 })
 %    \end{macrocode}
 %
+%    First we declare the function references for the entire scope.
+%
+%    \begin{macrocode}
+local add_to_callback
+local call_callback
+local create_callback
+local priority_in_callback
+local remove_from_callback
+local reset_callback
+%    \end{macrocode}
+%
 %    \subsubsection{Housekeeping}
 %
 %    The main table: keys are callback names, and values are the associated
@@ -628,7 +639,7 @@ local handlers = {
 %    Add a function to a callback. First check arguments.
 %
 %    \begin{macrocode}
-local function add_to_callback (name,func,description,priority)
+function add_to_callback (name,func,description,priority)
     if type(func) ~= "function" then
         return err("unable to add function:\nno proper function passed")
     end
@@ -697,7 +708,7 @@ luatexbase.add_to_callback = add_to_callback
 %    Remove a function from a callback. First check arguments.
 %
 %    \begin{macrocode}
-local function remove_from_callback (name, description)
+function remove_from_callback (name, description)
     if not name or name == "" then
         err("unable to remove function:\nno proper callback name passed")
         return
@@ -751,7 +762,7 @@ luatexbase.remove_from_callback = remove_from_callback
 %    callback handler unless the callback is user-defined.
 %
 %    \begin{macrocode}
-local function reset_callback (name, make_false)
+function reset_callback (name, make_false)
     if not name or name == "" then
         err("unable to reset:\nno proper callback name passed")
         return
@@ -777,7 +788,7 @@ luatexbase.reset_callback = reset_callback
 %    not in the list.
 %
 %    \begin{macrocode}
-local function priority_in_callback (name, description)
+function priority_in_callback (name, description)
     if not name or name == ""
             or not callbacktypes[name]
             or not description then
@@ -809,7 +820,7 @@ luatexbase.priority_in_callback = priority_in_callback
 %    callback must also call it, see next function.
 %
 %    \begin{macrocode}
-local function create_callback(name, ctype, default)
+function create_callback(name, ctype, default)
     if not name then
         err("unable to call callback:\nno proper name passed", name)
         return nil
@@ -839,7 +850,7 @@ luatexbase.create_callback = create_callback
 %    the \texttt{create} function.
 %
 %    \begin{macrocode}
-local function call_callback(name, ...)
+function call_callback(name, ...)
     if not name then
         err("unable to call callback:\nno proper name passed", name)
         return nil
-- 
cgit v1.2.3


From 2596b53e7577696440c84c1209a9f548cd6037ca Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Thu, 2 May 2013 20:56:29 +0200
Subject: store user whatsits by package

---
 luatexbase-attr.dtx | 116 +++++++++++++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 42 deletions(-)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 209ffd6..f1a0f7a 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -350,15 +350,32 @@ local nodesubtype       = node.subtype
 local nodetype          = node.id
 local stringfind        = string.find
 local stringformat      = string.format
+local tableunpack       = unpack or table.unpack
 local texiowrite_nl     = texio.write_nl
 local texiowrite        = texio.write
 --- luatex internal types
 local whatsit_t         = nodetype"whatsit"
 local user_defined_t    = nodesubtype"user_defined"
-
+local unassociated      = "__unassociated"
 luatexbase              = luatexbase or { }
 local luatexbase        = luatexbase
-
+%    \end{macrocode}
+%
+%    We improvise a basic logging facility.
+%
+%    \begin{macrocode}
+local reporter = function (log, category, ...)
+    if log == true then
+        texiowrite_nl("log", "("..category..") ")
+        texiowrite("log", stringformat(...))
+    else
+        texiowrite_nl("("..category..") ")
+        texiowrite(stringformat(...))
+    end
+end
+local warning = function (...) reporter (false, "warning", ...) end
+----- info    = function (...) reporter (false, "info",    ...) end
+local log     = function (...) reporter (true,  "log",     ...) end
 %    \end{macrocode}
 %
 %    This table holds the values of the allocated attributes, indexed by name.
@@ -423,8 +440,7 @@ function new_attribute(name, silent)
     attributes[name] = last_alloc
     unset_attribute(name)
     if not silent then
-        texiowrite_nl('log', string.format(
-            'luatexbase.attributes[%q] = %d', name, last_alloc))
+        log('luatexbase.attributes[%q] = %d', name, last_alloc)
     end
     return last_alloc
 end
@@ -445,9 +461,10 @@ luatexbase.unset_attribute = unset_attribute
 %
 %    \begin{macrocode}
 --- cf. luatexref-t.pdf, sect. 8.1.4.25
-local prefixsep           = "-"  --- make this @ for latex junkies?
-local user_whatsits       = { }  --- name -> id
-local whatsit_ids         = { }  --- id   -> name
+local user_whatsits       = {    --- (package, (name, id hash)) hash
+    __unassociated = { },        --- those without package name
+}
+local whatsit_ids         = { }  --- (id, (name * package)) hash
 local current_whatsit     = 0
 local anonymous_whatsits  = 0
 local anonymous_prefix    = "anon"
@@ -470,25 +487,31 @@ local anonymous_prefix    = "anon"
 --- string -> string -> int
 local new_user_whatsit_id = function (name, package)
     if name then
-        if package then name = package .. prefixsep .. name end
+        if not package then
+            package = unassociated
+        end
     else -- anonymous
         anonymous_whatsits = anonymous_whatsits + 1
-        name = anonymous_prefix
-            .. prefixsep
-            .. tostring(anonymous_whatsits)
+        package = unassociated
+        name    = anonymous_prefix .. tostring(anonymous_whatsits)
     end
-    local id = user_whatsits[name]
-    if id then --- what to do now?
-      texiowrite_nl(stringformat(
-        "replacing whatsit %s (%d)", name, id))
+
+    local whatsitdata = user_whatsits[package]
+    if not whatsitdata then
+        whatsitdata             = { }
+        user_whatsits[package]  = whatsitdata
+    end
+
+    local id = whatsitdata[name]
+    if id then --- warning
+        warning("replacing whatsit %s:%s (%d)", package, name, id)
     else --- new id
-      current_whatsit     = current_whatsit + 1
-      id                  = current_whatsit
+        current_whatsit     = current_whatsit + 1
+        id                  = current_whatsit
+        whatsitdata[name]   = id
+        whatsit_ids[id]     = { name, package }
     end
-    user_whatsits[name] = id
-    whatsit_ids[id]     = name
-    texiowrite_nl(stringformat(
-        "new user-defined whatsit %d (%s)", id, name))
+    log("new user-defined whatsit %d (%s:%s)", id, package, name)
     return id
 end
 luatexbase.new_user_whatsit_id = new_user_whatsit_id
@@ -503,7 +526,7 @@ luatexbase.new_user_whatsit_id = new_user_whatsit_id
 local new_user_whatsit = function (name, package)
     local id    = new_user_whatsit_id(name, package)
     local wi    = nodenew(whatsit_t, user_defined_t)
-    wi.user_id = id
+    wi.user_id  = id
     return wi, id
 end
 luatexbase.new_user_whatsit = new_user_whatsit
@@ -515,8 +538,10 @@ luatexbase.new_user_whatsit = new_user_whatsit
 %    \begin{macrocode}
 --- string -> string -> int
 local get_user_whatsit_id = function (name, package)
-    if package then name = package .. prefixsep .. name end
-    return user_whatsits[name]
+    if not package then
+        package = unassociated
+    end
+    return user_whatsits[package][name]
 end
 luatexbase.get_user_whatsit_id = get_user_whatsit_id
 %    \end{macrocode}
@@ -524,12 +549,13 @@ luatexbase.get_user_whatsit_id = get_user_whatsit_id
 %    The inverse lookup is also possible via \verb|get_user_whatsit_name|.
 %    Here it finally becomes obvious why it is beneficial to supply a package
 %    name -- it adds information about who created and might be relying on the
-%    whatsit in question.
+%    whatsit in question. First return value is the whatsit name, the second
+%    the package identifier it was registered with.
 %
 %    \begin{macrocode}
---- string -> string -> int
+--- int -> (string, string)
 local get_user_whatsit_name = function (id)
-    return whatsit_ids[id]
+    return tableunpack(whatsit_ids[id])
 end
 luatexbase.get_user_whatsit_name = get_user_whatsit_name
 %    \end{macrocode}
@@ -540,26 +566,32 @@ luatexbase.get_user_whatsit_name = get_user_whatsit_name
 %
 %    \begin{macrocode}
 --- string -> unit
-local dump_registered_whatsits = function (package)
-    if package then
-        texiowrite_nl("(user whatsit allocation stats for " .. package)
+local dump_registered_whatsits = function (asked_package)
+    local whatsit_list = { }
+    if asked_package then
+        local whatsitdata = user_whatsits[asked_package]
+        if not whatsitdata then
+            error("(no user whatsits registered for package %s)",
+                  asked_package)
+            return
+        end
+        texiowrite_nl("(user whatsit allocation stats for " .. asked_package)
+        for name, id in next, whatsitdata do
+            whatsit_list[#whatsit_list+1] =
+                stringformat("(%s:%s %d)", asked_package, name, id)
+        end
     else
         texiowrite_nl("(user whatsit allocation stats")
-    end
-    texiowrite_nl(stringformat(
-        " ((total %d)\n  (anonymous %d))",
-        current_whatsit, anonymous_whatsits))
-    texio.write_nl" ("
-    local whatsit_list = { }
-    for name, val in next, user_whatsits do
-        if package then --- restrict to matching prefix
-            if stringfind(name, "^"..package.."%"..prefixsep) then
-              whatsit_list[#whatsit_list+1] = stringformat("(%s %d)", name, val)
+        texiowrite_nl(stringformat(" ((total %d)\n  (anonymous %d))",
+            current_whatsit, anonymous_whatsits))
+        for package, whatsitdata in next, user_whatsits do
+            for name, id in next, whatsitdata do
+                whatsit_list[#whatsit_list+1] =
+                    stringformat("(%s:%s %d)", package, name, id)
             end
-        else
-            whatsit_list[#whatsit_list+1] = stringformat("(%s %d)", name, val)
         end
     end
+    texiowrite_nl" ("
     texiowrite(table.concat(whatsit_list, "\n  "))
     texiowrite"))"
 end
-- 
cgit v1.2.3


From d95b4e16d9985c89c75b798c72acb795fd4813f0 Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Thu, 2 May 2013 21:05:33 +0200
Subject: emit warning when defining anonymous whatsits

---
 luatexbase-attr.dtx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index f1a0f7a..5a4960c 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -492,6 +492,8 @@ local new_user_whatsit_id = function (name, package)
         end
     else -- anonymous
         anonymous_whatsits = anonymous_whatsits + 1
+        warning("defining anonymous user whatsit no. %d", anonymous_whatsits)
+        warning("dear package authors, please name your whatsits!")
         package = unassociated
         name    = anonymous_prefix .. tostring(anonymous_whatsits)
     end
-- 
cgit v1.2.3


From 00ba44f1939220af84ad885d1ba2f1f974bd7eb7 Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Thu, 2 May 2013 21:45:14 +0200
Subject: emit warning after 2^53 user whatsits

---
 luatexbase-attr.dtx | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 5a4960c..7c8f5b9 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -465,6 +465,7 @@ local user_whatsits       = {    --- (package, (name, id hash)) hash
     __unassociated = { },        --- those without package name
 }
 local whatsit_ids         = { }  --- (id, (name * package)) hash
+local whatsit_cap         = 2^53 --- Lua numbers are doubles
 local current_whatsit     = 0
 local anonymous_whatsits  = 0
 local anonymous_prefix    = "anon"
@@ -509,6 +510,11 @@ local new_user_whatsit_id = function (name, package)
         warning("replacing whatsit %s:%s (%d)", package, name, id)
     else --- new id
         current_whatsit     = current_whatsit + 1
+        if current_whatsit >= whatsit_cap then
+            warning("maximum of %d integral user whatsit ids reached",
+                whatsit_cap)
+            warning("further whatsit allocation may be inconsistent")
+        end
         id                  = current_whatsit
         whatsitdata[name]   = id
         whatsit_ids[id]     = { name, package }
-- 
cgit v1.2.3


From 9bc0be2978b9c87eaf111d93339378a9e3b5bbc9 Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Thu, 2 May 2013 22:05:22 +0200
Subject: accept node as argument for function ``get_user_whatsit_name``

---
 luatexbase-attr.dtx | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 7c8f5b9..54c26f7 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -561,8 +561,14 @@ luatexbase.get_user_whatsit_id = get_user_whatsit_id
 %    the package identifier it was registered with.
 %
 %    \begin{macrocode}
---- int -> (string, string)
-local get_user_whatsit_name = function (id)
+--- int | node -> (string, string)
+local get_user_whatsit_name = function (asked)
+    local id
+    if type(asked) == "number" then
+        id = asked
+    else --- node
+        id = asked.user_id
+    end
     return tableunpack(whatsit_ids[id])
 end
 luatexbase.get_user_whatsit_name = get_user_whatsit_name
-- 
cgit v1.2.3


From c5837a5e38f2324ce7960840b609c290337ff160 Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Thu, 2 May 2013 22:15:35 +0200
Subject: add warning if ``get_user_whatsit_name`` is called with unknown id
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

another of Stephan Hennig’s suggestions
---
 luatexbase-attr.dtx | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 54c26f7..60ca026 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -560,6 +560,9 @@ luatexbase.get_user_whatsit_id = get_user_whatsit_id
 %    whatsit in question. First return value is the whatsit name, the second
 %    the package identifier it was registered with.
 %
+%    We issue a warning and return empty strings in case the asked whatsit is
+%    unregistered.
+%
 %    \begin{macrocode}
 --- int | node -> (string, string)
 local get_user_whatsit_name = function (asked)
@@ -569,7 +572,12 @@ local get_user_whatsit_name = function (asked)
     else --- node
         id = asked.user_id
     end
-    return tableunpack(whatsit_ids[id])
+    local metadata = whatsit_ids[id]
+    if not metadata then -- unknown
+        warning("whatsit id %d unregistered; inconsistencies may arise", id)
+        return "", ""
+    end
+    return tableunpack(metadata)
 end
 luatexbase.get_user_whatsit_name = get_user_whatsit_name
 %    \end{macrocode}
-- 
cgit v1.2.3


From f7103fd0390b98c9ad4e74d8624376ee5b402a2b Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Sat, 4 May 2013 01:22:25 +0200
Subject: have ``new_user_whatsit`` return a generating function

---
 luatexbase-attr.dtx | 45 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 60ca026..faa0261 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -345,7 +345,8 @@ See the aforementioned source file(s) for copyright and licensing information.
 %    \begin{macrocode}
 %<*luamodule>
 --- locals
-local nodenew           = node.new
+local copynode          = node.copy
+local newnode           = node.new
 local nodesubtype       = node.subtype
 local nodetype          = node.id
 local stringfind        = string.find
@@ -525,19 +526,21 @@ end
 luatexbase.new_user_whatsit_id = new_user_whatsit_id
 %    \end{macrocode}
 %
-%    \verb|new_user_whatsit| first registers a new id and
-%    then also creates the corresponding whatsit of subtype “user defined”.
-%    Return values are said node and its id.
+%    \verb|new_user_whatsit| first registers a new id and then also
+%    creates the corresponding whatsit of subtype “user defined”.
+%    We return a nullary function that delivers copies of the whatsit.
 %
 %    \begin{macrocode}
---- string -> string -> (node_t -> int)
+--- string -> string -> (unit -> node_t, int)
 local new_user_whatsit = function (name, package)
-    local id    = new_user_whatsit_id(name, package)
-    local wi    = nodenew(whatsit_t, user_defined_t)
-    wi.user_id  = id
-    return wi, id
+    local id         = new_user_whatsit_id(name, package)
+    local whatsit    = newnode(whatsit_t, user_defined_t)
+    whatsit.user_id  = id
+    --- unit -> node_t
+    return function ( ) return copynode(whatsit) end, id
 end
-luatexbase.new_user_whatsit = new_user_whatsit
+luatexbase.new_user_whatsit         = new_user_whatsit
+luatexbase.new_user_whatsit_factory = new_user_whatsit --- for Stephan
 %    \end{macrocode}
 %
 %    If one knows the name of a whatsit, its corresponding id
@@ -564,11 +567,15 @@ luatexbase.get_user_whatsit_id = get_user_whatsit_id
 %    unregistered.
 %
 %    \begin{macrocode}
---- int | node -> (string, string)
+--- int | fun | node -> (string, string)
 local get_user_whatsit_name = function (asked)
     local id
     if type(asked) == "number" then
         id = asked
+    elseif type(asked) == "function" then
+        --- node generator
+        local n = asked()
+        id = n.id
     else --- node
         id = asked.user_id
     end
@@ -613,9 +620,20 @@ local dump_registered_whatsits = function (asked_package)
             end
         end
     end
+
     texiowrite_nl" ("
-    texiowrite(table.concat(whatsit_list, "\n  "))
-    texiowrite"))"
+    --- in an attempt to be clever the texio.write* functions
+    --- mess up line breaking, so concatenation is unusable ...
+    local first = true
+    for i=1, #whatsit_list do
+        if first then 
+            first = false
+        else -- indent
+            texiowrite_nl"  "
+        end
+        texiowrite(whatsit_list[i])
+    end
+    texiowrite"))\n"
 end
 luatexbase.dump_registered_whatsits = dump_registered_whatsits
 %    \end{macrocode}
@@ -623,6 +641,7 @@ luatexbase.dump_registered_whatsits = dump_registered_whatsits
 %    \begin{macrocode}
 luatexbase.newattribute            = new_attribute
 luatexbase.newuserwhatsit          = new_user_whatsit
+luatexbase.newuserwhatsitfactory   = new_user_whatsit_factory
 luatexbase.newuserwhatsitid        = new_user_whatsit_id
 luatexbase.getuserwhatsitid        = get_user_whatsit_id
 luatexbase.getuserwhatsitname      = get_user_whatsit_name
-- 
cgit v1.2.3


From 94fd32b7dd09f9c3caca57a24ca7519be66b012e Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
Date: Sat, 4 May 2013 01:25:40 +0200
Subject: fix ``get_user_whatsit_name``

---
 luatexbase-attr.dtx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index faa0261..aa5e987 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -575,7 +575,7 @@ local get_user_whatsit_name = function (asked)
     elseif type(asked) == "function" then
         --- node generator
         local n = asked()
-        id = n.id
+        id = n.user_id
     else --- node
         id = asked.user_id
     end
-- 
cgit v1.2.3