如何在 Lua 中获取标记列表 (tl) 变量的值?

如何在 Lua 中获取标记列表 (tl) 变量的值?

例如,如果我定义一个像这样的令牌列表

\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

相关内容