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