[luatex] Luatex primitive names

Taco Hoekwater taco at elvenkind.com
Mon Mar 9 15:27:34 CET 2009

Hi all,

After all the recent discussion, Hartmut, Hans and myself have been
emailing about primitives and namespaces and such, and we believe we
have come up with an extensible solution. Here is our plan on how
to handle this in luatex 0.40 and onwards:

First, there will be a new lua function tex.primitives(), as I wrote
in my earlier email. It optionally takes a list of keywords as argument
that select various sets of primitives to list (instead of everything,
which is the default). These are the keywords and meanings:

 'etex'   -- the list of primitives etex 2.2 offered on top of tex82
 'pdftex' -- non-etex primitives pdftex 1.40 offered on top of tex82
 'omega'  -- non-etex primitives aleph rc4 offered on top of tex82
 'luatex' -- primitives luatex itself offers on top of tex82

For example

  tex.primitives ('etex', 'omega')  -- this would be aleph's list
                                    -- of new primitives

  tex.primitives ('etex', 'pdftex') -- and this is pdfetex

  tex.primitives ()                 -- this is the whole lot:
                                    -- all non-TeX82 primitives

The names returned are the ones documented in the various reference
manuals (as strings, not leading backslash).

Second, there will be a new lua function called tex.enableprimitives(),
which takes two arguments. The first argument is a prefix string, and
the second an array of names.

For each combination of prefix and name, the tex.enableprimitives()
function first verifies that <name> is one of the new, non-tex82
commands (it must be returned by one of the tex.primitives() calls
explained above). If not, it does nothing and skips to the next pair.

Otherwise, it will contruct a csname variable by concatenating the
<prefix> and the <name>, unless the <prefix> is already the actual
prefix of <name>. In the latter case, it will discard the <prefix>,
and just use <name>.

Then it will then check for the existence of the constructed csname.
If the csname is currently undefined (note: that is not the same
as \relax), then it will globally define the csname to have the meaning:
run code belonging to the primitive <name>. If for some reason the
csname is already defined, it does nothing and tries the next pair.

An example:
  tex.enableprimitives('LuaTeX', {'formatname'})

will define \LuaTeXformatname with the same intrinsic meaning as
the current primitive \formatname, provided that \LuaTeXformatname
is currently undefined.

Second example:

  tex.enableprimitives('Omega',tex.primitives ('omega'))

will define a whole series of csnames like \Omegatextdir,
\Omegapardir, etc., but it will stick with \OmegaVersion instead of
creating the doubly-prefixed \OmegaOmegaVersion.

Third (and this is why the above two functions are needed) starting
with version 0.40, luatex in --ini mode will contain only the tex82
primitives and \directlua, no extra primitives *at all*.

So, if you want to have all the new functionality available using
their default names, as it is now, you will have to add

  \expandafter\ifx\csname directlua\endcsname \relax \else
     \directlua {tex.enableprimitives('',tex.primitives ())}

near the beginning of your format generation file. Or you can choose
different prefixes for different subsets, as you see fit.

Calling some form of tex.enableprimitives() is highly important though,
because if you don't, you will end up with a tex82-lookalike that can
run lua code but not do much else. The defined csnames are (of course)
saved in the format and will be available runtime.

We trust this solution is flexible enough to accomodate everyones
wishes, but if there are any comments, please give them now rather than
later. Once 0.40 is out, we don't want to have to go back to this topic.

Best wishes,

More information about the luatex mailing list