我尝试使用expl3
序列来存储datatool
数据库中存储的 0、1 或多个作者的从属关系。以下 MWE 效果很好:
\documentclass{article}
\usepackage{xparse}
\usepackage{datatool}
\ExplSyntaxOn
\DTLnewdb{_mymodule_authors}
\seq_new:N \g_mymodule_author_affiliations_seq
\keys_define:nn { mymodule/authors }
{
affiliation .code:n = \seq_gput_right:Nn \g_mymodule_author_affiliations_seq {#1}
}
\cs_new_protected:Nn \_mymodule_authors:nn
{
\DTLnewrow{_mymodule_authors}
\DTLnewdbentry{_mymodule_authors}{name}{#1}
\DTLnewdbentry{_mymodule_authors}{affiliations}{#2}
}
\cs_generate_variant:Nn \_mymodule_authors:nn { nV }
\RenewDocumentCommand \author { o m } {
\IfValueTF {#1}
{
\keys_set:nn { mymodule/authors } { #1 }
\_mymodule_authors:nV {#2}{\g_mymodule_author_affiliations_seq}
}
{
\_mymodule_authors:nV {#2}{\c_empty_tl}
}
\seq_gclear:N \g_mymodule_author_affiliations_seq
}
\NewDocumentCommand \showauthors { } {
\DTLforeach*{_mymodule_authors}{
\l_tmpa_tl=name,
\l_tmpa_seq=affiliations
}{
\mymodule_display_author:nn {\l_tmpa_tl}{\l_tmpa_seq}
\DTLiflastrow{
}{
\DTLpar
}
}
}
\cs_new_protected:Nn \mymodule_display_author:nn
{
#1
\seq_if_empty:NF {\l_tmpa_seq}
{
\space(\seq_use:Nn \l_tmpa_seq { ,~ })
}
}
\ExplSyntaxOff
\begin{document}
%\author{Foo, Bar 0}
\author[affiliation=Blah]{Foo, Bar 1}
\author[affiliation=Bleh,affiliation=Blih]{Foo, Bar 2}
\author[affiliation=Bloh,affiliation=Bluh,affiliation=Blyh]{Foo, Bar 3}
%
\showauthors
\end{document}
但是,一旦我注释掉\author{Foo, Bar 0}
具有 0 个从属关系的作者,我就会面临以下我无法理解的错误:
! Missing = inserted for \ifnum.
<to be read again>
{
答案1
序列不能用作说明V
符的参数,因为它没有单一的唯一值。
因此,您不必将序列存储在数据库中,而是可以存储指针到序列。作为指针,我使用作者姓名的“字符串化”版本。
\documentclass{article}
\usepackage{xparse}
\usepackage{datatool}
\ExplSyntaxOn
\DTLnewdb{_mymodule_authors}
\seq_new:N \l_mymodule_author_affiliations_seq
\keys_define:nn { mymodule/authors }
{
affiliation .code:n = \seq_put_right:Nn \l_mymodule_author_affiliations_seq {#1}
}
\cs_new_protected:Nn \_mymodule_authors:n
{
\DTLnewrow{_mymodule_authors}
\DTLnewdbentry{_mymodule_authors}{name}{#1}
\DTLnewdbentry{_mymodule_authors}{affiliations}{\tl_to_str:n{#1}}
}
\RenewDocumentCommand \author { O{} m }
{
\seq_clear:N \l_mymodule_author_affiliations_seq
\keys_set:nn { mymodule/authors } { #1 }
\_mymodule_authors:n {#2}
\seq_new:c { g_mymodule_affiliation_ \tl_to_str:n{#2} _seq }
\seq_gset_eq:cN { g_mymodule_affiliation_ \tl_to_str:n{#2} _seq } \l_mymodule_author_affiliations_seq
}
\NewDocumentCommand \showauthors { }
{
\DTLforeach*{_mymodule_authors}
{
\l_tmpa_tl=name,
\l_tmpb_tl=affiliations
}
{
\mymodule_display_author:VV \l_tmpa_tl \l_tmpb_tl
\DTLiflastrow { }{ \DTLpar }
}
}
\cs_new_protected:Nn \mymodule_display_author:nn
{
#1
\seq_if_empty:cF { g_mymodule_affiliation_#2_seq }
{
\c_space_tl(\seq_use:cn { g_mymodule_affiliation_#2_seq } { ,~ })
}
}
\cs_generate_variant:Nn \mymodule_display_author:nn { VV }
\ExplSyntaxOff
\begin{document}
\author{Foo, Bar 0}
\author[affiliation=Blah]{Foo, Bar 1}
\author[affiliation=Bleh,affiliation=Blih]{Foo, Bar 2}
\author[affiliation=Bloh,affiliation=Bluh,affiliation=Blyh]{Foo, Bar 3}
\showauthors
\end{document}