我有类似的东西
\directlua{X = "width=0.5*\linewidth"} <-- invalid escape sequence
\directlua{X = "width=0.5*\\linewidth"} <-- Error
! Undefined control sequence.
\\->\let \reserved@e
\relax \let \reserved@f \relax \@ifstar {\let \reserved...
l.254 ...X = "width=0.5*\\linewidth";}
X 在 lua 函数中使用,例如
function doX()
--X = "width=0.5*\\linewidth"; --works fine
tex.print("\includegraphics["..X.."]{...}");
end
因此问题不在于函数或我传递的内容,而在于转义问题。这是 catcode 问题吗?基本上,我想将字符串中的 LaTeX 宏传递给 lua,然后这些宏最终被 lua 代码原封不动地吐出,但\l
在 Lua 中被解释为转义序列\\
,我猜,这对 LaTeX 来说很奇怪。
答案1
该\directlua
原语在将结果字符串传递给 Lua 之前对其参数进行完全扩展。一般来说,它只应用于小的“片段”或加载单独的专用 Lua 文件
\directlua{dofile("name-of-file")}
因为这样就避免了担心 TeX<-> Lua 问题。
当你使用\directlua
除“文本”以外的任何内容时,你必须留意将要发生的 TeX 扩展。
\directlua{X = "width=0.5*\linewidth"}
因为\linewidth
不是可扩展标记,所以文字字符串被传递给 Lua。然后它看到\l
,正如错误所说,这不是有效的转义序列。
\directlua{X = "width=0.5*\\linewidth"}
你有 TeX 控制序列\\
:这通常意味着 LaTeX 中的行尾,并且有一个定义,它将扩展但不是“正确”。因此,你会得到一个奇怪的错误,就像你尝试
\edef\foo{\\}
正确的方法这里是为了确保 Lua 看到价值的\linewidth
:
\directlua{X = "width=0.5*\the\linewidth"}
如果你想在这里进行计算,你需要考虑到这\linewidth
是一个维度,所以也许
\directlua{X = "width=\the\dimexpr0.5\linewidth\relax"}
可能会更好。
如果你想让 Lua 返回 TeX 控制序列,你需要将文字放入\\
字符串中:这是使用 完成的\noexpand
。因此,如果你希望持有X
一个字符串以返回 TeX,那么
\directlua{X = "width=0.5*\noexpand\\linewidth"}
是正确的方法。
对于较长的块,可以考虑使用luacode
包。它定义了一个环境,在这个环境中进行了一些 catcode 更改,以便“更轻松地”将 Lua 代码直接放入 LaTeX 文档中。有几件事需要注意
- Catcode 更改和分组使
luacode
不可扩展 - 像(几乎)所有 LaTeX 环境一样,
luacode
是一个 TeX 组,因此 TeX 端的任何定义都需要是全局的才能“转义”
使用luacode
一个可能会
\RequirePackage{luacode}
\begin{luacode}
X = "width=0.5*\\linewidth"
\end{luacode}