如有任何关于如何调试或修复该问题的建议,我们将不胜感激。
\documentclass{minimal}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \__foo_aux:n #1{\c_novalue_tl}
\cs_set:Npn \__foo:n #1
{
\cs_set:Npn \__foo_aux:n ##1{#1}
__foo_aux:n
}
\begin{document}
% For comparison's sake:
\tl_new:N \__bar_tl
\tl_set:Nn \__bar_tl {__foo_aux:n}
\use:c{\__bar_tl}{X} % -No Value-
% The code that generates an error:
\\
\__foo_aux:n{X} % -No Value- %
\\ \__foo:n{(#1)} % __foo_aux:n %
\\ \__foo_aux:n{X} % (X)
\\ \use:c{\__foo:n{(#1)}}{X} % Expected: (X)
% Console output
%! Missing \endcsname inserted.
%<to be read again>
% \tex_long:D
%l.22 \\ \use:c{\__foo:n{(#1)}}
% {X} %! Missing \endcsname inserted.
\ExplSyntaxOff
\end{document}
答案1
\cs_new:Npn \__erwann_action:n #1 { \c_novalue_tl }
\cs_new_protected:Npn \erwann_set:n #1 { \cs_set:Npn \__erwann_action:n ##1 { #1 } }
\cs_new:Npn \erwann_do:n #1 { \__erwann_action:n { #1 } }
\cs_new_protected:Npn \erwann_do:nn #1 #2 { \erwann_set:n { #1 } \erwann_do:n { #2 } }
然后使用
\__erwann_action:n {X} % -No Value-
\erwann_do:n {X} % -No Value-
\erwann_set:n {(#1)} % just setup
\erwann_do:n {X} % (X)
\erwann_do:nn {(#1)} {X} % Expected: (X) OK
答案2
该\use:c
函数只是\csname
TeX 原语的包装器。TeXbook 中的描述非常清楚(第 40 页):
\csname
相反,您可以通过说 ' ⟨tokens⟩ '从字符标记列表转到控制序列。出现在和\endcsname
之间的此构造中的标记可能包含其他控制序列,只要这些控制序列最终扩展为字符而不是 TeX 基元;最终的字符可以是任何类别,不一定是字母。例如,' ' 本质上与 ' 相同;但 '是非法的,因为它扩展为包含基元的标记。此外,' ' 将产生不寻常的控制序列 ' ',即标记,您通常无法编写它。\csname
\endcsname
\csname TeX\endcsname
\TeX
\csname\TeX\endcsname
\TeX
\kern
\csname\string\TeX\endcsname
\\TeX
|\TeX|
不仅上述行为\kern
是违法的,而且任何不可扩展原语,例如\hbox
或\def
。由于每个赋值都是用不可扩展原语进行的,因此 中不能进行赋值,\csname...\endcsname
就像 的参数中不能进行赋值一样\use:c
。
可能有解决方法,但我不知道您会在什么情况下使用这个想法。