Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
add comment

2 Answers 2

up vote 8 down vote accepted

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.

share|improve this answer
add comment

There are a few things wrong. First, Lua uses the C-like == for comparison, not = (which is used for assignment). Secondly, you need to correctly escape the \\ in the branch using \math. Finally, you want "..." to quote material. Also, as this is ConTeXt-specific we can use context rather than tex.print:

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

(Note: I'm no ConTeXt or Lua expert, so there may be more to add here!)

share|improve this answer
2  
Or better context.math("#3") and so no backslash escaping is needed, see ConTeXt Lua Documents documentation for more info. –  Khaled Hosny Feb 4 '12 at 13:38
1  
I did say I'm no expert! –  Joseph Wright Feb 4 '12 at 13:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.