\let\mySection\section 与 directlua

\let\mySection\section 与 directlua

接下来lualatex MWE\newcommand\mySection{\section}在lua端进行模拟。

% !TEX TS-program = lualatex
\documentclass{article}
\begin{document}
\directlua{
  token.set_macro('mySection', '\\section')
}
\mySection{bar}
\end{document}

如何模拟\let\mySection\section

穷人的解决方案就像

\directlua{
  token.set_macro(catcodetable, 'mySection', token.get_macro('section'))
}

catcodetable只要正确设置,最终就会起作用,但如何操作呢?

答案1

一般来说你不能。tex.set_macro是唯一允许从 Lua 分配 TeX 宏的 Lua 函数,并且它相当有限:不可能使用它来定义带有参数的宏,并且它不允许您定义包含具有不同 catcode 的相同字符的宏。

因此,从 Lua 执行等效操作的唯一可靠方法\let是将\let\newname\oldname(或等效标记)传回 TeX 并让 TeX 执行它。

即使您想将自己限制为具有一致 catcode 的无参数宏,您token.get_macro也无法告诉您有关 catcode 的任何信息。因此,确定宏中使用的 catcode 的唯一方法是再次将其传回 TeX,在那里展开它,然后读回标记。

答案2

仅作为演示如何在 LuaTeX 中完成任务(可扩展!)

当然它仍然涉及将东西传递给 TeX 来执行。

%! TEX program = lualatex
\documentclass{article}
\begin{document}

% define some macros here.
% NOTE \a and \b should not be redefined in normal code
\def\a{123}
\def\b{456}

% the old value of \a is 123
\directlua{print("========", token.get_macro("a"))}

\edef\c{
    \directlua{

        --[[ the old value is 123 (use this comment style because new lines are stripped, this is directlua not luacode environment ]]
        print(token.get_macro("a"))

        --[[ create a table of tokens with content \let\a\b. Can use token.create as well ]]
        local tokens=token.scan_toks(false, false)

        --[[ run it ]]
        tex.runtoks(function()
            tex.sprint(tokens)
        end)

        --[[ look, the macro content really changed ]]
        print(token.get_macro("a"))

    }{\let\a\b}
}

% and outside too
\directlua{print(token.get_macro("a"))}

\end{document}

LuaTeX 文档中关于此代码的一些注释:

  • runtoks

    您必须确保 TEX 最后处于正常状态,而这并不总是那么简单。

  • 关于扫描令牌的一般信息

    在扫描下一个标记时,您需要记住,我们的扫描方式与 TeX 不同:扩展、更改模式并随心所欲地执行操作。使用 Lua 进行扫描时,我们只会拾取标记。


\beginlocalcontrol或者从中复制宏的定义https://tex.stackexchange.com/a/628874/250119我们可以做以下事情:

%! TEX program = lualatex
\documentclass{article}

\newluafunction\beginlocalcontrol
\directlua{lua.get_functions_table()[\the\allocationnumber] = function() return tex.runtoks(token.get_next) end}  % define its meaning
\luadef\beginlocalcontrol\allocationnumber

\begin{document}

% define some macros here.
% NOTE \a and \b should not be redefined in normal code
\def\a{123}
\def\b{456}

% the old value of \a is 123
\directlua{print("========", token.get_macro("a"))}

\edef\c{
  \beginlocalcontrol\let\a\b\endlocalcontrol
}

% the macro content changed
\directlua{print("======== changed", token.get_macro("a"))}

\end{document}

\newluafunction作为使用/ 的替代方法\allocationnumber,可以使用#lft+1如下方法 1 2 3 但是在 Lua 5.2 中,当分配非连续时,存在未定义行为的风险(但实际上不太可能发生)

相关内容