[Tex/LaTex] Using macro variables with Lua in ConTeXt

contextluamacros

I need to make some macros in ConTeXt. I have tried to use Lua code, but I do not understand how to mix ConTeXt source and Lua source together. Here is an example:

\define[3]\textmacro{
    \startlua
            if #1=1 then
                tex.print('#2')
            else
                tex.print('\math{#3}')
            end
    \stoplua
}
\starttext
    \textmacro{1}{This is some text.}{1+2}
\stoptext

If #1 is equal to "1", this should print the contents of #2, otherwise it should print the contents of #3 in math mode. In LaTeX, this can be written in this way:

\documentclass{article}
\usepackage{etoolbox}
\newcommand{\textmacro}[3]{
    \ifnumequal{#1}{1}{#2}{$#3$}
}
\begin{document}
    \textmacro{1}{This is some text.}{1+2}
\end{document}

How can I do this correctly with Lua and ConTeXt?

Best Answer

Although Joseph has already answered your question, let me give a few alternatives.

The vanilla ConTeXt version

Note that you don't need to go to Lua just to do simple comparisons. Like LaTeX, ConTeXt provides simple comparison macros at the TeX end:

\define[3]\testmacro
    {\doifelse{#1}{1}{#2}{\math{#3}}

Using Lua in a TeX macro

Joseph gave one way to use Lua in a TeX macro. Another alternative is to use the Lua function (defined in ConTeXt) commands.doifelse. ConTeXt also provides the macro \ctxcommands to call functions in the commands namespace, so you can use:

\define[3]\testmacro
    {\ctxcommand{doifelse(1==#1)}{#2}{\math{#3}}}

Notice that I just do the comparison in Lua, and then pass the control back to TeX.

Defining a Lua function and calling it from TeX

If you have a more complicated function, the usual idea is to define the function in Lua and then call it from TeX:

\startluacode
  userdata = userdata or {}
  function userdata.testmacro(counter, text, math) 
      if counter == 1 then
        context(text)
      else
        context.math(math)
      end
  end
\stopluacode

\unprotect
\define[3]\testmacro
    {\ctxlua{userdata.testmacro(#1, \!!bs #2 \!!es, \!!bs #3 \!!es)}}
\protect

Note that I define the Lua function in the userdata namespace so that it doesn't pollute the global namespace. While calling the function from TeX, I use \!!bs .. \!!es to escape strings rather than "...". This allows you to use " in the function argument, for example, you can call:

\textmacro{1}{"Hello"}{E^2}

and "Hello" will be printed.

Related Question