似乎所有 TeX 命令都会扩展为不可扩展的标记(例如,TOKENS1),然后这些标记会转换为其他标记(例如,TOKENS2)。例如
\directlua{
local var = [[\luaescapestring{\TeX}]]
print("*****" .. var .. "*****")}
\bye
执行完成后\luaescapestring{\TeX}
,我们得到的是
T\\kern -.1667em\\lower .5ex\\hbox {E}\\kern -.125emX
为什么
\luaescapestring
这样做以及为什么我们在 LuaTeX 中需要这个命令?
答案1
回答第二个问题(稍后回答第一个问题):
为什么在LuaTeX中我们需要这个命令?
想象一下以下文档:
\documentclass{article}
\newcommand\foo[1]{%
\directlua{tex.sprint("#1") }}
\begin{document}
\foo{bar}
\end{document}
\foo{bar}
扩展为\directlua{tex.sprint("bar")}
输出bar
。
现在让我们改变宏调用:
\documentclass{article}
\newcommand\foo[1]{%
\directlua{tex.sprint("#1") }}
\begin{document}
\foo{"baz"}
\end{document}
现在\foo{"baz"}
被扩展为 ,\directlua{tex.sprint(""baz"") }
这不是有效的 Lua 语法。为了保护我们免受想要打印引号的用户的侵害"
,我们可以手动检查参数(这往往非常困难),也可以依靠魔法\luaescapestring{...}
- 在 LaTeX 中,它的前缀是luatex
:
\documentclass{article}
\newcommand\foo[1]{%
\directlua{tex.sprint("\luatexluaescapestring{#1}") }}
\begin{document}
\foo{"baz"}
\end{document}
现在它扩展为如下所示的内容: \directlua{tex.sprint("\"baz\"")}
。
回答第一个问题:
为什么 \luaescapestring 可以完成这个工作?
\TeX
在纯 TeX 中定义:
\def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX}
因此 TeX 的扩展是T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX
包含\k
、\l
、\h
,它们是 Lua 字符串中的控制代码(或可能是)。因此\luaescapestring
添加一个反斜杠以将\\k
、\\l
和\\h
作为字符串源。现在您已经通过使用[[...]]
来定义字符串来欺骗系统,并且在此双括号字符串中反斜杠不会造成任何伤害。因此,在您的情况下,您不必使用\luaescapestring
。