LATEX-L Archives

Mailing list for the LaTeX3 project

LATEX-L@LISTSERV.UNI-HEIDELBERG.DE

Options: Use Classic View

Use Proportional Font
Show Text Part by Default
Show All Mail Headers

Topic: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Heiko Oberdiek <[log in to unmask]>
Wed, 15 Jun 2011 00:12:43 +0200
text/plain (74 lines)
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

ATOM RSS1 RSS2