On Tue, Jun 14, 2011 at 11:00:31PM +0200, Stephan Hennig wrote: > xparse's \NewDocumentCommand doesn't seem to play well with hyperref > bookmarks. In this code > > \listfiles > \documentclass{article} > \usepackage{xparse} > \usepackage{hyperref} > \begin{document} > \NewDocumentCommand{\fooa}{}{FooA} > \DeclareExpandableDocumentCommand{\foob}{m}{FooB} > \section{aaa \fooa\ bbb \foob{} ccc} > \end{document} > > text from macro \fooa doesn't show up in the bookmark. Fortunately, it > works at least for macro \foob. > > Is that expected behaviour? Yes. \NewDocumentCommand defines the macro using e-TeX's \protected. The result of \show\fooa: | \fooa=\protected macro: | ->FooA. \pdfstringdef uses \edef to expand the string, \protected prevents this and the unexpandable macro is then filtered out: | Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding): | (hyperref) removing `\fooa' on input line 9. > Would it be possible to make > \NewDocumentCommand macros work with hyperref bookmarks? No, even worse, you cannot provide a bookmark string (\texorpdfstring) inside the definition, because it will not be expanded and \texorpdfstring is not seen. > I'd prefer > using \NewDocumentCommand macros because of the mandatory argument of > \DeclareExpandableDocumentCommand macros which I don't need in my context. I don't see that mandatory arguments matter here. But probably you are refering to "1.7 Fully-expandable document commands": | * The function must have at least one mandatory argument, and in | particular the last argument must be one of the mandatory types | (l, m or u). The section 1.7 contains advice against \DeclareExpandableDocumentCommand: | do not use these functions! One translation is: Good bye bookmarks. Of course there are macros, whose definition text makes it difficult for bookmarks anyway (assignments, ...). But the expandable macros are excluded using \DeclareDocumentCommand. Workarounds: * \pdfstringdefDisableCommands can be used, but an expandable macro needs to be added for each \protected macro that might appear in bookmarks. Then the redefinition takes place for each bookmark string conversion, not very efficient. * Expandable wrapper command that expands to the bookmark string if inside bookmarks and calls the unexpandable macro otherwise. * LuaTeX would add access to node lists, thus the bookmark string could be set in a \hbox and the node list examined and converted to a text string. Some cases are probably quite easy, other cases are very difficult and would cry for OCR methods. * ...? Yours sincerely Heiko