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