我正在尝试在调用中将键值嵌入到键值中,如下所示:
\showchapter{
title=My chapter,
authors={
{name=Peter,affiliation=MIT},
{name=Mary,affiliation=UCLA},
},
}
得到这个输出
My chapter
Peter, MIT
Mary, UCLA
但我无法访问嵌入的键值authors
。
\seq_map_indexed_function:NN \authors \callshowauthorx:nn
对in的调用\showauthors
没有按预期进行。
在下面的例子中,我只想输出参数和嵌入的参数:
\documentclass{book}
\ExplSyntaxOn
\keys_define:nn { authorkeys }
{
name .tl_set:N = \name,
affiliation .tl_set:N = \affiliation,
}
\NewDocumentCommand{\showauthor}{m}
{
\textbf{showauthor:~}
\keys_set:nn { authorkeys } { #1 }
( \name { ,~ } \affiliation )
}
\seq_new:N \myseqx
\NewDocumentCommand \showauthors { m }
{
\textbf{showauthors:~}
\seq_set_from_clist:Nn \myseqx { #1 }
\seq_map_indexed_function:NN \myseqx \callshowauthorx:nn
}
\cs_new:Nn \callshowauthorx:nn
{ \par \showauthor{#2} }
\keys_define:nn { chapterkeys }
{
title .tl_set:N = \title,
authors .clist_set:N = \authors,
}
\seq_new:N \myseqy
\NewDocumentCommand{\showchapter}{m}
{
\keys_set:nn { chapterkeys } { #1 }
\par\textbf{showchapter-title:~}
\title
\par\textbf{showchapter-authors:~}
% next line seems not to work as expected
\seq_map_indexed_function:NN \authors \callshowauthorx:nn
}
\ExplSyntaxOff
\begin{document}
\showauthor{name=Peter,affiliation=MIT}
\showauthors{
{name=Peter,affiliation=MIT},
{name=Mary,affiliation=UCLA},
}
\showchapter{
title=My chapter,
authors={
{name=Peter,affiliation=MIT},
{name=Mary,affiliation=UCLA},
},
}
\end{document}
答案1
我怀疑你真的想要所有这些机器。我认为其中一些是用于测试/开发。
我整理了代码(一点点),并修改了它,让它可以做我想让你做的事情。也许这会有所帮助,你可以对它进行微调。
我会坚持使用clist
s,而不是使用序列 ( seq
)。后者有优势,而且对于某些事情来说它们是必要的,但是当您试图掌握时,它们会增加一层复杂性,您可以使用s 和标记列表 ( s )expl3
做任何您想做的事情。它们也更接近用户输入,我只是认为在您熟悉语法之前,从较少类型的东西开始更容易。clist
tl
在您的原始代码中,您似乎混淆了clist
and seq
/or tl
。命名约定的一个优点是它使这样做变得更加困难并且更容易发现。
如果你说
\tl_new:N <blah>
你正在制作一个 token 列表,<blah>
应该结束_tl
。同样
\clist_new:N <blah>_clist
对于其他变量也是如此(即不是命令,而是序列和其余部分)。
变量应始终以\l_
或\g_
和 常量开头\c_
。通常,您需要\l_
局部变量或\g_
全局变量。我通常使用局部变量,除非我需要全局变量。
我们还需要一个模块名称。我使用了wolfrevo
。然后,局部变量名称的形式基本上是
\l_wolfrevo_<description>_<type>
要处理嵌入的作者,您需要设置两组密钥。最直接的方法就是authors
从章节开始传递内容并设置下一级密钥。
\NewDocumentCommand{\showchapter}{m}
{
\keys_set:nn { wolfrevo / chapterkeys } { #1 }
我们将 的值放入、authors
中,并将标题放入标记列表 ( )、 中。clist
\l_wolfrevo_authors_clist
tl
\g_wolfrevo_title_tl
\par\textbf{showchapter-title:~}
\g_wolfrevo_title_tl
我们想要的只是排版标题,所以我们就这么做。
\par\textbf{showchapter-authors:~}
我们不想直接使用作者。相反,我们希望将 clist 的内容本身视为一组键,这次将它们传递给东西authorkeys
进行处理。我们可以将 clist 映射到另一个内部函数来实现此目的。
\clist_map_inline:Nn \l_wolfrevo_authors_clist
{
\wolfrevo_showauthor:n { ##1 }
}
}
\wolfrevo_showauthor:n
然后设置键并排版每个作者的姓名和所属机构。
我没有尝试对输入进行合理性检查,因此如果您向命令传递任何意外内容,您将收到奇怪的错误。如果您与其他人(包括后来的您)共享代码,您可能希望在其中建立一些有意义的反馈。
\documentclass{book}
\ExplSyntaxOn
\keys_define:nn { wolfrevo / authorkeys }
{
name .tl_set:N = \l_wolfrevo_name_tl,
name .initial:n = {Bilbo ~ Baggins},
affiliation .tl_set:N = \l_wolfrevo_affiliation_tl,
affiliation .initial:n = {Hobbinton ~ College ~ of ~ Further ~ Education, ~ The ~ Shire},
}
\keys_define:nn { wolfrevo / chapterkeys }
{
title .tl_gset:N = \g_wolfrevo_title_tl,
title .initial:V = \c_empty_tl,
authors .clist_set:N = \l_wolfrevo_authors_clist,
authors .initial:n = {},
}
\clist_new:N \l_wolfrevo_tmpa_clist
\cs_new_protected:Nn \wolfrevo_showauthor:nn
{
\textbf{showauthor:~} (#1 , ~ #2)
}
\cs_generate_variant:Nn \wolfrevo_showauthor:nn { VV }
\cs_new_protected:Nn \wolfrevo_showauthor:n
{
\keys_set:nn { wolfrevo / authorkeys } { #1 }
\wolfrevo_showauthor:VV \l_wolfrevo_name_tl \l_wolfrevo_affiliation_tl
\par
}
\NewDocumentCommand{\showchapter}{m}
{
\group_begin:
\keys_set:nn { wolfrevo / chapterkeys } { #1 }
\par
\textbf{showchapter-title:~} \g_wolfrevo_title_tl
\par
\textbf{showchapter-authors:~}
\par
\clist_map_inline:Nn \l_wolfrevo_authors_clist
{
\wolfrevo_showauthor:n { ##1 }
}
\group_end:
}
\ExplSyntaxOff
\begin{document}
\showchapter{%
title=Prequel,
}
\showchapter{
title=My chapter,
authors={
{name=Peter,affiliation=MIT},
{name=Mary,affiliation=UCLA},
},
}
\showchapter{%
title=Sequel,
}
\end{document}
希望以下内容与您的目标类似。
编辑
我通常会使用组来保持本地更改。这样,如果未指定任何内容,您始终会获得键的初始值。这不是您在每种情况下都想要的,但这是一种相当常见的设置。
\NewDocumentCommand{\showchapter}{m}
{
\group_begin:
\keys_set:nn { wolfrevo / chapterkeys } { #1 }
\par\textbf{showchapter-title:~}
\l_wolfrevo_title_tl
\par\textbf{showchapter-authors:~}
% next line seems not to work as expected
\clist_map_inline:Nn \l_wolfrevo_authors_clist
{
\wolfrevo_showauthor:n { ##1 }
}
\group_end:
}
但请注意,这也会将标题变为本地标题。您可以使用以下方法防止这种情况发生
title .tl_gset:N = \g_wolfrevo_title_tl,
并替换\g_wolfrevo_title_tl
。\l_wolfrevo_title_tl
这样,标题将保留在组中(例如,用于标题),但作者列表将不会保留。
这些变化现在已经在上面的代码中实现。