我不明白token
luatex 的库是如何工作的。
\documentclass{standalone}
\begin{document}
\def\mymacro{A}
\directlua{%
t = token.create ('mymacro')
token.expand(t)
token.get_next()
}
\end{document}
token.expand 无法按我预期的方式工作:luatex
说Undefined control sequence
。为什么?
有了token.get_next()
,我不知道我到底应该得到什么......
答案1
不幸的token.expand
是,目前已损坏。请参阅错误报告它源自一个与您完全相同的例子。
答案2
token.expand
永远没有用,即使过了 10 年也没有修复,因为 luatex 的每个 API 都与变量隔离,例如cur_cmd
。但你可以编写自己的expand
%!TEX program=lualatex
\documentclass{standalone}
\directlua{
local exp_after = token.create('expandafter')
local lbrace = token.create(string.byte('{'))
local rbrace = token.create(string.byte('}'))
function expand()
token.put_next(lbrace, exp_after, rbrace)
token.scan_toks(false, true)
end
}
\begin{document}
\def\mymacro{ABC}%
\directlua{
local t = token.create'mymacro'
token.put_next(t)
expand()
token.get_next()
}
\end{document}
如果需要处理大括号的 catcode 和 的重新定义\expandafter
,代码会更长。
local lbrace = token.new(string.byte'{', 1)
local rbrace = token.new(string.byte'}', 2)
function expand()
local cur_exp_after = token.create('expandafter')
local cur_let = token.create('let')
local prefix = '^'..'^@'
while token.is_defined(prefix..'expandafter') or token.is_defined(prefix..'let') do
prefix = prefix..'^'..'^@'
end
local undefined = token.create(prefix..'expandafter')
tex.enableprimitives(prefix, {'expandafter', 'let'})
local exp_after, let = token.create(prefix..'expandafter'), token.create(prefix..'let')
token.put_next(lbrace, exp_after, rbrace)
token.scan_toks(false, true)
tex.runtoks(function()
token.put_next(let, exp_after, undefined, let, let, undefined)
end)
end
答案3
或者也可以tex.runtoks
这样实现
tex.runtoks(function()
tex.sprint {token.create "expandafter"}
end)
然而,这依赖于LuaTeX的一些实现细节。
解释:tex.runtoks
采用一个函数来打印出一些要立即执行的标记;在内部,它是通过放在⟨the tokens⟩ ⟨internal \endlocalcontrol token⟩
输入流前面执行“本地运行”来完成的。
因此输入流的格式如下
\expandafter ⟨\endlocalcontrol⟩ ⟨tokens in the input stream⟩
首先\expandafter
进行扩展,从而扩展标记。然后⟨\endlocalcontrol⟩
执行并退出tex.runtoks
。
请注意, 表示的标记⟨\endlocalcontrol⟩
是内部标记,根据具体情况可能会显示为。但BAD
它与普通标记具有相同的含义。\endlocalcontrol