使用包我以以下方式xparse
将某篇论文的作者存储在\clist
\NewDocumentCommand\addauthor{m}{%
\clist_put_right:Nn\l_allauthors{#1}%
}
我在 pdf 中使用了命令
\addauthor{bla bla bla}
添加一些作者。然后我还定义了函数
\NewDocumentCommand \printall{}{
\clist_use:Nnnn \l_allauthors{~and~}{,~}{~and~}
}
并按\printall
预期打印出所有作者。问题出现在我尝试设置
\hypersetup{pdfauthor={\printall}}
我收到错误消息
Token not allowed in PDF string
我该如何解决这个问题?
答案1
必须\printall
先扩展,即使用pdfauthor=\expandafter{\printall}
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \l_allauthors_clist
\NewDocumentCommand\addauthor{m}{%
\clist_put_right:Nn\l_allauthors_clist{#1}%
}
\NewDocumentCommand \printall{}{
\clist_use:Nnnn \l_allauthors_clist {~and~}{,~}{~and~}
}
\ExplSyntaxOff
\usepackage{hyperref}
\begin{document}
\addauthor{bla bla bla}
\addauthor{Gandalf}
\hypersetup{pdfauthor=\expandafter{\printall}}
\section{Foo}
\end{document}
答案2
将您的代码更改为
\clist_new:N \g_mapo_allauthors_clist
\NewDocumentCommand\addauthor{m}
{
\clist_gput_right:Nn \g_mapo_allauthors_clist { #1 }
}
\NewDocumentCommand \printall { } { } % initialization
\DeclareExpandableDocumentCommand \printall { }
{
\clist_use:Nnnn \l_mapo_allauthors_clist { ~and~ } { ,~ } { ~and~ }
}
要点是\DeclareExpandableDocumentCommand
(预防性地检查命令是否未定义)。用 定义的宏\NewDocumentCommand
是“受保护的”,因此它们不会在\edef
上下文中扩展,这就是hyperref
在 中获取作者列表的用途pdfauthor
。另一方面,\clist_use:Nnnn
是可以安全地完全扩展的,因此我们可以(并且应该)使用\DeclareExpandableDocumentCommand
。
使用正确的变量命名约定:g
代表“全局”,应该在这里使用,因为作者列表似乎最好作为全局处理;接下来是前缀(包名称或代码作者的姓名),然后是实际名称,最后是变量的类型。
完整示例。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \g_mapo_allauthors_clist
\NewDocumentCommand\addauthor {m}
{
\clist_gput_right:Nn \g_mapo_allauthors_clist { #1 }
}
\NewDocumentCommand \printall { } { } % initialization
\DeclareExpandableDocumentCommand \printall { }
{
\clist_use:Nnnn \g_mapo_allauthors_clist { ~and~ } { ,~ } { ~and~ }
}
\ExplSyntaxOff
\usepackage{hyperref}
\begin{document}
\addauthor{Euclid}
\addauthor{Archimedes}
\hypersetup{pdfauthor={\printall}}
\section{Foo}
\end{document}