LATEX-L Archives

Mailing list for the LaTeX3 project


Options: Use Classic View

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

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

Print Reply
Joseph Wright <[log in to unmask]>
Wed, 15 Jun 2011 14:14:44 +0100
text/plain (92 lines)
On 14/06/2011 23:12, Heiko Oberdiek wrote:
> 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.

Clearly, dealing with bookmarks is something that will need to be
addressed in the longer term in a more systematic way: it is not the
intention to say 'Good bye bookmarks'!

To me, it seems that:
 - only some document commands need to work inside bookmarks, although
   it takes a human to decide which ones.
 - the definition for use within bookmarks needs to be carefully worked
   out, so again automation is out.
 - definitions for expandable contexts will in general be different from
   non-expandable ones.

There are a number of ways we could handle this. One way would be to
have a \DeclareBookmarkableCommand (or similar) macro, which would work
in the form

     {Standard code}
     {Bookmark code}

and then to define \foo as Heiko suggests

  \def\foo{\texorpdfstring{\InternalFoo}{Bookmark Code}}

although I'm not sure what happens in other expandable contexts (I
assume anything other than a bookmark context uses branch 1).

A second alternative would be to go with Frank's idea of separating out
interface and implementation


and to provide a way to switch implementations.

I think I prefer the first approach, but in general expandable versus
non-expandable document commands are still a problem, as are variations
in implementation. So we may need to think a bit more widely about this.
Joseph Wright