使用 token 库进行 token 扩展

使用 token 库进行 token 扩展

我不明白tokenluatex 的库是如何工作的。

\documentclass{standalone}

\begin{document}

\def\mymacro{A}

\directlua{%
  t = token.create ('mymacro')
  token.expand(t)
  token.get_next()
}

\end{document}

token.expand 无法按我预期的方式工作:luatexUndefined 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

相关内容