我需要在 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 专家,因此这里可能还有更多内容需要添加!)