我假设\keyval_parse:nnn
吸收了它的第三个参数,但它却插入到了输入流中,为什么?
\documentclass{report}
\usepackage{xparse}
\begin{document}
\ExplSyntaxOn
\noindent%
\keyval_parse:nnn{}{}{j=u}\\
\keyval_parse:nnn{\use_none:n{##1}}{\use_none:nn{##1}{##2}}{k=v}\\
\keyval_parse:NNn\use_none:n\use_none:nn{l=w}
\ExplSyntaxOff
\end{document}
答案1
您需要仔细查看文档中的示例,以了解其作用。假设一个简单的示例,\keyval_parse:nn
要求每个键都有一个值,只是为了简化。输入:
\keyval_parse:nn { <keyval code> } { key 1 = value 1, key 2 = value 2 }
相当于:
<keyval code>{key 1}{value 1}
<keyval code>{key 2}{value 2}
也就是说,对于每个,key=value
它都会在括号中插入和<keyval code>
。对于仅限键的版本也是如此,但它只会在代码后插入一个括号组:key
value
<keyval code>{key 1}
<keyval code>{key 2}
前两个示例仅打印了键值列表,因为它们实际上并未使用键值对。仔细观察,规则与之前相同:
\keyval_parse:nnn{}{}{j=u}
这里<keyval code>
是空的,因此变成:
%↓ empty
{j}{u}
它仅写入ju
输出。
第二个例子是:
\keyval_parse:nnn{\use_none:n{##1}}{\use_none:nn{##1}{##2}}{k=v}
变成:
\use_none:nn{##1}{##2}{k}{v}
然后\use_none:nn
消耗##1
并##2
再次kv
排版。
这是一个可能更有启发性的例子。看看\erwann_wrap_one:n
他们的论点是什么,并与 PDF 输出进行比较:
\documentclass{article}
\usepackage{xparse}
\begin{document}
\ExplSyntaxOn
\noindent
\cs_new:Npn \erwann_wrap_one:n #1 { (#1) }
\cs_new:Npn \erwann_wrap_two:nn #1 #2 { [#1--#2] }
\keyval_parse:nnn
{ \typeout{A~KEY} \erwann_wrap_one:n }
{ \typeout{A~KEY~WITH~VALUE} \erwann_wrap_two:nn }
{
k1,
k2 = v,
}
\ExplSyntaxOff
\end{document}
这将打印
A KEY
A KEY WITH VALUE
到终端,PDF 将具有:
答案2
第一个参数应该\keyval_parse:nnn
以需要括号参数的内容结尾。
类似地,第二个参数应该以需要两个括号参数的内容结尾。
在您的第一次通话中,您只会得到{j}{u}
。
这些示例使用了一个双参数函数和一个三参数函数,但只提供了一个参数,其他参数将通过解析提供。
当然这不是为了打印什么东西,而是做一些设置。
打印示例:
\documentclass{article}
\ExplSyntaxOn
\cs_new:Nn \erwann_test:n { \#1~is~#1 }
\cs_new:Nn \erwann_test:nn { \#1~is~#1;~ \#2~is~#2 }
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\keyval_parse:nnn { \erwann_test:n } { \erwann_test:nn } { j=u , k }
\ExplSyntaxOff
\end{document}
带有设置的示例。
\documentclass{article}
\ExplSyntaxOn
\seq_new:N \l_erwann_test_seq
\prop_new:N \l_erwann_test_prop
\cs_new_protected:Nn \erwann_set:n
{
\keyval_parse:nnn
{
\seq_put_right:Nn \l_erwann_test_seq
}
{
\prop_put:Nnn \l_erwann_test_prop
}
{ #1 }
}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\erwann_set:n { j, k=a, yy=b, c }
\seq_show:N \l_erwann_test_seq
\prop_show:N \l_erwann_test_prop
\ExplSyntaxOff
\end{document}
终端上的结果
The sequence \l_erwann_test_seq contains the items (without outer braces):
> {j}
> {c}.
<recently read> }
l.28 \seq_show:N \l_erwann_test_seq
?
The property list \l_erwann_test_prop contains the pairs (without outer
braces):
> {k} => {a}
> {yy} => {b}.
<recently read> }
l.29 \prop_show:N \l_erwann_test_prop
?
该\keyval_parse:NNn
函数的作用基本相同,但你只需传递一个单参数函数和一个双参数函数。因此,上面的代码也可以写成
\documentclass{article}
\ExplSyntaxOn
\seq_new:N \l_erwann_test_seq
\prop_new:N \l_erwann_test_prop
\cs_new_protected:Nn \erwann_set:n
{
\keyval_parse:nnn \erwann_set_one:n \erwann_set_two:nn { #1 }
}
\cs_new_protected:Nn \erwann_set_one:n
{
\seq_put_right:Nn \l_erwann_test_seq { #1 }
}
\cs_new_protected:Nn \erwann_set_two:nn
{
\prop_put:Nnn \l_erwann_test_prop { #1 } { #2 }
}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\erwann_set:n { j, k=a, yy=b, c }
\seq_show:N \l_erwann_test_seq
\prop_show:N \l_erwann_test_prop
\ExplSyntaxOff
\end{document}