1

LuaTeX provides the primitive \directlua, which is described in detail in section 1.6.1 of the LuaTeX reference manual. Basically, this primitive runs Lua code. Its syntax is:

\directlua ⟨general text⟩
\directlua name ⟨general text⟩ ⟨general text⟩
\directlua ⟨16-bit number⟩ ⟨general text⟩

For reasons that would take too long to explain, I would like to run some custom (TeX) code everytime \directlua is used after normal \directlua work is carried out. This custom code would only make use of one of the arguments passed: the Lua code; all other arguments passed to the primitive would be ignored.

My first attempt was using \let to save \directlua under another name and then overwriting \directlua with \def. However, this turned out to be problematic because it seemed to be impossible to emulate \directlua's syntax with \def. That said, I'm not very skilled, to say the least.

Then I tried etoolbox's \apptocmd and xpatch's \xapptocmd:

\apptocmd{\directlua}{%
    % my custom code%
}
{}
{\typeout{could not append to \noexpand\directlua}\stop}

\xapptocmd{\directlua}{%
    % my custom code%
}
{}
{\typeout{could not append to \noexpand\directlua}\stop}

… but both fail.

Is it possible to do what I want to do, i.e., turn \directlua into something that has exactly the same syntax as LuaTeX's \directlua and in fact forwards its arguments to LuaTeX's \directlua, plus runs some code that makes use of some of the arguments?


For anyone interested: What I want to do is to save the Lua code that's passed to \directlua in a bytecode slot. This should allow, I believe, to dump formats even when there is Lua code in use (currently, this is problematic). Basically, the idea is:

% before the patch
% We save the plain \directlua so as to not run into a loop later
\let\plaindirectlua\directlua

% As said, this patch doesn't apply, but you get the idea
\apptocmd{\directlua}{%
    \newluabytecode\mybytecode%
    \plaindirectlua{lua.bytecode[\the\mybytecode]=function()#1 end}%
    \global\everyjob\expandafter{\the\everyjob\plaindirectlua{lua.bytecode[\the\mybytecode]()}}%
}
{}
{}
  • 3
    you can store things in the bytecode table but you can't in general delay all directlua code in that way typically the directlua calls will be writing back to the tex stream but that won't happen if you convert them to function bytecodes, so the surrounding tex probably won't work. If you know you are in this setup you could write directlua that would work, but then you could use bytecode directly in that case – David Carlisle Jan 21 '16 at 15:04
  • 1
    @DavidCarlisle comment boils down to 'Do Not Do This'. We can argue about format dumping as an approach, but for Lua code add it to \everyjob if that's what you need. – Joseph Wright Jan 21 '16 at 15:47
  • @DavidCarlisle The Lua code would still be executed at the moment of the \directlua call; what I want is to additionally save it in a bytecode slot that's dumped in the format. That's why I thought about using \apptocmd and the kind: to append code to be run after the normal \directlua work is carried out. – Kalrish Jan 21 '16 at 16:00
  • 2
    The syntax \primitive ⟨optional keywords⟩ ⟨general text⟩ is exceptional to primitve commands. You can always define a macro like \def\directlua name #1#2{…}, but then the name part is mandatory for every call. Also #1 has to be wrapped in braces. – Henri Menke Jan 21 '16 at 22:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.