4

How can I create a macro (re)definition directly inside a LuaTeX block?

e.g.,

\directlua{tex.print("\\mymacro{test}")}

would be the same as

\mymacro{test}

in TeX?

8
  • You're missing \noexpand before \\ (and I'm pretty sure to have seen a similar question in the past --- no time to hunt for it, though). Mar 17, 2012 at 23:04
  • Thanks, I thought I tried that as I saw an example somewhere too but it didn't work. I think I put the noexpand in the wrong place. It should be tex.print("\noexpand\\mymacro{test}")
    – Uiy
    Mar 17, 2012 at 23:12
  • I tried it both with and without the \noexpand in ConTeXt, and it seems to work equally well. Am I missing something?
    – Esteis
    Mar 17, 2012 at 23:22
  • 1
    @Eris Ok, see my updated post on how to define and call a TeX macro in lua. See if you can reproduce those without using noexpand.
    – Uiy
    Mar 17, 2012 at 23:38
  • 1
    @Esteis: In ConTeXt, inside a luacode environment, \\ is unexpandable. In LaTeX, if you don't use any package, \\ is not redefined inside \directlua, so a \noexpand is needed to ensure that Lua sees \\ .
    – Aditya
    Mar 17, 2012 at 23:46

3 Answers 3

6

While the other explanations are correct, I strongly suggest to use another way. Don't write any code in \directlua, except for a call to another file. See my lengthy answer at https://tex.stackexchange.com/a/33102/243

That way you can write tex.print("\\mymacro{test}") in your Lua file and TeX won't see it and thus you don't need to protect the string`.

1
  • It definitely is easier and better and I've started doing this simply because I get better error message locations and it is easier to maintain. I still like to use directlua for testing simple things. I guess I could make a "main" function in a separate file and call that from latex. The biggest problem I have is having to switch between files. (write in lua file, save, switch to latex file, compile... doesn't seem like much but those few tens of seconds add up)
    – Uiy
    Mar 21, 2012 at 12:14
2

If I understand you and your example correctly, you want to (1) define a macro yourself in TeX; (2) generate some TeX code from LuaTeX that includes a call to your macro; (3) you want that TeX code to be expanded (evaluated). Something like this? (ConTeXt code.)

% Define the macro we're going to use
\def\betweenXY#1%
    { X#1Y }

% Either print the backslash directly (don't forget to escape it!) (options 1 and 3)
% or use the fact that any macro you define ends up in the `context` (option 2)
% namespace in LuaTeX
\startluacode
    tex.print('\\betweenXY{jolly}')  % option 1
    context.betweenXY('swagman')     % option 2
\stopluacode
\directlua{tex.print('\\betweenXY{swagman}')} % option 3
2
  • I'm not sure if this works or not but as Bruno pointed out you have to not expand the macro(I guess luatex is expanding the macro inline instead of just passing it as text). The context I didn't know about and that is helpful as it is something I'll have to learn about eventually.
    – Uiy
    Mar 17, 2012 at 23:22
  • This works; I tested it. Can't see any behaviour change with the \noexpand. \directlua{print('\\betweenXY{camped}')} and \directlua{print('\noexpand\\betweenXY{camped}')} both print this to stdout: \betweenXY{camped}.
    – Esteis
    Mar 17, 2012 at 23:52
1

Bruno answered this but here is the corrected code:

\def\mymacro#1{--#1--}
\directlua{tex.print("\noexpand\\mymacro{test}")}

The Lua code will call \mymacro with test as an argument.

The following code

\def\mymacro#1{-#1}
\mymacro{test}

is equivalent to

\directlua{tex.print("\noexpand\\def\noexpand\\mymacro\#1{-\#1-}")} % Same as using \def\mymacro#1{-#1-} in TeX
\directlua{tex.print("\noexpand\\mymacro{test}")} % Same as using \mymacro{test} in TeX

It seems one must use \noexpand on all TeX macros to prevent TeX from interpreting them(basically to use them as a text string. If not, TeX will see \def in the above string and try to define a macro instead of passing \def to the tex.print function.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .