etoolbox与LuaLatex的碰撞

etoolbox与LuaLatex的碰撞

我使用一个宏,它返回由外部计数器根据来自的宏\mychoice{item a, item b, items c,…}确定的逗号分隔列表的一项。在简单文本中,此宏工作正常,但当我尝试在Lua(La)TeX 中使用它时,它会引发奇怪的(至少对我来说)错误。\docsvlistetoolbox\directlua{}

梅威瑟:

\documentclass{article}
\usepackage{luacode}
\usepackage{etoolbox}
\begin{luacode*}
 function dummy(argument)
 end
\end{luacode*}

\newcounter{choicecounter}
\newcounter{argcounter}

\newcommand{\mychoice}[1]{
    \setcounter{argcounter}{0}
    \renewcommand*{\do}[1]{
        \stepcounter{argcounter}
        \csedef{argcounter\arabic{argcounter}}{##1}}
    \docsvlist{#1}
    \csuse{argcounter\arabic{choicecounter}}
}

\newcommand{\main}[1]{%
    \setcounter{choicecounter}{#1}
    hello world \mychoice{one,{two,three}}
    \directlua{dummy(\luastring{\mychoice{foo,bar}})}
}

\begin{document}
\main{1}

\main{2}
\end{document}

所以这个版本会引发错误。如果你注释掉它,\directlua编译会成功。

我做错了什么?还是某个地方有错误?

PS:\directlua用-package\luadirect或-package替换或者省略\luaexec-command不会改变任何东西。luacode\luastring

答案1

您可以使用 expl3 和\clist_item:nn在列表中选择一个项目。这是可扩展的:

\documentclass{article}
\usepackage{luacode}
\usepackage{expl3}
\begin{luacode*}
 function dummy(argument)
  tex.sprint("lua: ".. argument)
 end
\end{luacode*}

\ExplSyntaxOn
\newcommand{\main}[1]{%
    hello~world~\clist_item:nn{one,{two,three}}{#1}\par
    \directlua{dummy(\luastring{\clist_item:nn{foo,bar}{#1}})}
}
\ExplSyntaxOff

\begin{document}
\main{1}

\main{2}
\end{document}

正如 egreg 在评论中所建议的那样,真正的 expl3 版本将使用 \lua_now:e 而不是 \directlua:

 \lua_now:e {dummy("\lua_escape:e{\clist_item:nn{foo,bar}{#1}}")}

在此处输入图片描述

答案2

您需要做的最重要的事情是将宏定义中的 替换\luastring\luastringN——N代表“不执行扩展” \main。此外,您需要通过在和宏%定义中的各个行尾放置 来禁止所有这些不必要的空格。\main\mychoice

对于以下 MWE,我借用dummyUlrike 的回答

在此处输入图片描述

\documentclass{article}
\usepackage{etoolbox}
\usepackage{luacode} % for 'luacode' environment and '\luastringN' macro
\begin{luacode}
function dummy ( argument )
   tex.sprint ( "lua: " .. argument )
end
\end{luacode}

\newcounter{choicecounter}
\newcounter{argcounter}

\newcommand{\mychoice}[1]{%
    \setcounter{argcounter}{0}%
    \renewcommand*{\do}[1]{%
        \stepcounter{argcounter}%
        \csedef{argcounter\arabic{argcounter}}{##1}}%
    \docsvlist{#1}%
    \csuse{argcounter\arabic{choicecounter}}%
}

\newcommand{\main}[1]{%
    \setcounter{choicecounter}{#1}%
    \mychoice{one,{two,three}}

    \directlua{dummy(\luastringN{\mychoice{one,{two,three}}})}
}

\begin{document}
1 --- \main{1}

\medskip
2 --- \main{2}
\end{document}

相关内容