4

using package xparse I stored the author of a certain paper in a \clist in the following way

\NewDocumentCommand\addauthor{m}{%                           
 \clist_put_right:Nn\l_allauthors{#1}%                       
}

and the I used in the pdf the command

\addauthor{bla bla bla}

to add some author. Then I also defined the function

\NewDocumentCommand \printall{}{
 \clist_use:Nnnn \l_allauthors{~and~}{,~}{~and~}
}

and \printall actually print al the author, as expected. The problem comes when I try to set

\hypersetup{pdfauthor={\printall}}

I get the error message

Token not allowed in PDF string

How can I solve the problem?

  • Untested: Try \space instead of ~ – user31729 May 6 '16 at 5:40
  • I tried: id didn't work. Even if I replace, just for a try, { ~and~}{,~}{~and~} with {}{}{}; same error. – MaPo May 6 '16 at 9:55
  • Related: tex.stackexchange.com/questions/307943/… – cfr May 6 '16 at 12:13
1

The \printall must be expanded first, i.e. use 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}

enter image description here

  • How did you know that pdfauthor=\expandafter{\printall} works? – Manuel May 6 '16 at 12:14
  • @Manuel: I looked into the properties of the pdf file. – user31729 May 6 '16 at 12:17
  • Okey, I was more into the TeX part. Is that a feature of certain key-value packages? – Manuel May 6 '16 at 12:20
3

Change your code into

\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~ }
 }

The main point is \DeclareExpandableDocumentCommand (with a preventive check that the command is undefined). Macros defined with \NewDocumentCommand are “protected”, so they won't expand in \edef contexts, which is what hyperref uses for getting the authors' list in pdfauthor. On the other hand, \clist_use:Nnnn is safely fully expandable, so we can (and should) use \DeclareExpandableDocumentCommand.

Use the proper naming convention for variables: g stands for “global”, which should be used here as the author list seems better treated as global; next comes a prefix (the package name or the code author's name), then the actual name and finally the type of variable.

Full example.

\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}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.