例如,如果我定义一个像这样的令牌列表
\tl_set:Nn \l__tmpa_tl {content\someundefinedmacro}
我可以使用哪个函数来获取令牌列表的值?
答案1
使用函数token.get_macro
(返回字符串)。
print(token.get_macro("l__tmpa_tl"))
为了获取 catcode 信息,我想出了一个复杂的方法,但是似乎没有更好的办法:
(此方法作品在仅扩展上下文中,但它需要退出 TeX 引擎并返回,因此它不能被包装在函数中,除非调用者是协程)
%! TEX program = lualatex
\documentclass[12pt]{article}
\usepackage{luacode}
\begin{document}
\ExplSyntaxOn
% ======== Prepare an example `\test` token list (tl) for getting the value in Lua
\tl_set:Nx \test {
\char_generate:nn {"41} {8}
\char_generate:nn {"41} {11}
\char_generate:nn {"41} {12}
}
\tl_put_right:Nn \test {
{}$&#^$
\somethingundefined
\input
\scantokens
\q_nil
\cs_set:Npn
\A
\~
}
\exp_args:NNo \tl_put_right:No \test {
\char_generate:nn {`A} {13}
}
\exp_args:NNo \tl_put_right:No \test {
\char_generate:nn {`\~} {13}
}
% ======== Define the main function.
\begin{luacode*}
function f()
while true do
local t=token.get_next()
if t.csname then
if t.csname=="q_stop" then
break
end
print(string.format("cs %20s active=(%s) cmdname=(%s) ", "'" .. t.csname .. "'", t.active, t.cmdname))
else
print("char", t.cmdname, string.char(t.mode))
end
--print(t.command, t.cmdname, t.tok, t.active, t.expandable, t.protected, t.mode, t.index)
end
end
\end{luacode*}
% ======== Define a helper TeX function.
\cs_set:Npn \callf {\directlua{f()}}
% ======== Actually call the function -- read the definition of the `\test` macro.
\exp_after:wN \callf \test \q_stop
\ExplSyntaxOff
\end{document}
输出:
char sub_mark A
char letter A
char other_char A
char left_brace {
char right_brace }
char math_shift $
char tab_mark &
char mac_param #
char sup_mark ^
char math_shift $
cs 'somethingundefined' active=(false) cmdname=(undefined_cs)
cs 'input' active=(false) cmdname=(call)
cs 'scantokens' active=(false) cmdname=(input)
cs 'q_nil' active=(false) cmdname=(call)
cs 'cs_set:Npn' active=(false) cmdname=(long_call)
cs 'A' active=(false) cmdname=(undefined_cs)
cs '~' active=(false) cmdname=(call)
cs 'A' active=(true) cmdname=(undefined_cs)
cs '~' active=(true) cmdname=(call)
当然还有另一种\tl_analysis_map_inline
更简短的使用方法:
\begin{luacode*}
function f(s, charcode, catcode)
print(s, charcode, catcode)
end
\end{luacode*}
\tl_analysis_map_inline:Nn \test {\directlua{f("\luaescapestring{\detokenize{#1}}", #2, "#3")}}
结果:
\exp_not:n {A} 65 8
\exp_not:n {A} 65 B
\exp_not:n {A} 65 C
\exp_after:wN {\if_false: }\fi: 123 1
\if_false: {\fi: } 125 2
\exp_not:n {$} 36 3
\exp_not:n {&} 38 4
\exp_not:n {##} 35 6
\exp_not:n {^} 94 7
\exp_not:n {$} 36 3
\exp_not:n {\somethingundefined } -1 0
\exp_not:n {\input } -1 0
\exp_not:n {\scantokens } -1 0
\exp_not:n {\q_nil } -1 0
\exp_not:n {\cs_set:Npn } -1 0
\exp_not:n {\A } -1 0
\exp_not:n {\~} -1 0
\exp_not:n {A} 65 D
\exp_not:n {~} 126 D