这个问题可能微不足道,但我几个小时前就开始探索 Lua(La)TeX,所以请耐心等待。
MWE 如下:
test.tex
:
\documentclass{article}
\directlua{require("test.lua")}
\begin{document}
\foo{bar}
\end{document}
test.lua
:
tex.print("\\newcommand{\\foo}[1]{")
tex.print("\\texttt{#1}")
-- arg = ?? how do I pass #1 to arg ??
-- arg = arg .. " baz"
-- tex.print("\\textit{" .. arg .. "}")
tex.print("}")
我知道我可以将其放入文件\newcommand
中tex
,然后directlua
在命令定义中调用,但在我的实际用例中,我循环遍历一个表,其中的键是命令名称,所以我需要保持原样。
编辑:由于我最初的问题可能有点像 XY 问题,因此我在下面发布了我的真实用例。
我的目标是:给定一组由thmtools
包定义的定理环境,通过将它们嵌入到环境中来重新定义它们tcolorbox
。
我开始通过这种方式做事expl3
,但很快就感到沮丧,部分原因是我对 LaTeX3 编程方式的无能,部分原因是与其他所有“正常”编程语言(for 循环、if 语句等)相比,用 LaTeX 编程太痛苦了,这就是我开始深入研究 LuaTeX 的原因。
现在来看看代码。我有这张表
boxed_theorems = {
definition = "definition",
example = "example",
lemma = "theorem",
theorem = "theorem",
corollary = "theorem",
proof = "proof",
}
其中的键是环境名称(同样来自 thmtools),值是tcolorbox
选项(这里definition
,,和example
是一堆 tcolorbox 样式。theorem
proof
我循环遍历该表(以及通过包含的其余.lua文件\directlua
)的方式如下:
tex.print("\\ExplSyntaxOn")
for theorem,tcolorbox_theorem in pairs(boxed_theorems) do
-- copy <theorem_name> in a new environment inner<theorem_name>
tex.print("\\let\\inner" .. theorem .. "\\" .. theorem)
tex.print("\\let\\endinner" .. theorem .. "\\end" .. theorem)
tex.print("\\RenewDocumentEnvironment{ " .. theorem .. " }{ O{} }{")
-- I want to be able to call the new environment like this:
--
-- \begin{theorem}[name={foo}, label={bar}, tcolorbox={baz}]
--
-- where 'name={foo}, label={bar}' is the argument of the
-- innertheorem and should be assigned to 'theorem_options',
-- while '{baz}' is an argument of the embedding tcolorbox and
-- should be assigned to 'tcolorbox_local'.
-- I haven't got that far yet (I need to create a function that
-- parses #1, hence the original post), so for now they are just
-- left empty.
theorem_options = ""
tcolorbox_local = ""
-- The rest is pretty self-explanatory
tex.print("\\begin{tcolorbox}[" .. tcolorbox_theorem .. ","
.. tcolorbox_local .. "]")
if theorem_options == "" then
tex.print("\\begin{inner" .. theorem .. "}")
else
tex.print("\\begin{inner" .. theorem .. "}[" .. theorem_options .. "]")
end
tex.print("}{")
tex.print("\\end{inner" .. theorem .. "}")
tex.print("\\end{tcolorbox}")
tex.print("}")
end
tex.print("\\ExplSyntaxOff")
答案1
我认为在 .tex 文件中设置 LaTeX 宏并将 Lua 代码分组到可以接受和返回参数的函数中更为直接。
例如,test.tex
可能如下:
\documentclass{article}
\directlua{require("test.lua")}
\newcommand\foo[1]{\directlua{foo("#1")}}
\begin{document}
\foo{bar}
\end{document}
虽然test.lua
可能包含
function foo ( s )
tex.sprint ( "\\textit{"..s.."}" )
end
答案2
请注意, 积累的字符串 直到 Lua 块完成才会返回到 TeX,因此在作为参数处理的tex.print
点处没有 Lua 处于活动状态。因此,要回答您的问题,您需要在该点重新输入 Lua,如下所示。#1
bar
这将打印
arg is: barbaz
来自Lua,显示字符串bar
被传递给Lua。
并对其进行排版,我认为这就是您想要的输出。
然而,这几乎肯定不是解决实际用例的最佳方法。
\documentclass{article}
\directlua{require("test.lua")}
\begin{document}
\foo{bar}
\directlua{
texio.write_nl('arg is: ' .. arg .. '\string\n')
}
\end{document}
测试.lua
tex.print("\\newcommand{\\foo}[1]{")
tex.print("\\texttt{#1}")
tex.print("\\directlua{arg='#1' arg = arg .. 'baz' tex.print('\\\\textit{' .. arg .. '}')}")
tex.print("}")