\clist 和 hyperref

\clist 和 hyperref

使用包我以以下方式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}

在此处输入图片描述

相关内容