From ad537519dede600d6d0a0542d07c64fbc1e82de3 Mon Sep 17 00:00:00 2001 From: Philipp Gesang 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 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} % % \end{macrocode} -- cgit v1.2.3 From ec9d2665e95c90f27f2529072a0616f7156ea13f Mon Sep 17 00:00:00 2001 From: Philipp Gesang 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 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 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 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 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 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 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 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 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