我正在尝试将逗号分隔的列表存储到键值属性中以便稍后使用它,但我无法使其正常工作。
我不太明白 latex 如何解析 keyval 参数,但我猜测它将参数作为纯文本进行处理。
这是我目前拥有的代码:
\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand { \getvmeta } { m } { \prop_item:cn { g_rvnlatex_doc_prop } { #1 } }
\NewDocumentCommand { \setvmeta } { m m } { \prop_gput:cnV { g_rvnlatex_doc_prop } { #1 } #2 }
\keys_define:nn { ravenhill/latex/meta } {
author .clist_set:N = \l_rvnlatex_author_clist ,
}
\NewDocumentCommand { \setup } { m } {
\group_begin:
\prop_new:c { g_rvnlatex_doc_prop }
\keys_set:nn { ravenhill/latex/meta } { #1 }
\setvmeta { author } { \l_rvnlatex_author_clist }
\group_end:
}
\NewDocumentCommand { \authorblock } { } {
\clist_new:N \l__authblock_authcopy_clist
\clist_set:Nn \l__authblock_authcopy_clist { \getvmeta { author } }
\clist_use:Nnnn \l__authblock_authcopy_clist { ~and~ } { ,~ } { ,~and~ }
}
\ExplSyntaxOff
\setup {
author = {John, Bob},
}
\begin{document}
\authorblock
\end{document}
我得到的结果是John,Bob
而不是John and Bob
。
我是否遗漏了什么?
答案1
你的猜测是正确的。当你使用
\clist_set:Nn \l__authblock_authcopy_clist { \getvmeta { author } }
clist 解析器只能看到\getvmeta { author }
,就它而言,它与没有什么不同getvmeta { author }
,因为其中没有逗号。
要显示传递给键的逗号列表author
,您必须扩展\getvmeta{author}
其内容。为此,请使用\clist_set:Nx
(x
表示详尽扩展)。它将起作用,因为\prop_item:Nn
通过扩展工作,因此它可以在扩展上下文中返回该项目(您还必须\getvmeta
通过使用声明来允许扩展)。\NewExpandableDocumentCommand
另外,将变量声明移到用户级命令之外:您永远不知道是否有人会尝试使用\setup
两次,如果他们这样做,您的代码将在尝试声明已存在的变量时出错。
\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand { \getvmeta } { m }
{ \prop_item:Nn \g_rvnlatex_doc_prop {#1} }
\NewDocumentCommand { \setvmeta } { m m }
{ \prop_gput:NnV \g_rvnlatex_doc_prop {#1} #2 }
\keys_define:nn { ravenhill/latex/meta }
{ author .clist_set:N = \l_rvnlatex_author_clist }
\prop_new:N \g_rvnlatex_doc_prop
\clist_new:N \l__authblock_authcopy_clist
\NewDocumentCommand \setup { m }
{
\group_begin:
\keys_set:nn { ravenhill/latex/meta } {#1}
\setvmeta { author } { \l_rvnlatex_author_clist }
\group_end:
}
\NewDocumentCommand \authorblock { }
{
\clist_set:Nx \l__authblock_authcopy_clist { \getvmeta { author } }
\clist_use:Nnnn \l__authblock_authcopy_clist { ~and~ } { ,~ } { ,~and~ }
}
\ExplSyntaxOff
\setup{author = {John, Bob}}
\begin{document}
\authorblock
\end{document}