\ifx\BeginCatcodeRegime\undefined\else\expandafter\endinput\fi \ifx \ProvidesPackage\undefined\begingroup\def\ProvidesPackage #1#2[#3]{\endgroup\immediate\write-1{Package: #1 #3}} \fi \ProvidesPackage{luatexbase} [2015/10/04 v1.3 luatexbase interface to LuaTeX ] \edef\emuatcatcode{\the\catcode`\@} \catcode`\@=11 \ifx\@setrangecatcode\@undefined \ifx\RequirePackage\@undefined \input{ctablestack.sty}% \else \RequirePackage{ctablestack} \fi \fi \def\RequireLuaModule#1{\directlua{require("#1")}\@gobbleoptarg} \ifdefined\@ifnextchar \def\@gobbleoptarg{\@ifnextchar[\@gobble@optarg{}}% \else \long\def\@gobbleoptarg#1{\ifx[#1\expandafter\@gobble@optarg\fi#1}% \fi \def\@gobble@optarg[#1]{} \let\CatcodeTableIniTeX\catcodetable@initex \let\CatcodeTableString\catcodetable@string \let\CatcodeTableLaTeX\catcodetable@latex \let\CatcodeTableLaTeXAtLetter\catcodetable@atletter \newcatcodetable\CatcodeTableOther \@setcatcodetable\CatcodeTableOther{% \catcodetable\CatcodeTableString \catcode32 12 } \newcatcodetable\CatcodeTableExpl \@setcatcodetable\CatcodeTableExpl{% \catcodetable\CatcodeTableLaTeX \catcode126 10 % tilde is a space char \catcode32 9 % space is ignored \catcode9 9 % tab also ignored \catcode95 11 % underscore letter \catcode58 11 % colon letter } \def\BeginCatcodeRegime#1{% \@pushcatcodetable \catcodetable#1\relax} \def\EndCatcodeRegime{% \@popcatcodetable} \let\PushCatcodeTableNumStack\@pushcatcodetable \let\PopCatcodeTableNumStack\@popcatcodetable \let\SetCatcodeRange\@setrangecatcode \let\setcatcodetable\@setcatcodetable \directlua{ function luatexbase.reset_callback(name,make_false) for _,v in pairs(luatexbase.callback_descriptions(name)) do luatexbase.remove_from_callback(name,v) end if make_false == true then luatexbase.disable_callback(name) end end luatexbase.base_add_to_callback=luatexbase.add_to_callback function luatexbase.add_to_callback(name,fun,description,priority) local priority= priority if priority==nil then priority=\string#luatexbase.callback_descriptions(name)+1 end if(luatexbase.callbacktypes[name] == 3 and priority == 1 and \string#luatexbase.callback_descriptions(name)==1) then luatexbase.module_warning("luatexbase", "resetting exclusive callback: " .. name) luatexbase.reset_callback(name) end local saved_callback={},ff,dd for k,v in pairs(luatexbase.callback_descriptions(name)) do if k >= priority then ff,dd= luatexbase.remove_from_callback(name, v) saved_callback[k]={ff,dd} end end luatexbase.base_add_to_callback(name,fun,description) for k,v in pairs(saved_callback) do luatexbase.base_add_to_callback(name,v[1],v[2]) end return end luatexbase.catcodetables=setmetatable( {['latex-package'] = \number\CatcodeTableLaTeXAtLetter, ini = \number\CatcodeTableIniTeX, string = \number\CatcodeTableString, other = \number\CatcodeTableOther, latex = \number\CatcodeTableLaTeX, expl = \number\CatcodeTableExpl, expl3 = \number\CatcodeTableExpl}, { __index = function(t,key) return luatexbase.registernumber(key) or nil end} )} \ifnum\luatexversion<80 % \def\newcatcodetable#1{% \e@alloc\catcodetable\chardef \e@alloc@ccodetable@count\m@ne{"8000}#1% \initcatcodetable\allocationnumber {\escapechar=\m@ne \directlua{luatexbase.catcodetables['\string#1']=% \the\allocationnumber}}% } \fi \directlua{ function luatexbase.priority_in_callback (name,description) for i,v in ipairs(luatexbase.callback_descriptions(name)) do if v == description then return i end end return false end luatexbase.is_active_callback = luatexbase.in_callback luatexbase.base_provides_module=luatexbase.provides_module function luatexbase.errwarinf(name) return function(s,...) return luatexbase.module_error(name, s:format(...)) end, function(s,...) return luatexbase.module_warning(name, s:format(...)) end, function(s,...) return luatexbase.module_info(name, s:format(...)) end, function(s,...) return luatexbase.module_info(name, s:format(...)) end end function luatexbase.provides_module(info) luatexbase.base_provides_module(info) return luatexbase.errwarinf(info.name) end } \ifnum\luatexversion<80 % \def\newattribute#1{% \e@alloc\attribute\attributedef \e@alloc@attribute@count\m@ne\e@alloc@top#1% {\escapechar=\m@ne \directlua{luatexbase.attributes['\string#1']=% \the\allocationnumber}}% } \fi \ifx\@percentchar\@undefined {\catcode`\%=12 \gdef\@percentchar{%}} \fi \directlua{% local copynode = node.copy local newnode = node.new local nodesubtype = node.subtype local nodetype = node.id local stringformat = string.format local tableunpack = unpack or table.unpack local texiowrite_nl = texio.write_nl local texiowrite = texio.write local whatsit_t = nodetype"whatsit" local user_defined_t = nodesubtype"user_defined" local unassociated = "__unassociated" local user_whatsits = { __unassociated = { } } local whatsit_ids = { } local anonymous_whatsits = 0 local anonymous_prefix = "anon" local new_user_whatsit_id = function (name, package) if name then if not package then package = unassociated end else % anonymous anonymous_whatsits = anonymous_whatsits + 1 warning("defining anonymous user whatsit no. \@percentchar d", anonymous_whatsits) package = unassociated name = anonymous_prefix .. tostring(anonymous_whatsits) end 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 \@percentchar s:\@percentchar s (\@percentchar d)", package, name, id) else %- new id id=luatexbase.new_whatsit(name) whatsitdata[name] = id whatsit_ids[id] = { name, package } end return id end luatexbase.new_user_whatsit_id = new_user_whatsit_id local new_user_whatsit = function (req, package) local id, whatsit if type(req) == "string" then id = new_user_whatsit_id(req, package) whatsit = newnode(whatsit_t, user_defined_t) whatsit.user_id = id elseif req.id == whatsit_t and req.subtype == user_defined_t then id = req.user_id whatsit = copynode(req) if not whatsit_ids[id] then warning("whatsit id \@percentchar d unregistered; " .. "inconsistencies may arise", id) end end return function () return copynode(whatsit) end, id end luatexbase.new_user_whatsit = new_user_whatsit local get_user_whatsit_id = function (name, package) if not package then package = unassociated end return user_whatsits[package][name] end luatexbase.get_user_whatsit_id = get_user_whatsit_id 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.user_id else %- node id = asked.user_id end local metadata = whatsit_ids[id] if not metadata then % unknown warning("whatsit id \@percentchar d unregistered; inconsistencies may arise", id) return "", "" end return tableunpack(metadata) end luatexbase.get_user_whatsit_name = get_user_whatsit_name 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 \@percentchar s)", asked_package) return end texiowrite_nl("(user whatsit allocation stats for " .. asked_package) for name, id in next, whatsitdata do whatsit_list[\string#whatsit_list+1] = stringformat("(\@percentchar s:\@percentchar s \@percentchar d)", asked_package, name, id) end else texiowrite_nl("(user whatsit allocation stats") texiowrite_nl(stringformat(" ((total \@percentchar d)\string\n (anonymous \@percentchar d))", current_whatsit, anonymous_whatsits)) for package, whatsitdata in next, user_whatsits do for name, id in next, whatsitdata do whatsit_list[\string#whatsit_list+1] = stringformat("(\@percentchar s:\@percentchar s \@percentchar d)", package, name, id) end end end texiowrite_nl" (" local first = true for i=1, \string#whatsit_list do if first then first = false else % indent texiowrite_nl" " end texiowrite(whatsit_list[i]) end texiowrite"))\string\n" end luatexbase.dump_registered_whatsits = dump_registered_whatsits 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 } \let\newluatexattribute\newattribute \let\setluatexattribute\setattribute \let\unsetluatexattribute\unsetattribute \let\newluatexcatcodetable\newcatcodetable \let\setluatexcatcodetable\setcatcodetable \let\luatexbase@directlua\directlua \let\luatexbase@ensure@primitive\@gobble \let\luatexattribute\attribute \let\luatexattributedef\attributedef \let\luatexcatcodetable\catcodetable \let\luatexluaescapestring\luaescapestring \let\luatexlatelua\latelua \let\luatexoutputbox\outputbox \let\luatexscantextokens\scantextokens \catcode`\@=\emuatcatcode\relax