在 ConTeXt 中将宏变量与 Lua 结合使用

在 ConTeXt 中将宏变量与 Lua 结合使用

我需要在 ConTeXt 中创建一些宏。我尝试过使用 Lua 代码,但我不知道如何将 ConTeXt 源和 Lua 源混合在一起。以下是示例:

\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

如果#1等于“1”,则应打印的内容#2,否则应以数学模式打印的内容#3。在 LaTeX 中,可以这样写:

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

如何使用 Lua 和 ConTeXt 正确地做到这一点?

答案1

尽管约瑟夫已经回答了你的问题,但让我再给出几个替代方案。

原始 ConTeXt 版本

请注意,您不需要使用 Lua 进行简单的比较。与 LaTeX 一样,ConTeXt 在 TeX 端提供了简单的比较宏:

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

在 TeX 宏中使用 Lua

Joseph 给出了一种在 TeX 宏中使用 Lua 的方法。另一种方法是使用 Lua 函数(在 ConTeXt 中定义)commands.doifelse。ConTeXt 还提供了宏\ctxcommands来调用commands命名空间中的函数,因此您可以使用:

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

请注意,我只是在 Lua 中进行比较,然后将控制权交还给 TeX。

定义一个 Lua 函数并从 TeX 调用它

如果你有一个更复杂的函数,通常的想法是在 Lua 中定义该函数,然后从 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

请注意,我在命名空间中定义 Lua 函数userdata,以便它不会污染全局命名空间。从 TeX 调用函数时,我使用\!!bs .. \!!es来转义字符串,而不是"..."。这允许您在函数参数中使用",例如,您可以调用:

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

"Hello"会被打印出来。

答案2

有几个错误。首先,Lua 使用 C 类==进行比较,而不是=(用于赋值)。其次,您需要\\使用 正确转义分支中的\math。最后,您想要"..."引用材料。此外,由于这是 ConTeXt 特有的,我们可以使用context而不是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

(注意:我不是 ConTeXt 或 Lua 专家,因此这里可能还有更多内容需要添加!)

相关内容