这个例子永远编译不完。我一定是用错了keyval_parse
\documentclass{report}
\usepackage{xparse}
% Relevant doc:
% http://www.texdoc.net/texmf-dist/doc/latex/l3kernel/interface3.pdf#part.21
\ExplSyntaxOn
\NewDocumentCommand{\mykeyvalparser}
{
m % key
m % val
}
{
\tl_case:NnTF #1
{
foo{Hello, #2!}
bar{Bye, #2!}
}{}{No matching key}
}
\NewDocumentCommand{\mykeyparser}
{
m % key
}
{
\tl_case:NnTF #1
{
qux{QUX}
}{}{No matching key}
}
\begin{document}
\keyval_parse:NNn
\mykeyparser
\mykeyvalparser
{
foo=World,
bar=Universe,
qux
}%WANTED: Hello, World! Bye, Universe! QUX
\ExplSyntaxOff
\end{document}
编译日志:
Running `LaTeX' on `parser-1' with ``pdflatex -file-line-error -interaction=nonstopmode parser-1.tex''
This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./parser-1.tex
LaTeX2e <2019-10-01>
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/report.cls
Document Class: report 2019/08/27 v1.4j Standard LaTeX document class
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/size10.clo))
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3kernel/expl3.sty
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3kernel/expl3-code.tex
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3kernel/l3deprecation.def))
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3backend/l3backend-pdfmode.def))) (./parser-1.aux)
./parser-1.tex:45: Missing number, treated as zero.
<to be read again>
o
l.45 }
%WANTED: Hello, World! Bye, Universe! QUX
更新:
来自所引用的文档:
\keyval_parse:NNn〈function1〉 〈function2〉{〈key–value list〉}
因此
\keyval_parse:NNn \function:n \function:nn{ key1 = value1 , key2 = value2, key3 = , key4 }
被转换成输入流
\function:nn { key1 } { value1 }
\function:nn { key2 } { value2 }\function:nn { key3 } { }\function:n { key4 }
答案1
正如@UlrikeFischer 在评论中指出的那样,您对 的使用\tl_case:NnTF
是错误的。相反,您应该\str_case:nnTF
在这里使用 。此外,您不应该将\NewDocumentCommand
用作代码级函数,该函数将与 一起使用\keyval_parse:NNn
,因此我将它们切换到不存在的模块的代码级my
(您可能应该更改该名称)。哦,您还必须在~
中明确添加空格\ExplSyntaxOn
,因为其他空格将被忽略(并且~
不是通常的不可破坏空格,而只是这里的普通空格)。
\documentclass{report}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new:Npn \my_keyval_parser:nn #1 #2
{
\str_case:nnTF { #1 }
{
{ foo } {Hello, ~ #2!}
{ bar } {Bye, ~ #2!}
}
{}
{ No ~ matching ~ key}
}
\cs_new:Npn \my_key_parser:n #1
{
\str_case:nnTF { #1 }
{
{ qux } {QUX}
}
{}
{ No ~ matching ~ key}
}
\begin{document}
\keyval_parse:NNn
\my_key_parser:n
\my_keyval_parser:nn
{
foo=World,
bar=Universe,
qux
}%WANTED: Hello, World! Bye, Universe! QUX
\ExplSyntaxOff
\end{document}
顺便说一句,正确的语法是\tl_case:NnTF
将标记列表变量与标记列表变量(-type 参数)进行比较N
,并且在您的情况下看起来像下面这样(在那里您还会看到为什么要使用\str_case:nn
):
\tl_new:N \l_my_tmpa_tl
\tl_const:Nn \c__my_foo_tl { foo }
\tl_const:Nn \c__my_bar_tl { bar }
\tl_const:Nn \c__my_qux_tl { qux }
\cs_new_protected:Npn \my_keyval_parser:nn #1 #2
{
\tl_set:Nn \l_my_tmpa_tl { #1 }
\tl_case:NnTF \l_my_tmpa_tl
{
\c__my_foo_tl {Hello, ~ #2!}
\c__my_bar_tl {Bye, ~ #2!}
}
{}
{ No ~ matching ~ key}
}
\cs_new_protected:Npn \my_key_parser:n #1
{
\tl_set:Nn \l_my_tmpa_tl { #1 }
\tl_case:NnTF \l_my_tmpa_tl
{
\c__my_qux_tl {QUX}
}
{}
{ No ~ matching ~ key}
}